Now that we have a readonly flag on our variables, almost the only thing missing from PonieScript to have constant (not reassignable) variables is the syntax to do so.
Right now I am thinking of using let as the keyword for this, as opposed to var for reassignable variables.
fun my_fun() -> int {
let myval = 10;
let myval = myval + 20; // shadow
myval + 30
}
class MyClass {
// Can only be assigned on class construction
let identity: int = 30;
}
fun do_something() {
let me = new MyClass { identity: 20 };
//me.identity = 22; // invalid
}
class MyOtherClass {
var something: int = 30;
}
fun do_something_else() {
let me = new MyOtherClass { something: 45 };
me.something += 20; // valid because only me is not reassignable
}
However, the obvious question this brings up (at least in my mind) is: What do we do when we want a readonly class member, that you CAN'T assign a different value to during construction?
Such a value would still be "public," but would be prevented from appearing in new{} expressions.
I think ultimately we will want GDScript or Rust style "annotations," which we might also use for plain visibility. Something like:
class MyClass {
// You can change this one
let otherval: int = 10;
// You can't change this one
@restrict_construction
let val: int = otherval + 5;
// Private and constant
@private
let something: int = 20;
}
// Members in this class default to private (the LSP should show you which ones are public/private?)
@default_visibility(private)
class OtherClass {
@public
var my_val: int = 30;
@public
@restrict_construction
let something: int = 23;
}
The question, then, of course is what do "private" and "public" actually mean. I think in general I will want "private" to mean private to the file that the class is defined in -- this (sort of) matches what Rust does, which tends to be pretty convenient.
We could, however, also have something like @private(file) versus @private(class), or even @private(.my_fun) to restrict the variable's access to a single function. That is something fun to consider... eventually.
One other thing that would be "fun" but is maybe not worth considering right now is having some sort of "constant reference" type. This type is definitely useful in the case of Arrays, for example, where we would like to be able to pass an Array[Dog] as a const Array[Horse], or something along those lines.
I'm not sure exactly the best syntax (or even semantics) for that. It is important to note that these are reference modifiers, so they don't actually change the underlying type of the data, only how a specific pointer is allowed to interact with that data.
The main idea is you would have something like
class Array[T] {
@const
fun operator[] -> T {
...
}
}
But I feel like annotating every function that can be safely used with a const reference is very annoying.
These could be inferred by the compiler, but that would mean that changing a function's implementation can be a breaking change if it makes the function non-@const.
Now that we have a
readonlyflag on our variables, almost the only thing missing from PonieScript to have constant (not reassignable) variables is the syntax to do so.Right now I am thinking of using
letas the keyword for this, as opposed tovarfor reassignable variables.However, the obvious question this brings up (at least in my mind) is: What do we do when we want a readonly class member, that you CAN'T assign a different value to during construction?
Such a value would still be "public," but would be prevented from appearing in new{} expressions.
I think ultimately we will want GDScript or Rust style "annotations," which we might also use for plain visibility. Something like:
The question, then, of course is what do "private" and "public" actually mean. I think in general I will want "private" to mean private to the file that the class is defined in -- this (sort of) matches what Rust does, which tends to be pretty convenient.
We could, however, also have something like
@private(file)versus@private(class), or even@private(.my_fun)to restrict the variable's access to a single function. That is something fun to consider... eventually.One other thing that would be "fun" but is maybe not worth considering right now is having some sort of "constant reference" type. This type is definitely useful in the case of Arrays, for example, where we would like to be able to pass an
Array[Dog]as aconst Array[Horse], or something along those lines.I'm not sure exactly the best syntax (or even semantics) for that. It is important to note that these are reference modifiers, so they don't actually change the underlying type of the data, only how a specific pointer is allowed to interact with that data.
The main idea is you would have something like
But I feel like annotating every function that can be safely used with a const reference is very annoying.
These could be inferred by the compiler, but that would mean that changing a function's implementation can be a breaking change if it makes the function non-
@const.