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

Add static typing for loop variables in for loops #632

Closed
ttencate opened this issue Mar 25, 2020 · 21 comments · Fixed by godotengine/godot#80247
Closed

Add static typing for loop variables in for loops #632

ttencate opened this issue Mar 25, 2020 · 21 comments · Fixed by godotengine/godot#80247
Milestone

Comments

@ttencate
Copy link

ttencate commented Mar 25, 2020

Describe the project you are working on:

A Zachtronics style puzzle game, using static typing as much as possible.

Describe the problem or limitation you are having in your project:

My code does a lot of work with Arrays, which contain objects that are all the same type. This is extremely common with arrays in general; I've rarely seen use cases for arrays containing completely arbitrary types. There's almost always at least a common base type for all elements.

When looping over the Array with a for loop, the docs explicitly state that you can't specify a type. This is forbidden:

for name: String in names:
    ...

So inside the loop body, name will be untyped, even if we know we started out with an array of Strings. We'd prefer to fail with a clear error if that assumption is ever violated.

The reason, according to the docs, is:

You can’t force the assignment of types in a for loop, as each element the for keyword loops over already has a different type.

That's a nonsensical argument; in other places (e.g. simple variable assignments) it's entirely possible assign values of unknown types to variables that have a static type:

var foo = 0
var bar: String = foo  # Fine at compile time, error at runtime.

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

Allow syntax like the above:

for name: String in names:
    ...

It would check the type at runtime and throw the usual error if it doesn't match:

Trying to assign a value of type 'whatever' to a variable of type 'String'.

Within the body of the for loop, name would have the type String and provide autocompletion and other static type checks accordingly.

Describe how your proposal will work, with code, pseudocode, mockups, and/or diagrams:

I would hope that it's fairly straightforward to add this to GDScript, but I've never looked at that part of the codebase before so I might be wrong.

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

One workaround is to live with a dynamically typed loop variable, at the cost of losing autocompletion and type checking in the editor.

The other workaround is to use a helper variable and cast it explicitly:

for temp_name in names:
    var name := temp_name as String
    ...

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

It's a core GDScript feature, so it cannot be implemented externally.

@Deftwun
Copy link

Deftwun commented Apr 22, 2020

Godot noob & Just my 2 cents but this syntax would be awesome to get type hints inside for loops

for name in names as String:
    print(name)

I'd expect it to throw an error at runtime if types didn't match

@Calinou
Copy link
Member

Calinou commented Apr 22, 2020

@Deftwun That syntax doesn't seem as readable as for name: String in names. Also, as has different semantics from : type hinting in GDScript.

@ghost
Copy link

ghost commented Apr 22, 2020

I would also expect it to follow what it's doing currently.

for name : String in names:

@MatthewDLudwig
Copy link

Is there any progress on this proposal? Given that we can't use type hints with arrays (though the pooled arrays exist for some types) being able to specify what type we expect to be looping through would be helpful in terms of editor auto-suggestions.

@Calinou Calinou changed the title Static typing for loop variables in for loops Add static typing for loop variables in for loops Aug 15, 2020
@ScrewTSW
Copy link

What's the plan for this proposal?
It would be a really valuable Quality of life improvement

@katoneko
Copy link

4.0, AFAIK, will get typed arrays and dictionaries, so, bearing that in mind, is it necessary to specify the type of the loop variable when it can be inferred (at compile time!) from the container items' type? Not against this proposal though, just a thought.

@Calinou
Copy link
Member

Calinou commented Nov 22, 2020

@katoneko Typed (Variant) arrays are planned for 4.0, but I'm not sure if typed dictionaries will also be added in 4.0 as they are more difficult to implement.

@mounirtohami
Copy link

mounirtohami commented Jan 27, 2021

this works for me , it may help for type hints since var button := _button will print an error of unknown type

for _button in buttons:
    var button : Button = _button
    button.align = ALIGN_CENTER

@mleidl
Copy link

mleidl commented Jun 26, 2021

This will give you the code hinting at least, and it makes sure it's of that type:

for button in buttons:
    if button is Button:
        button.align = ALIGN_CENTER

@Calinou
Copy link
Member

Calinou commented Jun 26, 2021

This will give you the code hinting at least, and it makes sure it's of that type:

for button in buttons:
    if button is Button:
        button.align = ALIGN_CENTER

This fails silently at run-time if the type doesn't match, so beware. A safer alternative for debug builds is:

for button in buttons:
    assert(button is Button)
    button.align = ALIGN_CENTER

@PoisonousGame
Copy link

PoisonousGame commented Sep 1, 2021

Hope to implement soon! It might now be possible to write:

for button in buttons:
    button = button as Button
    button.align = ALIGN_CENTER

I don’t know which way is better?

@aXu-AP
Copy link

aXu-AP commented Nov 21, 2021

I just wanted to propose this exact thing with the same arguments, as well. I find myself from time to time trying to write for loops with static typing just to remember it cannot be done.
I think it would do a lot for consistency of gdscript and feel totally natural to use static typing in every place we can declare variables.

@Daylily-Zeleen
Copy link

@katoneko Typed (Variant) arrays are planned for 4.0, but I'm not sure if typed dictionaries will also be added in 4.0 as they are more difficult to implement.

I hope typed dictionaries can be implemnted in 4.0, I think it is as important as typed arrays. I can't find a proposal about typed dictionaries, but it is obviously that typed dictionaries can bring benifits which the same as typed arrays, and I think core developers have realized that. So I don't know whether a proposal should be submitted.

@raulsntos
Copy link
Member

@Daylily-Zeleen A proposal for typed dictionaries already exists: #56

@Daylily-Zeleen
Copy link

@Daylily-Zeleen A proposal for typed dictionaries already exists: #56

Thanks, hope it can be implements as soon as possible.

@Calinou
Copy link
Member

Calinou commented Feb 8, 2022

Thanks, hope it can be implements as soon as possible.

Typed dictionaries are not planned for 4.0 due to time constraints, but they may be implemented in a future 4.x release.

@nautmeg
Copy link

nautmeg commented Jun 15, 2022

Has anyone heard any news on typed for loops? Would like to see that implemented, although as some have said already it isn't difficult to add a new typed variable and assign the value of the for loop item to it... just seems a bit unnecessary. Also, I'm thinking when iterating larger objects, creating a new instance and assigning the looped item to it could be expensive... I can't say that's been an issue particularly for me as I wouldn't normally have a large set of large objects to loop through but it may be detrimental for some.

@oparisy
Copy link

oparisy commented Jun 15, 2022 via email

@4CoDev
Copy link

4CoDev commented Jun 18, 2022

Why specify a type for "name" if it has the same type as "names"?

@oparisy
Copy link

oparisy commented Jun 19, 2022 via email

@OffsetMOSFET
Copy link

OffsetMOSFET commented Aug 17, 2023

Hope to implement soon! It might now be possible to write:

for button in buttons:
    button = button as Button
    button.align = ALIGN_CENTER

I don’t know which way is better?

I'm able to infer the type without assignment (align should be recommended).

for button in buttons:
  button as Button
  button.align = ALIGN_CENTER

edit: this also works

for button in buttons:
  button is Button
  button.align = ALIGN_CENTER

@dalexeev dalexeev added this to the 4.2 milestone Aug 20, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.