If you know me from Reddit, you might know that I'm in love with Ruby programming language XD
There are some things in Ruby (and some other languages too) that I miss in GDScript. Some of them might be controversial and they are all probably for Godot 4.0, but thought I'd write it for discussion purposes etc. So the list is:
I noticed that GDScript supports both and and &&. I was disappointed when I discovered they have same precedence. In Ruby, symbolic operators have precedence over word ones (so e.g. && is evaluated before and) and it's sometimes useful in complex conditions to avoid using brackets. I mean, since both of them are supported, they might be more than aliases.
It works like this Ruby and LUA (and probably some other). I know GDScript takes heavily from Python, but that doesn't mean it should work exactly like that. There are people that take advantage of 0 being false, but there are also people that expect it to work otherwise. I for example like to make a null variable that has later number assigned and then I check if it exists and e.g. increment it. It was confusing to me few times when it didn't work. I know it's a matter of writing if variable != null, but still.
EDIT:
Apparently, zero vector is "false" too. Really? 卢_卢
As stupid as it seems, it's useful when you are e.g. searching inside array. Normally you need to do
var found_one = find_in_array(something)
if found_one:
found_one.do_something_etc()
This could be replaced by
if found_one = find_in_array(something):
found_one.do_something_etc()
Maaybe in GDScript you'd need var after if, because otherwise it's less helpful, but right now you can't do something like this at all.
Sometimes you want two variables to have one value. You need to do
b = a
c = a
While with chained assignment you could just do this:
b = c = a
Also in Ruby, you can go further:
a, b = c, d
I know that what am I proposing here are probably some useless quirks (arguably except the first one) that just make you save one line or few extra character. I'm not saying of course this MUST be a thing, I'm just writing this, because at some point I actually wanted to use each of them at least once, which means that there are some use cases where this might be useful for some people. While first two might break some scripts, 3 and 4 don't really affect anything other than giving more options.
Any thoughts? >.>
You should try to search for existing issues first: #7222, #7584
Huh, #7222 would work both for 3 and 4. Seems like it was rejected though :/
Dunno, instead of preventing the construct at all, Godot could just should throw a warning, so you know that it's there, but you could leave it like this. Or maybe there could be a list of "ignorable" errors, that _really advanced users_ could opt-out from showing. I know it's not beginner friendly to allow this etc. but maaybe making it optional somehow wouldn't really hurt.
btw, it isn't always easy to find what you are looking for, because it can be named otherwise than expected (e.g. I suspected Python has "list unpacking", but didn't now it's named like that; or that "assignment = expression" thing).
Having used Ruby myself, I can see where the convenience of these ideas could come in. Here's my take on these ideas:
Yes. Yes. Yes. If they're going to allow both, people are probably going to use one or the other, not both in combination.
0
and []
as true
Wait, you mean they aren't already? This whole time, I've been under the assumption that checking if something:
would always treat something
as true
unless they were exactly null
or false
. Why are empty arrays and 0s not counted as true?
This would be useful, but I can't tell you the number of times in Ruby I've accidentally left one =
in there instead of two. Every time, it took me a while to figure out that I was assigning by accident, not just checking equality. Maybe this would be useful? But consider what drawbacks it could have. I wouldn't say "no" to this just on the basis of the confusing situations it could lead to, though -- maybe we could use a warning if someone does if a = b
? Just something to say "Hey, double-check that you meant to do assignment here".
I have no comment on this.
Why are empty arrays and 0s not counted as true?
Because Python. GDScript already differs from Python tho, so this could be changed too IMO.
maybe we could use a warning if someone does if a = b?
That's what I said in my previous comment. Also, advanced users should be able to disable these particular warnings. At first I assumed it won't introduce problems, but well, they can be taken into account and feature could be implemented properly, instead of outright rejecting the change, like in referenced issue.
That's what I said in my previous comment.
Oh my bad, I didn't notice.
Also, since you seem unsure if ignorable errors could be implemented, let me point you to the warning system proposal itself: #19993
Wow, that warning system seems perfectly suited for this case D:
More and more I feel that we should solve #18698 once and for all. It's not bad to submit proposals, but usually those come from familiarity with other languages, which not always fits the GDScript feel.
Treat 0 and [] as "true"
How many languages treat 0
as true
? That sounds very alien to me. I don't think many people expect it to work this way (in fact, false
is pretty much an alias to 0
, considering the legacy from C). I can see about the empty array, but I still think it's normal to treat it as false
.
Different precedence for and/or/not and &&/||/!
Again, I wouldn't expect them to have different precedence. For me they are just alias of one another, they shouldn't behave any different. I always use and/or/not because they look more idiomatic in GDScript (I'm not even sure why the other ones are supported, likely just to appeal to regular C++ users).
Allow for assignment inside condition statements
Allow for chained assignement
I already commented on the other issue. IMO being less error-prone is better than saving a few characters in the code.
How many languages treat 0 as true?
I tried to find some data, but hard to find a good list. Anyways, 0 being false is no more than a legacy. I just prefer the philosophy where "if it exists, it counts as true" and 0 and [] is actually _something_ in this case. There are other people who will agree. But well, it's debatable.
Again, I wouldn't expect them to have different precedence.
As LikeLakers2 said, people rarely, if ever, use both of them in one condition (like, why would you mix and with ||?). These who would do otherwise likely expect these operators to have differences.
IMO being less error-prone is better than saving a few characters in the code.
With warning system you can have both - allow this for people who want it and make sure that other people will know that they made a mistake. Only people that don't read warnings will be negatively affected.
(like, why would you mix and with ||?)
I meant that people don't seem to mix and
and &&
, or
and ||
, not
and !
. They might mix between different operators for different functions (and
, or
and !
are what I typically use), but I've rarely seen people use both not
and !
in the same statement.
if something
is equivalent to if boolean(something)
thus if bool(0)
should be false
(and true
for all other numbers), a number is a raw value.
if bool([])
should be true
because an empty array is a value, its length is another problem.
Technically in List work the empty array is false, or rather false is defined as the empty array, the empty array being nil
(and things like an array of [1, 2, 3]
being a list of 3 Cons Cells of (1, (2, (3, ())))
, so the empty array being false makes perfect sense. A reference may or may not be false depending on if it is null
or not, but with the now Typed GDScript not everything is a nullable reference and the values there-of are important. Similar with 0
for integers and so forth.
I don't have an opinion on 2 and 3, but I think 1 and 4 are good proposals.
If there's two operators for "and" etc, it makes sense for them to have functional differences, plus it's unlikely to break existing projects since I doubt people would mix-and-match. It makes sense for the symbols to have higher precedence, since "a && b and c && d
" just sounds right.
I use chained assignment often in C#, it's quite useful.
How many languages treat
0
astrue
?
@vnen Bash comes to mind, since 0
means "true" and "no error", while 1
, 2
, etc, means "false" and "exited with error code X". But I don't know if this is useful for GDScript.
If there's two operators for "and" etc, it makes sense for them to have functional differences, plus it's unlikely to break existing projects since I doubt people would mix-and-match. It makes sense for the symbols to have higher precedence, since "
a && b and c && d
" just sounds right.
Mixing both in the same statement can also hurt readability, so I'm not sure if the precedence of symbolic operators should be changed in GDScript. I'm fine with the current way to do things (consider wrapping long if
statements over multiple lines using parentheses).
How many languages treat
0
astrue
?
In Erlang only the atom false
is false, everything else, including 0
is true.
In Elixir only the values nil
and false
are false, everything else, including 0
is true.
I think 0
in Lua is also true if I recall right?
In OCaml and other similar languages 0
is not a boolean value and cannot be cast to one as such, thus it is not false.
Etc... etc... etc...
Mixing both in the same statement can also hurt readability, so I'm not sure if the precedence of symbolic operators should be changed in GDScript.
There's lots of things that hurt readability, like inline if statements, which are against style guides and sometimes cause a bug in debugger (ironic XD, but reported #20820). Should we really disallow practices that "hurt readability" to the point where they are not possible? Nope. Just let people write the code the way they want and if you think it's bad, just document it as "don't use it". Or don't document it at all :v
Also for the _0 = true_ thing, most scripting languages treat 0 as true.
Should we really disallow practices that "hurt readability" to the point where they are not possible?
I personally value consistency over being able to use my preferred style, so we can spend less time on arguing about style and more time programming :slightly_smiling_face:
Even if or
and ||
have different precedence, it'll never be clear which has the higher precedence, so it will not be clear what's happening. If you want to change precedence just use parentheses, it's not that bad.
How many languages treat
0
astrue
?
Erlang [...] Elixir [...] Lua [...] OCaml [...]
Apart from Lua, those are functional and not widely-known languages, so it's not ideal for reference. GDScript is meant to be simple, it should follow the trends of more popular languages.
I still support 0
as false
to be an "empty" value (same to []
and even Vector2()
), and thus equate to false
, especially since GDScript doesn't have nullable types. You can consider zero as "not set" for integers, the same way a null
would be for objects. If you really want to check if something is null
, simply use if something == null
.
I'm of the opinion that 'false' is a boolean, a '0' is an integer, an integer != a boolean, thus 0 is not false nor true. Though in the untyped side of gdscript 0 equating to false seems fine, but it shouldn't be allowed in typed code (or it fails typing) and an explicit !=0
test should be performed instead.
Yes! Would be useful and I don't see any downside with it
I don't think 4. is something that's done often enough to justify making the parser more complex. There's a maintenance cost that comes with every feature :slightly_smiling_face:
Closing because it's a proposal on main repo, which is illegal (XD).
I still very much support 1, so I might create a separate proposal for it. I don't recall 3 and 4 being very useful recently (maybe I used to write bad code and I don't do it anymore). Also 2 turned out to would have been less convenient than current behavior.
@KoBeWi The &&
and ||
logical operators will be deprecated in 4.0 (in the interest of consistency). They will still work, but you'll get a warning when using them.
I know. That's why I wanted to propose repurposing them instead.
@KoBeWi The
&&
and||
logical operators will be deprecated in 4.0 (in the interest of consistency). They will still work, but you'll get a warning when using them.
Why? Its shorter and makes sence and is also how it works in many other languages. Removing it makes 0 sence.
@MCrafterzz Python doesn't have &&
聽and ||
. This means that in GDScript, you just have another way to do the same thing. This makes style guides longer when they could have been shorter :slightly_smiling_face:
Ruby has &&
and ||
with higher precedence than and
/or
, but it's easy for that feature to become confusing, especially for beginners.
Eh, I was just writing a proposal and scrapped it halfway, because I realized that for the most common use case a and b or c and d
the precedence doesn't matter .-.
Most helpful comment
More and more I feel that we should solve #18698 once and for all. It's not bad to submit proposals, but usually those come from familiarity with other languages, which not always fits the GDScript feel.
How many languages treat
0
astrue
? That sounds very alien to me. I don't think many people expect it to work this way (in fact,false
is pretty much an alias to0
, considering the legacy from C). I can see about the empty array, but I still think it's normal to treat it asfalse
.Again, I wouldn't expect them to have different precedence. For me they are just alias of one another, they shouldn't behave any different. I always use and/or/not because they look more idiomatic in GDScript (I'm not even sure why the other ones are supported, likely just to appeal to regular C++ users).
I already commented on the other issue. IMO being less error-prone is better than saving a few characters in the code.