Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Some GDScript behavior proposals #20634

Closed
KoBeWi opened this issue Jul 31, 2018 · 26 comments
Closed

Some GDScript behavior proposals #20634

KoBeWi opened this issue Jul 31, 2018 · 26 comments

Comments

@KoBeWi
Copy link
Member

KoBeWi commented Jul 31, 2018

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:

  1. Different precedence for and/or/not and &&/||/!

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.

  1. Treat 0 and [] as "true"

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? ¬_¬

  1. Allow for assignment inside condition statements

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.

  1. Allow for chained assignement

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? >.>

@bojidar-bg
Copy link
Contributor

You should try to search for existing issues first: #7222, #7584

@KoBeWi
Copy link
Member Author

KoBeWi commented Jul 31, 2018

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).

@LikeLakers2
Copy link
Contributor

Having used Ruby myself, I can see where the convenience of these ideas could come in. Here's my take on these ideas:

Different precedence for and/or/not and &&/||/!

Yes. Yes. Yes. If they're going to allow both, people are probably going to use one or the other, not both in combination.

Treat 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?

Allow for assignment inside condition statements

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".

Allow for chained assignment

I have no comment on this.

@KoBeWi
Copy link
Member Author

KoBeWi commented Jul 31, 2018

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.

@LikeLakers2
Copy link
Contributor

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

@KoBeWi
Copy link
Member Author

KoBeWi commented Jul 31, 2018

Wow, that warning system seems perfectly suited for this case D:

@vnen
Copy link
Member

vnen commented Jul 31, 2018

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.

@KoBeWi
Copy link
Member Author

KoBeWi commented Jul 31, 2018

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.

@LikeLakers2
Copy link
Contributor

(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.

@BBric
Copy link

BBric commented Jul 31, 2018

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.

@OvermindDL1
Copy link

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.

@aaronfranke
Copy link
Member

aaronfranke commented Feb 26, 2019

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 as true?

@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.

@Calinou
Copy link
Member

Calinou commented Feb 26, 2019

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).

@OvermindDL1
Copy link

How many languages treat 0 as true?

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...

@KoBeWi
Copy link
Member Author

KoBeWi commented Feb 26, 2019

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.

@Calinou
Copy link
Member

Calinou commented Feb 26, 2019

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 🙂

@vnen
Copy link
Member

vnen commented Feb 27, 2019

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 as true?

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.

@OvermindDL1
Copy link

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.

@MarcusElg
Copy link
Contributor

MarcusElg commented Apr 17, 2020

  1. Just use brackets :P changing this behaviour makes it less logical and more confusing imo
  2. A bool is kinda the same thing as 0 or 1 so having 0 as true makes no sence, 1 should be true and 0 false.
  3. Maybe
  4. Yes! Would be useful and I don't see any downside with it

@Calinou
Copy link
Member

Calinou commented Apr 17, 2020

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 🙂

@KoBeWi
Copy link
Member Author

KoBeWi commented May 25, 2020

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.

@Calinou
Copy link
Member

Calinou commented May 25, 2020

@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.

@KoBeWi
Copy link
Member Author

KoBeWi commented May 25, 2020

I know. That's why I wanted to propose repurposing them instead.

@MarcusElg
Copy link
Contributor

@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.

@Calinou
Copy link
Member

Calinou commented May 26, 2020

@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 🙂

Ruby has && and || with higher precedence than and/or, but it's easy for that feature to become confusing, especially for beginners.

@KoBeWi
Copy link
Member Author

KoBeWi commented May 27, 2020

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 .-.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants