Open Wavesonics opened 4 years ago
Can't be worked around
You can make a setter function with setget and only assign a value if it is null.
@Jummit only if you are talking about a member variable, not if this is a local variable.
For reference, quoting my own message from https://github.com/godotengine/godot/issues/23695:
I'm in favor of
let
, as it's harder to confuse compared toval
(which looks close tovar
at a quick glance). Some languages like Nim already uselet
for immutable variables. However, there's the downside that JavaScript users may be confused by this keyword, sincelet
variables are mutable there.Edit: Swift also uses the
let
keyword for immutable variables (andvar
for mutable ones).
It can enforce a variable only gets assigned once in an if/else chain or match statement:
Allowing this would likely complexify the implementation a fair bit, so I'm not sure about it. (Just a gut feeling, I'll let vnen decide on this.)
It can enforce a variable only gets assigned once in an if/else chain or match statement:
Allowing this would likely complexify the implementation a fair bit, so I'm not sure about it.
Using if/else in its expression form and introducing or improving match to be an expression would IMO solve the problem more elegantly (without the need of flow analysis which I imagine would be quite a feat to implement).
@Jummit only if you are talking about a member variable, not if this is a local variable.
Local variables do trigger setter and getter functions when used with self
. See a related proposal.
Unrelated, I'd also like to state that val
and var
are not only too similar, but some people have trouble pronouncing "L" and "R" properly, so let's not open that can of worms. ;)
I use val
as a var name for locals and property arguments a lot. Maybe some other keyword or combination of keywords could be used? var my_variable = x const
maybe?
Other suggestions:
const var
immutable
final
or sealed
readonly
let
or just allow local constants.... But I'm guessing the reason that wasn't allowed is because of philosophy over the definition of what const
is and should be....
Describe the problem or limitation you are having in your project: I can't enforce a varriable only being assigned once
Honestly, this is not the purpose of the heading. Making a proposal "I want X" then say that's because "I can't do X" isn't very informative. The question is: why do you need variables to be only assignable once?
I know it's an interesting programming concept that some languages implement. But why and how would that be beneficial in GDScript?
or just allow local constants.... But I'm guessing the reason that wasn't allowed is because of philosophy over the definition of what
const
is and should be....
Not sure what such philosophy is, but in Godot 4 local constants will be allowed. From the perspective of implementation it's a no-brainer since now it can reuse almost all of the code made for class constants (which wasn't the case before).
Not sure what such philosophy is,
Well, normally, I imagine it would be that a keyword like const
is typically reserved for variables that are known to be constant at design-time, which is definitely different from variables that are immutable. const
s in that sense would only be a subset of immutable variables, the latter of which only become "constant" once they're first assigned (though I imagine most syntaxes require assignment on the same line as where an immutable var is declared).
Fair point about the heading. It wasn't meant to be facetious, but I suppose I could have added a bit more to it. Local const
does solve many of the use cases I had in mind. One pattern that I personally like which it does not cover is something like the val
keyword in Kotlin:
val x: int
if(condition_1)
x = 1
else if(condition_2)
x = 2
else
x = -1
If someone goes back to maintain this code, it's fairly resistant against mistakes. Removing the else
will result in unassigned error at compile time. Adding another branch but forgetting to assign x
is a compiler error, modifying an existing branch, but adding a path that doesn't assign or, or even re-assigns it, all result in compiler errors.
The more common use case of just assigning a local that shouldn't be changed is covered by local const though, so that would solve a lot of my own use cases as well.
I think some mention should be made about the concept being something being visibly immutable. For example, say I have the following value:
class_name Player extends KinematicBody
var _breadcrumbs: = PoolVector3Array();
Then I wanted to expose it by providing a get function.
func get_breadcrumbs(index: int) -> PoolVector3Array:
return self._breadcrumbs;
Visibly const would allow you to guarantee that the callsite cannot modify the data structure while having it mutable as usual within the origin class, by providing a limited view to the data without having to write multiple sets of getters.
func get_breadcrumbs(index: int) -> readonly(PoolVector3Array):
return self._breadcrumbs;
This is just spit-balling however, as I don't really use GDScript enough yet to know if this would have any implications that would break existing code or go against any sort of design philosophy with it.
I wanted to make a proposal for this but i'm not sure if it's worth a proposal and it makes more sense in the current context so i'll mention it here.
The idea is to add oninstanced
keyword. It would assign variables upon instantiation, so when NOTIFICATION_INSTANCED gets emitted. Or more precisely - right before that, just like var k = 5
at the top of the script is initialized right before _init()
.
I recall some users had the need to refer to child nodes before _ready()
.
It'd be useful mostly for caching child nodes which now is usually done with onready
keyword. oninstanced
would be allowed to be used in place of onready
:
oninstanced val = $"Godot 4 will be great"
or
oninstanced let = $"In the meantime try Godot 3.3"
or whichever keyword would be chosen.
Why does it make more sense in the context of this proposal? Because oninstanced
would be the last time an immutable script variable could be initialized which would allow for code like the one above. It would give immutability + value assignment on declaration line.
Well, seems that using:
let
imut
Seems to be good options!
Also This could let us export those imutables, for example, lets suppose I want a constant speed variable, but I want to export it so I can change it:
@export imut MAX_SPEED := 10.0 # This can be changed only in-editor
Hi, I need this Feature
Here is where (Godot 4.0 beta 7):
@export var week: Week : set = set_week
var _is_ready: bool = false
func _ready() -> void:
connect("ready", func () : _is_ready=true)
func set_week(value: Week) -> void:
if not self._is_ready:
await ready
week = value
# Update the Children
for weekday in self.get_children():
#Do stuff ...
You see that _is_ready
is never suppose to change and if it does, the children won't get updated.
So let's just pretend it's 2:00 am in the Morning and I make the mistake of writing _is_ready = false
in a random script or another contributer was just playing around with it
Now I have to try and find the error
If the variable would be immutable, the debugger would point me right to the codeline, where I try to assign a value to an already locked variable
But without it I'd be noticing that my children aren't getting updated anymore
And depending on the projects size I might be looking into multiple error sources
Once I would have figured out it's _is_read
I'd still have to find the piece of code that changes it (which might be inside a random script somewhere in my project)
You get my point
So please let
me lock varialbes! :D
4.0 is in feature freeze. This may be added later in 4.x because it doesn't break backwards compatibility. The current workaround is
var my_var = init_value:
set(value): assert(false, "my_var is readonly")
Hi, I need this Feature
Here is where (Godot 4.0 beta 7):
@export var week: Week : set = set_week var _is_ready: bool = false func _ready() -> void: connect("ready", func () : _is_ready=true)
@MaasTL right here you are changing the value, so immutability would not solve for you because the _is_ready
wouldn't be allowed to change to true
after the initial assignment of false
.
This case could be worked around with a setter:
var _is_ready: bool = false:
set(value):
_is_ready = _is_ready or value
This way it can only ever change from false
to true
, assuming the node is not supposed to leave the tree and become "unready".
This case would require you to change at runtime the immutability state of a variable which I think it's a bit dangerous and also harder to enforce (no compile-time checks would be possible for instance). I believe it would be better solved by access modifiers if we want to go that route.
Regarding keyword, I believe it's much better to find an affix for var
rather than just replacing it. So readonly var x
or var immutable x
. It is just much more clear what means instead of trying to figure out the difference between var
and let
or val
. Not to mention that val
is very close to var
and might be mistaken for one another in a quick glance.
Or an annotation, which is much more compatibility friendly, though I do prefer avoiding annotations for this kind of thing.
readonly
could also work but I insist that const
should be use here.
For most cases readonly var
and const
will work the same. The only diference will be with maps and arrays when const
should allow to not change the reference to a new one but to alter the map or array
readonly
could also work but I insist thatconst
should be use here.
const
is used in GDScript in the sense of "value known at compile time", like constexpr
in C++.
The only diference will be with maps and arrays when
const
should allow to not change the reference to a new one but to alter the map or array
In 4.0 this was changed, now the contents of const
arrays and dictionaries cannot be changed.
In 4.0 this was changed, now the contents of
const
arrays and dictionaries cannot be changed.
That is what I'm implying. If values of arrays and maps can be changed in const that would solve the need of a val
or readonly
. The reference cannot be changed but the content of the array or map.
@jcostello that wouldn't solve the problem as you still wouldn't have immutable variables. While you wouldn't be able to change the reference, you could still change it's contents the same way you can change a regular variable. So you cannot use the contents as readonly since they can be changed and the array itself needs to be a compile time constant to use const
so it's also not a solution even if you want an array.
However, since Godot 4 has read-only Arrays and Dictionary, you can actually leverage that for sort of immutable variables:
var imut_container := { imut = non_const_expression() }
imut_container.make_read_only()
imut_container.imut = "new value" # Gives an error since the dictionary is now read-only.
I believe this is a key feature that Gdscript is missing, and it would be extremely helpful for things like exports.
I would use let
instead of val thought as it's more distinct.
Imutable variables are key for functional programming patterns.
As for branches, I agree that they should allowed to be used as expressions, and even could replace the current ternary statements, but that would require rust like results, aka implicit return of the last expression in a block. this however should be mentioned in a separate issue.
let b = true
let a = if b: 6 else: 9
let c = if b:
6
else:
9
Bugsquad edit: Removed excessive quoting.
I think it's too much of a footgun for val
and var
to differ by only one letter, both of which consist mostly of a vertical stroke.
I think it's too much of a footgun for
val
andvar
to differ by only one letter, both of which consist mostly of a vertical stroke.
Scala uses var
and val
and I don't think in hundreds of hours I have ever used them incorrectly. Probably because I use val
everywhere and only where performance is extra important var
was used. Another approach would be to have val
(immutable) and mutable val
(mutable). But I suspect preferring immutability (similarly to FP and types) is not something GDScript devs are interested in. It could be a setting of a project (when enabled everything is immutable by default, explicit modifier must be used to make it mutable), but I believe similar proposal was shot down with enforcing types.
Changing var
to val
is not going to fly as it is a huge compatibility breaking change
Also changing from mutable by default to immutable by default additionally breaks compat, and makes the code for even simple things significantly more complex by adding mutable
everywhere
It also makes little sense to me to have immutable by default in a script language
I think it's too much of a footgun for
val
andvar
to differ by only one letter, both of which consist mostly of a vertical stroke.Scala uses
var
andval
and I don't think in hundreds of hours I have ever used them incorrectly. Probably because I useval
everywhere and only where performance is extra importantvar
was used. Another approach would be to haveval
(immutable) andmutable val
(mutable). But I suspect preferring immutability (similarly to FP and types) is not something GDScript devs are interested in. It could be a setting of a project (when enabled everything is immutable by default, explicit modifier must be used to make it mutable), but I believe similar proposal was shot down with enforcing types.
FP patterns are on their rise recently, and imutability would be wonderful for things like apis.
I personally don't like mutable val
and in my opinion if this was to ever happen system closer to rust let
and let mut
would be better although let mut
would replace var as so it shouldn't be a project setting, and due to that it would be a major breaking change, so it is not a very good idea on its self.
Scala uses
var
andval
and I don't think in hundreds of hours I have ever used them incorrectly. Probably because I useval
everywhere and only where performance is extra importantvar
was used. Another approach would be to haveval
(immutable) andmutable val
(mutable). But I suspect preferring immutability (similarly to FP and types) is not something GDScript devs are interested in. It could be a setting of a project (when enabled everything is immutable by default, explicit modifier must be used to make it mutable), but I believe similar proposal was shot down with enforcing types.
The same rationale could be used to argue that there was no need to disallow assignment in tests in if
statements in Python and Rust and so on because "I never have a problem avoiding accidental if x = 1
in C".
Just because you don't have a problem with an error-prone design decision in one language doesn't mean it's a good design decision.
Changing
var
toval
is not going to fly as it is a huge compatibility breaking changeAlso changing from mutable by default to immutable by default additionally breaks compat, and makes the code for even simple things significantly more complex by adding
mutable
everywhereIt also makes little sense to me to have immutable by default in a script language
Yes indeed, we shouldn't not change var
to val
.
As for adding mutable everywhere I disagree, there exists a some languages with imutable by default for instance rust, and from personal experience I rarely rarely have to mutate data.
Also something unmentioned is that imutable variables can prevent bugs that occur by accidental mutation of a value,
like for instance you have a export for the player jump height, exports as far as I'm aware cannot be const
therefore a bug could be unintentionally introduced along the line that for example doubles the jump height
prevent bugs that occur by accidental mutation of a value
The proposal literally mentions this as an argument
prevent bugs that occur by accidental mutation of a value
The proposal literally mentions this as an argument
Oh I did realize it my bad
I like readonly var
or let
. But readonly var
has questions:
1. Should it be an annotation or a keyword? static
is a keyword, @onready
and @export
are annotations. If we add public
/protected
/private
modifiers in the future, will they be keywords or annotations? For example, private readonly static var x = 1
.
The point of annotations is to reduce the keyword count and keep the parser simple, but static
is a keyword. I think this is because static
is a common keyword in different programming languages, while @onready
and @export
are Godot-specific.
2. Immutable variables can also be useful as local declarations, in which case you probably don't want long keywords. Especially since 4.x supports local constants. I'd prefer let
or other keyword (but not val
, since it's too similar to var
).
var
and const
are different keywords for "stored values" with different traits, not var val
and const val
for example.
var
- value can change at runtime.let
- the value is known upon assignment and cannot be reassigned (can't change if we think about references, not contents).const
- the value is known at compile time and can't change.If we have var
and let
, then we allow the user to choose the option they need from two "equal rights" options (three with const
). We do not impose any of them, neither mutable nor immutable. And if we have var
and readonly var
, then we implicitly prefer the mutable option, and make the immutable option secondary / more verbose / less accessible.
Just because you don't have a problem with an error-prone design decision in one language doesn't mean it's a good design decision.
Scala had recently(ish) a major release with many breaking changes. Had this var
vs val
been an issue, they would have changed it (they changed many core features and syntax). They haven't, so that tells me very few people in real world has problems with it.
I would wager it comes from the "prefer safer" approach. If you heavily prefer immutability (of variables and inside data structures), you rarely use var
and almost everywhere is val
, so at worst when you try mutating/reassigning something which you wanted to be var
but made a mistake with val
, compiler complains. If you heavily prefer val
, then other way doesn't really happen, because you have so few var
s in a place and those are carefully chosen because of limitations like performance.
Edit: Also since Godot comes with a script editor, it should be quite simple to implement e.g. coloring based on which variable is var/val (or any other names capturing same idea).
My favourite language is Rust, so I'm well aware of the whole "most variables don't need to be mutable" thing and agree... but "code is read more than it's written".
Having val
and var
be so similar is like forgetting your commas when writing prose. You can infer around it, but it's much more prone to mis-reading... especially if the person doing the reading isn't having a well-rested, distraction-free day.
Also changing from mutable by default to immutable by default additionally breaks compat
Maybe I didn't write it correctly, I meant by default option for "non-reassignable by default" would be off. So no change in compat.
and makes the code for even simple things significantly more complex by adding mutable everywhere
Well, yes, that's the point in such languages. Since mutations are source of many bugs (especially in parallel and async programming), it is generally best to not prefer them (not make it easier for a user to shoot themselfes in the foot - make mutable variables very apparent in the code). I also believe non-reassignable "variables" have performance benefits, or at least potential for more optimization.
It also makes little sense to me to have immutable by default in a script language
What difference does it make, if you are using highlevel language or scripting language to interact with the engine? You can script okish in Scala (Ammonite) or Haskell (Stack) and both have immutable data structures, Haskell has non-reassignable "variables" (thought redefinable in certain places), Scala supports both. Also by GDScript adding types and being compiled (if I understand the export process correctly), it has started moving away from a scripting language in my opinion. Again, I may have written it wrongly before, but I meant an option toggle on "non-reasignable by default" for a project, not that such option would be by default activated. Immutable data structures by default could be quite a problem, I fully agree. Might be a better approach to just add new data structures which are immutable and a warning/error (with option to disable with comment or similar) if you use a mutable datastructure in non-reasignable "variable".
Having val and var be so similar is like forgetting your commas when writing prose. You can infer around it, but it's much more prone to mis-reading... especially if the person doing the reading isn't having a well-rested, distraction-free day.
I honestly don't really care how it will be called (just that it's short), I just pointed out var/val seems to be a non-issue and demonstrated that on pretty large language and its recent rework where they fixed a lot of similar usability issues, but this wasn't one of them. I wouldn't like to have another FP (maybe just FP close?) feature feeling like afterthought because of cumbersome syntax, similar how lambdas ended (very verbose, to the point my hacky library for v3 is better, at least in syntax).
I honestly don't really care how it will be called (just that it's short), I just pointed out var/val seems to be a non-issue and demonstrated that on pretty large language and its recent rework where they fixed a lot of similar usability issues, but this wasn't one of them. I wouldn't like to have another FP (maybe just FP close?) feature feeling like afterthought because of cumbersome syntax, similar how lambdas ended (very verbose, to the point my hacky library for v3 is better, at least in syntax).
ivar
(immutable var) would be good enough, since it's an additional character rather than just one character changed to another, similar one.
var
vs. let
would be a valid choice under the same logic, since they're so visibly different.
+1 for let
, it's short, clearly visually distinct from var
, and has a lot of precedent being used for immutable variables (javascript is the exception that proves the rule)
let
would also put the language into a state where you could pretend that let
came first and var
was added later, which is nice.
Imutable variables would be amazing for exports, thats what i would mainly use them for
I like
readonly var
orlet
. Butreadonly var
has questions:
- Should it be an annotation or a keyword?
static
is a keyword,@onready
and@export
are annotations. If we addpublic
/protected
/private
modifiers in the future, will they be keywords or annotations? For example,private readonly static var x = 1
.The point of annotations is to reduce the keyword count and keep the parser simple, but
static
is a keyword. I think this is becausestatic
is a common keyword in different programming languages, while@onready
and@export
are Godot-specific.
- Immutable variables can also be useful as local declarations, in which case you probably don't want long keywords. Especially since 4.x supports local constants. I'd prefer
let
or other keyword (but notval
, since it's too similar tovar
).
var
andconst
are different keywords for "stored values" with different traits, notvar val
andconst val
for example.
var
- value can change at runtime.let
- the value is known upon assignment and cannot be reassigned (can't change if we think about references, not contents).const
- the value is known at compile time and can't change.If we have
var
andlet
, then we allow the user to choose the option they need from two "equal rights" options (three withconst
). We do not impose any of them, neither mutable nor immutable. And if we havevar
andreadonly var
, then we implicitly prefer the mutable option, and make the immutable option secondary / more verbose / less accessible.
If i were to choose i would prefer readonly
. I think the points about it being more verbose are not really warranted, considering we have autocompletion. I would expect it to autocomplete in this case if typing an r on a new line, so it would just be two key presses anyway. It is also much easier to see when skimming code.
Also, whether most variables need to be mutable or not, most people will have most variables mutable, so i don't see `readonly
being used that often.
I also do not think they belong as annotations.
If i were to choose i would prefer
readonly
. I think the points about it being more verbose are not really warranted, considering we have autocompletion.
If declaring and initializing in separate locations (eg. declare in file/class scope, initialise on construction) is supported, then readonly
will be misleading, since it's really "write once".
Also, whether most variables need to be mutable or not, most people will have most variables mutable, so i don't see
`readonly
being used that often.
I don't think it's reasonable to use an assumption like that to justify making it more verbose for people coming from languages like Rust or various functional languages to do the "immutable unless mutation is necessary" pattern. That's reminiscent of how making const
-ness and restrict
opt-in in C and C++ limit their real-world use.
If declaring and initializing in separate locations (eg. declare in file/class scope, initialise on construction) is supported, then
readonly
will be misleading, since it's really "write once".
Isn't that the same with C#?
I don't think it's reasonable to use an assumption like that to justify making it more verbose for people coming from languages like Rust or various functional languages to do the "immutable unless mutation is necessary" pattern. That's reminiscent of how making
const
-ness andrestrict
opt-in in C and C++ limit their real-world use.
The assumption being that beginners will most likely keep all variables mutable. Its the same precedent set with types. I would argue languages like Rust are more advanced but here with GDScript, we are trying to lower the cost of entry for beginners.
I guess we need to decide what is best for a language developed primarily for game development, that also allows easy entry for beginners but also allows advanced programming techniques for professionals, or for building larger and more advanced games.
If declaring and initializing in separate locations (eg. declare in file/class scope, initialise on construction) is supported, then
readonly
will be misleading, since it's really "write once".Isn't that the same with C#?
I don't think it's reasonable to use an assumption like that to justify making it more verbose for people coming from languages like Rust or various functional languages to do the "immutable unless mutation is necessary" pattern. That's reminiscent of how making
const
-ness andrestrict
opt-in in C and C++ limit their real-world use.The assumption being that beginners will most likely keep all variables mutable. Its the same precedent set with types. I would argue languages like Rust are more advanced but here with GDScript, we are trying to lower the cost of entry for beginners.
I guess we need to decide what is best for a language developed primarily for game development, that also allows easy entry for beginners but also allows advanced programming techniques for professionals, or for building larger and more advanced games.
Yes, that's why I believe let
would be the best choice, it's not veborse and it's simple
I see 2 advantages to val
or let
:
var
so they will look nice next to each othervar foo := 3
var bar :Node
val baz = "Godot is awesome!"
@export
. People might also be using it with @readonly
. We could also consider potential syntax additions like encapsulation wich would most likely require a keyword in front of every variable.@onready private readonly var some_stuff
would be quite lengthy.
I think, conventions aside, var
and val
are too visually similar and would be bad for readability. So I'm in favor of let
I think, conventions aside,
var
andval
are too visually similar and would be bad for readability. So I'm in favor oflet
vnen was more in favor of an annotation in this comment, but maybe I'd go for @final
in this case (Python uses a : Final
type annotation as part of its typing_extensions
package).
My only concern would be potential confusion for people coming from Java. Java's final
is best known in its role as the inverse of C++'s virtual
rather than in its role as being about single-assignability.
I could easily see that confusing people who've had a semester or two of Java and little more.
(I'm one such person and I'd actually either forgotten or never learned about its use outside opting out of virtual dispatch.)
Any keyword that makes the variable immutable is fine. It can be readonly var
or let
or final var
.
My question in the code below
# Defined a read-only var variable, it can be any keyword
class_name ParentClass
readonly var MYCLASS := CustomClass.new() #1st assignment
func _init()
MYCLASS = CustomClass.new() #2nd Assignment
Which assignment is final? If 1. then why not use const keyword as anyway the reference will be const not the content If 2. then can it be assigned in derived class also. (It gives quite flexibility and power)
"let" will probably confuse people coming from webdev. In modern JavaScript, let is a way to define scoped reassignable variables ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let )
I know JS is the only language using let this way... But it's also the most widely used language worldwide ( https://www.statista.com/statistics/793628/worldwide-developer-survey-most-used-languages/ ) and GDscript also contains a "var" keyword just like JavaScript, so the confusion potential for new users is quite high imo
Although Godot has been upgraded to version 4.2 and there are still no runtime constants that we can use, i think it is quite unreasonable to think that the let
keyword may be misunderstood by JavaScript programmers.
What really worries me is that, as @Calinou said, "Immutable variables must also be initialized as soon as they're declared." Will this prevent us from defining immutable variables in the constructor method when creating an instance? What i mean is, one of the situations where such an immutable variable would be most useful would be as used in the code snippet below.
class_name SomethingHasImmutableID
extends Object
let id: int
func _init(p_id: int):
id = p_id
like in cpp
class SomethingHasImmutableID {
private:
const int m_id;
public:
SomethingHasImmutableID(int p_id)
: m_id { p_id }
{}
};
If you let me think out loud, imho to achieve the effect here, it can be ensured that let variables can be defined as null, and then the first assignment can only be made if it is null, throw an error otherwise for sure. But the problem here is that initialization does not have to be done in the _init function. In fact, it is not necessary to do it at all. It is obvious that such a situation is unacceptable. Therefore, if it is known that a value is assigned to the let variable in the _init function, then the let variable can be allowed to be defined as null.
Would be great to make it work with @export too, my use case would be like :
class_name ResourceContainerBase
extends Object
@export readonly path: String
...
func create() -> ResourceContainerBase:
var ressource= preload(path)
...
return ressource
...
class_name ResourceContainerImpl
extends ResourceContainerBase
func _init():
path= "const path inside godot"
For now, preload work only only work on const variable that we can't associate with export (use it more for serialisation than edition), Parse Error: Preloaded path must be a constant string.
But when writing this message I supose maybe it would be complicated to make it, even if we have const inside variable, set it in children could be make the task too complicated.
Describe the project you are working on: video game
Describe the problem or limitation you are having in your project: I can't enforce a varriable only being assigned once
Describe the feature / enhancement and how it helps to overcome the problem or limitation: I propose adding a new keyword to GDScript:
val
in addition to the existingvar
for declaring variables. This would force the variable to only be assigned once.Kotlin, ECMA6, and Swift all have a feature similar to this.
Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: declaring a variable as
val
will throw a error if the variable is assigned more than once. It allows for a few nice conventions: 1) It allows for a sort of scoped constant (currently constants can only be global) 2) It prevents accidental re-assignments for varriables that weren't intended to change. It makes maintaining the code less error prone. 3) It can enforce a variable only gets assigned once in an if/else chain or match statement:If this enhancement will not be used often, can it be worked around with a few lines of script?: Can't be worked around
Is there a reason why this should be core and not an add-on in the asset library?: Can't, it's a language level feature