godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Resolve inconsistent dictionary declaration syntax #1664

Closed CitrusWire closed 3 years ago

CitrusWire commented 4 years ago

Describe the project you are working on: n/a

Describe the problem or limitation you are having in your project: Godot has two ways of declaring dictionaries. The problem is, they're mutually incompatible and provide extra scope for confusion and bug creation.

Consider the follow script:

extends Sprite

var dict1 = {
    key1: 1,
    key2: 1
}

var dict2 = {
    key1= 1,
    key2= 1
}

Dict1 will cause an exception because key1 is referencing an undeclared variable. Whereas dict2 treats key1 as a string key and will work fine.

Inconsistency is one of the worst possible things you can have in a programming language (see also: PHP).

This isn't hypothetical either, it just bit me on my first time using them! (Partly due to docs issues, but they'll go in the appropriate tracker), and I can all but guarantee it'll get me again.

Describe the feature / enhancement and how it helps to overcome the problem or limitation:

I don't have any preference for how to solve this, but I'd suggest one of the following: a) get rid of one of the methods of declaring dicts b) Ensure both methods treat unquoted strings the same way

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams: Both of the code snippets provided above should work the exact same way.

If this enhancement will not be used often, can it be worked around with a few lines of script?: n/a

Is there a reason why this should be core and not an add-on in the asset library?: Fundamental GDScript language issue

jonbonazza commented 4 years ago

This is by design. As you mentioned, they are two separate syntaxes and are going to work differently by nature. The first is python-like. Anyone familiar with python expects it to work this way. The second is lua-like. Anyone familiar with lua expects it to work this way. If you arent familiar with either, then it shouldn't matter. Just pick one and learn how it works.

You shouldn't be mixing and matching them in your code base. Whichever one you choose should be a part of your project's style and convention guidelines.

Calinou commented 4 years ago

The only outcome I see to this proposal (other than doing nothing) would be to remove the Lua-style syntax. However, this would make writing one-off arrays much less convenient, especially for String.format() and similar. Therefore, I'm against it. I'm aware Python doesn't have a simplified syntax for dictionaries, but I sometimes wish it had :stuck_out_tongue:

We can't remove the Python-style syntax as it's the only syntax that accepts non-string values (and variables) as keys. While we could accept a JavaScript-like syntax for variables as dictionary keys ({[hello]: "world"} where hello is a variable), it's quite obscure and not very discoverable for beginners.

Personally, I use the Lua-style dictionary syntax unless I can't use them for some reason.

me2beats commented 4 years ago

lua style is just a kind of syntactic sugar imo. however, the python style is more versatile because: 1) you cannot use variables as dictionary keys using lua style with py you can:

var x = 'hello'
var d = {x:1}

2) you cannot use non-string types as keys using the lua style. with py you can:

var d = {1:1}
print(d.keys()[0] is int)
---> true

Calinou beat me

CitrusWire commented 4 years ago

However, this would make writing one-off arrays much less convenient, especially for String.format() and similar.

The question becomes: which is more important, consistency, or syntactic sugar? To me the answer is obvious, consistency. If making it more consistent removes sugar and that sugar is important, I see no reason not to add a new mechanism to make using String.format() more convenient while not introducing inconsistencies.

You shouldn't be mixing and matching them in your code base. Whichever one you choose should be a part of your project's style and convention guidelines.

In principle, I agree with you, however the realities are: a) It's going to confuse some people who are new to godot. b) People occasionally make mistakes/typoes etc. This inconsistent style facilitates that, rather than inhibits. c) Most amateur, and many pro projects won't have style guides. d) Documentation examples/tutorials/Stack exchanges etc all using different styles is only going to further confuse things.

And those aren't hypotheticals. (a) already happened to me. (b) If you find a programmer who tells you they never make mistakes, run far far away. (d) Godots own docs confuse the matter (issue opened).

For an analogy, consider the words there, their, they're or your, you're or any other grammatical homophone. Even among native English speakers it's common for people to use the wrong one, and that's with decades of practice and formal education telling them how to use them correctly. Much as we may not like to admit it, Human brains are lazy and error prone. A good system works to reduce the chance that such errors can happen in the first place.

KoBeWi commented 4 years ago

a) It's going to confuse some people who are new to godot.

When you are new, lots of things can confuse you. That's because you don't know them and just need to learn. When you know that there are two ways to create dictionaries and what is the difference between them, then it's not a problem anymore.

b) People occasionally make mistakes/typoes etc. This inconsistent style facilitates that, rather than inhibits.

No idea how is this relevant.

c) Most amateur, and many pro projects won't have style guides.

Not a problem either. Not mixing styles is just a recommendation. Personally I use LUA style and Python style when I need non-string keys. It's not like it's going to break your code or something.

d) Documentation examples/tutorials/Stack exchanges etc all using different styles is only going to further confuse things.

Same as a)

IMO what we should do is improve documentation. Dictionary class ref should mention that there's a second way to define dictionary and tell what's the difference. Also the biggest mistake you can make with LUA syntax is unintentionally shadowing a variable by doing {some_variable = "some_value"}. We could add a warning for this case. That would solve all the problems.

CitrusWire commented 4 years ago

a) It's going to confuse some people who are new to godot.

When you are new, lots of things can confuse you. That's because you don't know them and just need to learn.

Indeed, but that does not excuse making the learning curve steeper than it needs to be, or including random gotchas.

When you know that there are two ways to create dictionaries and what is the difference between them, then it's not a problem anymore.

No, because if you never use the second method you'll probably end up forgetting about it, then you copy/paste something from the internet to solve and problem and bam, new bug. Bonus: I know enough languages I often forget random bits of syntax for them after I've not used it for a while, including basic things like dictionary syntax.

b) People occasionally make mistakes/typoes etc. This inconsistent style facilitates that, rather than inhibits.

No idea how is this relevant.

Example:

extends Node

var health = 5

var player_stats = {
    health: health
}

Ignoring the obviously poor variable names, a one character typo completely changes how this script behaves. What it /should/ do is raise an exception.

I've lost count of the number of times I've spent hours trying to find what turned out to be a single-character typo that compiled but did something insidious. Maybe you're all amazing coders who never make those sorts of mistakes, but most coders /do/ make those sorts of mistakes, and so good language design takes that into account. Sure, the compiler can't know that I meant < rather than >, or + not -, but what the compiler/language /can/ do is not introduce new scenarios where that sort of bug can happen.

c) Most amateur, and many pro projects won't have style guides.

Not a problem either.

I'm not saying it's a problem. jonbonazza said that style guides solve the problem of mixing types, I was pointing out they often don't exist and therefore do not solve the problem.

d) Documentation examples/tutorials/Stack exchanges etc all using different styles is only going to further confuse things.

Same as a)

As is my response.

Also the biggest mistake you can make with LUA syntax is unintentionally shadowing a variable by doing {some_variable = "some_value"}.

Which is exactly my point. It's also the worst class of bug because it's invisible and insidious. The sort that take the longest to find.

me2beats commented 3 years ago

Will the "lua-style" syntax be removed in Godot4 ?

Calinou commented 3 years ago

Will the "lua-style" syntax be removed in Godot4 ?

As far as I know, there are no plans to remove the Lua-style dictionary syntax in 4.0.

Calinou commented 3 years ago

Closing due to lack of support (see the above comments and reactions on OP).