-
-
Notifications
You must be signed in to change notification settings - Fork 97
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 extendable collections to GDScript #8029
Comments
There are two proposals in one here, but I'd like to address the first one. I think that generics would be a wonderful addition to GDScript, mainly in the spirit of making collections more recursive. Currently nested typed collections are not supported. If generics are implemented, I would want to also rectify this issue. As for the syntax of generics, I propose the angle bracket syntax similar to C# # my_list.gd
class_name MyList<T>
func append(item: T) -> void:
# implementation...
# other_class.gd
class_name OtherClass
var list: MyList<int> = MyList<int>.new()
func add_item(element: int):
list.add(element) I also think that typed arrays (regardless of whether they eventually support nesting) should have the generic syntax optional to them (we would keep the [] syntax to avoid breaking compatibility) var typed_array1: Array<int> = [5, 3, 2] # Valid
var typed_array2: Array[int] = [2, 3, 5] # Also valid
|
Currently, nested array types are not supported at the core level. This would be much easier to implement if we supported first class types (a type that represents a type), but these are too big core changes, I doubt that this will be feasible in the near future. |
I'm not sure how nested typed collections are relevant here? But yes, a solution that incorporated them would probably be preferable if possible... |
They're only relevant if you'd like to extend typed arrays. Currently, typed collections are not "generics" per se, rather each base type an array could have is explicitly implemented, including TypedArray |
So what would be stopping one from making a class that extends TypedArray? 😕 As I see it, extendable collections are basically just syntactic sugar, a less verbose form of something like this:
This could be simplified down, purely on the syntactic level, to:
Likewise, accessing it could be simplified from It's a stupid and entirely meaningless example, but I think it gets the point across. |
Typed arrays are not syntactic sugar. They check the type when adding an element at runtime. The current implementation does not support nested types. We could hardcode the nesting level for types like |
No, not typed arrays, extended arrays. I agree, typed arrays are a whole other can of worms, but the proposal doesn't really change the way typed collections work, it just adds a simplified method of attaching a wrapper around a collection. Likewise, I don't think it's particularly critical that parameterized classes (i.e. generics) retain their type information at runtime. Both aspects of my proposal center exclusively around developer QoL, teaching the GDScript interpreter about constructs that can already be expressed in GDScript, but require outsized quantities of fragile code to express. |
GDScript combines both dynamic and static typing. The user can not only choose one of the options, but use both at the same time, combining typed and untyped code. So we need to balance between these two aspects. Also GDScript relies heavily on the Godot core type system, it is not an independent language with type erasure like TypeScript. In my opinion, adding "ephemeral" types like |
I need to get into the habit of writing these things elsewhere, where I can periodically hit Ctrl-S. Bloody machine blew up on me the first time I was writing a reply... Summarized, then, because writing code examples in GitHub is a pain in the neck: I don't care about What I am proposing is no more, and no less, than these two pieces of functionality:
Both of these things are already entirely possible in GDScript, but require unnecessarily bloated and potentially fragile script constructs to achieve. In my previous comment, I demonstrated how you could achieve almost the same effect as an extended collection type, with probably the biggest difference being that there's no way in current GDScript for a typed variable to be typed as being one of several possible types, so statically typed APIs written for 4.2 would need to choose between using an Array and using an ArrayWithMetadata. (Well, also the fact that you can't define operators for custom types, so bracket syntax would not work for ArrayWithMetadata.) Meanwhile, my idea for generics? Literally lifting the Java rules would be perfectly adequate in my book, no matter what kind of syntax you settled on. Use |
In regards of "The possibility to define parameterized (i.e. generic) types, and have their type parameters respected by the static analyzer and the inspector", I added a possible work around here: Is not as convenient as "True generics" (Java/Kotlin/C#), but it'll get the job done until they are added to GdScript. |
I'm not sure how I overlooked the above comment for so long, but reading it has made me realize half of my proposal is just duplicating #1207. Updated accordingly. |
Describe the project you are working on
A 2D tactical game with an overcomplicated data model, because I wanted to be able to do too many things in the singleplayer campaign. 😬
Describe the problem or limitation you are having in your project
We've had typed arrays for... what, almost a year now? By this time next year, chances are we'll also have typed dictionaries via #56, and if #782 were implemented, that would seem to add optional strong typing to every collection or collection-like object in GDScript. And if we get #6416, who could stop us? 😂
Yet, the type system still feels a little immature compared to other languages offering typed collections:
Classes and methods must be written as either fully typeless, or be tightly bound to a specific class (or trait, as the case may become).(Duplicate of Add generic parameters to allow strongly typing for collections #1207, I only figured it out just now while reading @AlbertoRota's comment.)Describe the feature / enhancement and how it helps to overcome the problem or limitation
Overriding the inner logic of a collection allows you to optimize them for a specific purpose, or ensure that a certain process is absolutely always followed when performing certain operations on that collection. For instance, an
Array
whose values need to always be sorted could have theinsert()
,push_back()
, andpush_front()
methods callsort()
every time, instead of requiring the caller to remember to do it every time they're adding values to the array.Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams
This is probably purely syntactic sugar: Collections are probably too different from objects to be extended, and providing core support for their extension would come at a performance cost. However, an object "extending" a collection could offer transparent access to that collection and its functions, much like an object extending another object offers transparent access to the original object's properties and functions. (With, of course, the same ability to override those functions. Overriding the collection itself might be... heh, tricky, not to mention redundant.)
An example
SortedArray
class:If this enhancement will not be used often, can it be worked around with a few lines of script?
Sort of, and I almost already do it at one point. (Not quite, because my script does something slightly more complicated requiring two arrays and some other stuff... but almost!) You can write a class that owns a collection, and you can either have consumers access the collection directly, or expose wrappers for all its functions (but not its operators, because we can't define custom operators - material for another proposal, perhaps? 🤔) if you so desire.
It's needlessly clunky and verbose, and there's a perpetual risk that someone will fail to use your wrappers properly in favor of directly accessing the wrapped collection.
Is there a reason why this should be core and not an add-on in the asset library?
It is fundamentally an expansion of GDScript's syntax. I don't think it can be done by addons.
The text was updated successfully, but these errors were encountered: