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 type hints for array members #192

Closed
SeleDreams opened this issue Oct 30, 2019 · 18 comments
Closed

Add static type hints for array members #192

SeleDreams opened this issue Oct 30, 2019 · 18 comments
Milestone

Comments

@SeleDreams
Copy link

Describe the project you are working on:
I am working on a Pokemon inspired RPG where the player would be a "manager" and would have battle moves and stats based on the objects they own

Describe the problem or limitation you are having in your project:
I guess it isn't a "problem" but I thought of something while implementing the party system.
While implementing the party system, I've made an array that would contain multiple instances of a specific class I made (BattleCharacter), however, while I always use static typing, it seems to be impossible to determine in advance the type all array members would have.

Which I am used to coming from a C# background, I also feel like it would allow a lot of optimizations in case of iterations through array members

Show a mock up screenshots/video or a flow diagram explaining how your proposal will work:
My proposal would be to allow something like
var array_name : type = []
or
var array_name = [] : type
it would then only allow to set values of the array to values of the specified type

Describe implementation detail for your proposal (in code), if possible:
As I only started using Godot recently, I unfortunately don't know enough the way the engine handles internally GDScript.

If this enhancement will not be used often, can it be worked around with a few lines of script?:
Well, yeah since it can be done without static typing, it's mostly a feature improving on the static typing added to 3.0

Is there a reason why this should be core and not an add-on in the asset library?:
It would allow big performance optimizations in games relying heavily on arrays and iterations.

@hilfazer
Copy link

And for Dictionary members.

@Calinou
Copy link
Member

Calinou commented Oct 30, 2019

It would allow big performance optimizations in games relying heavily on arrays and iterations.

This will require GDScript to support typed instructions first. Otherwise, the typing will just be used to improve autocompletion, type safety and documentation.

@SeleDreams
Copy link
Author

I see.
Yeah, I knew typed variables didn't have effects on performances yet because typed instructions haven't been implemented, but in the long run it could allow performance improvements when it would be added

It would also still help for what you said at the end of your message which is a good advantage as well

@willnationsdev
Copy link
Contributor

Other syntax ideas?

var char_list: [BattleCharacter] = []
var char_set: { BattleCharacter: null } = {}
var char_dict: {int: BattleCharacter} = {}

@LikeLakers2
Copy link

LikeLakers2 commented Nov 9, 2019

I've always been a fan of how Ruby YARD documentation handles Arrays and Dictionaries (called "Hashes" in Ruby, but I'll be calling them Dictionaries for simplicity). Perhaps we could use that syntax?

For reference, Arrays are usually handled like Array<SomeOtherClass> in YARD docs. If you need to go deeper with Arrays, you might do something like Array<Array<SomeOtherClass>>. And if you wanted to document that a array could have multiple objects, you might do Array<SomeClass, SomeSecondClass, SomeThirdClass>.

As for Dictionaries, YARD documentation would usually look something like Dictionary<String => SomeClass>, although I'll admit that the => is a ruby thing -- perhaps we can use -> here?

And the two can be put within each other: Dictionary<String => Array<BattleCharacter>>. In GDScript, this would probably end up typed out as var units_by_team_name : Dictionary<String -> Array<BattleCharacter>>.

I don't know how hard it would be to implement this sort of syntax, but that's my suggestion for handling static typing for arrays and dictionaries.

@Calinou Calinou changed the title Static typing for array members Add static type hints for array members Sep 6, 2020
@Two-Tone
Copy link

This will require GDScript to support typed instructions first. Otherwise, the typing will just be used to improve autocompletion, type safety and documentation.

Once godotengine/godot/pull/43004 gets merged hopefully work on this can be started.

@vnen
Copy link
Member

vnen commented Oct 23, 2020

Once godotengine/godot/pull/43004 gets merged hopefully work on this can be started.

I definitely want to make this for Godot 4.0. It still will take sometime since I have other tasks.

@Calinou Calinou added this to the 4.0 milestone Oct 23, 2020
@kintrix007
Copy link

kintrix007 commented Oct 27, 2020

I've been thinking about this just recently and then stumbled upon this issue.

First I was thinking like C++ syntax for this, but var int_arr : Array<int> = [0, 1, 2, 3, 4, 5] wouldn't really suit GDScript. Especially because of the < > syntax that would only appear here.

I really like @willnationsdev 's idea, and I think that would be the best, and it still looks like GDScript.

@dgellow
Copy link

dgellow commented Oct 27, 2020

Go has var arr: []int for slices, Typescript has let arr: int[] for arrays. Both would look quite natural in GDscript IMHO.

@willnationsdev
Copy link
Contributor

@dgellow Yeah, I often like that syntax actually (C-like too). But how would you do Dictionaries then?

@dgellow
Copy link

dgellow commented Oct 29, 2020

For dictionaries, two options that build on my previous comment, and don't require additional characters (so shouldn't complicate the parsing rules too much, hopefully):

  • var dict: string[int], keys of type string, values of type int
  • var dict: [string]int, here too, keys of type string, values of type int

I find the second one a bit more clear, but I'm using Go quite a lot so that could be a bias.

@h4de5
Copy link

h4de5 commented Oct 29, 2020

I don't want to open a pandoras box, but have you looked more into typescript? specially the way they handle:

  • array typing
let a: number[]; // [1, 2, 3]
let b: string[]; // ["a", "b", "c"]
  • using tuples and array tuples
let t: [string, number, boolean][]; // [["a", 1, true],["b", 2, false]]
  • multiple distinct types for one variable (union type)
let foo: number | string | null;
  • as well as distinct values for one variable (literal type)
let bar: "up" | "left" | "right";
  • or use enums and interfaces for distinct values
const enum Directions {
  up = "KeyW",
  left = "KeyA",
  right = "KeyD"
}
let bar2: keyof Directions; // same as : "up" | "left" | "right";
  • define key and value types for dictionaries:
let bar3: { [key: string]: number }; // { "x": 4 }
  • re-using a type from a given varibale
let foo = { bar: 42 }
let bar: typeof foo;

again - I know, this is already drifting far from array typing, and I am not saying Godot should take over all those syntax options - but I just wanted to list some of them, as I don't see them covered so far.

@willnationsdev
Copy link
Contributor

@dgellow

var dict: string[int], keys of type string, values of type int

I also find this very pleasing to the eye. Although, I'm likely biased due to PHP like you are of the latter version for Go.

Either way, you think of the braces as wrapping the key ("what type is the key that goes in the square brackets?") or the value ("what type am I indexing to get?"), but both approaches work well imo. Between the two, I prefer the former because I like starting to type with actual type information rather than syntax characters. Makes it easier for me to just go with my train of thought. Need "X" which maps to "Y" vs. Need a "Map" of "X" to "Y". Slightly less cognitive load.

string[int] # starts with `s` from `string`. Yay, type info!
[string]int # starts with `[`, for syntax. Boo, I have to remember to know immediately to put that

@h4de5

let t: [string, number, boolean][]; // [["a", 1, true],["b", 2, false]]

let foo: number | string | null;

let bar: "up" | "left" | "right";

Supporting any of these would mean adding support for tuples and unions in the core Variant type which would likely be a lot more work. If you think adding these types provide a significant enough advantage to warrant integrating and maintaining them in the core, then you should open proposals for them.

As it stands, I think the struct proposal already kind of does this for tuples (#279), but there isn't anything yet for unions afaik.

let bar3: { [key: string]: number }; // { "x": 4 }

Besides the "starting with syntax characters" thing I mentioned before, I especially don't like the idea of needing to use key, in the type definition (regardless of whether it's arbitrary or a keyword). I don't think I should have to express a full key-value pair syntax just to indicate what the correct type information should be.

  • re-using a type from a given varibale

    let foo = { bar: 42 }
    let bar: typeof foo;

Really not sure about this one. Sounds more GDScript-like to formally declare the existence of a type alias (if support for that were added) and then allowing you to use that in type hints. There's already typeof() in GDScript, but it returns an enum value. And in order to fully understand the type of something, you'd need at least both the typeof() result and the get_class() result (or the script class name).


I'm good with structs eventually being supported, cause tuples are convenient and useful, but as for everything else, I'd just keep to the int[], string[int], etc. Although, type hinting tuples would be another thing altogether which can be discussed in the mentioned Issue if things ever progress that far. No need to waste time on it here.

@katoneko
Copy link

* `var dict: [string]int`, here too, keys of type `string`, values of type `int`

To me, this is the only right way because you index dicts and arrays with [], so by intuition key type is expected to stand between them followed by the value type.

@jendrikw
Copy link

I think Python's dict[string, int] would work well in GDScript.

@Shadowblitz16
Copy link

Shadowblitz16 commented Nov 23, 2020

so wait you guys would perfer..

class MyDict[key, value]:
var dict := MyDict[key, value]()

over?

class MyDict<key, value>:
var dict := MyDict<key, value>()

how would something like constraints work if they were added?

EDIT: TBH the first one looks better in python
EDIT2: so here are my thoughts on this..

I think that we shouldn't do it like so..
let bar3: { [key: string]: number }; // { "x": 4 }
its confusing

I personally think something like this should be done...

var array :  Array[int]    limits it
var array := Array[int]() assigns it
var dict :  Dictionary[String, MyObject]   limits it
var dict := Dictionary[String, MyObject]() assigns it

@chexmo
Copy link

chexmo commented Feb 14, 2021

Hi everyone.... I'm personally interested in this feature since I come from a Java background.
AFAIK, with ducktyping what a variable holds was inferred from the assignment

var number = 3
var array = ["Hello", "Bye"]
var dict = {"key": 3, "another key": 4}

Since the current typing (3.1+) gives us this syntax...

var number : int = 3

...the syntax for the type hints following the same guidelines (IMO) should be like this...

var array : Array[String] =  ["Hello", "Bye"]
var dict : Dictionary{String : int}= {"key": 3, "another key": 4}

And maybe, given the fact that dictionaries and arrays uses different symbols ({} and [] respectively), it could end up being something like this..

var array : [String] =  ["Hello", "Bye"]
var dict : {String : int}= {"key": 3, "another key": 4}

(Edit: Fixed a typo)

FIGBERT added a commit to FIGBERT/sevivon that referenced this issue Apr 8, 2021
Previously, code just assumed that the dictionary
conformed to the structure outlined in state.gd.
With the addition of the Player class, properties
can be typed and well defined.

Now, if only Godot had types for array members...
godotengine/godot-proposals#192
@Calinou
Copy link
Member

Calinou commented Jun 14, 2021

Typed GDScript arrays were implemented by godotengine/godot#46830, closing.

See #56 for dictionary type hints (which are not planned for 4.0, but may be added in a future release).

@Calinou Calinou closed this as completed Jun 14, 2021
FIGBERT added a commit to FIGBERT/sevivon that referenced this issue Jun 4, 2022
Previously, code just assumed that the dictionary
conformed to the structure outlined in state.gd.
With the addition of the Player class, properties
can be typed and well defined.

Now, if only Godot had types for array members...
godotengine/godot-proposals#192
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