godotengine / godot-proposals

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

Statically typed Callable #10807

Open sockeye-d opened 2 months ago

sockeye-d commented 2 months ago

Describe the project you are working on

Any project that uses lambda functions heavily

Describe the problem or limitation you are having in your project

Callables have no defined type of parameter list

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

Add a type field to Callable, similar to Array and Dictionary

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

When defining a Callable, you can add as many type parameters as you want. These would all be valid:

# returns int
Callable[int]
# returns String, takes a float and an untyped parameter
Callable[String, float, Variant]
# returns void, takes String
Callable[void, String]
# or maybe this should be
Callable[null, String]

Lambda functions will not need type hints if types are declared in the variable or parameter, making them more concise but still type safe:

func my_method(callable: Callable[String, Node]) -> void:
    pass

# there would be code completion here, and it would give an error if it didn't return anything
my_method(func(node): return node.name)

Since actual class and method generics aren't supported (the way it's implemented in other languages), things like Array methods (map, reduce, filter) still won't work correctly.

Callable would also have methods for getting the types, like Array does:

c.get_typed_builtin(index)
c.get_typed_class_name(index)
c.get_typed_script(index)

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

It requires casting, which I think is undesirable

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

GDScript is core

Mickeon commented 2 months ago

This is related to

The team on GDScript occasionally talks about this kind of thing, but it can't come any time soon due to severe changes being required to the typing system and the GDScript parser, first.

dalexeev commented 2 months ago

I think we should think about the unified type system as a whole, not just Callable.

See also:

sockeye-d commented 1 month ago

Yes, I agree the implementation of "generics" as we have them seem to be a hack. I hope that the generics get a more unified system that makes it trivial to create generic classes, methods, and variables though, it would make life a lot simpler in these kinds of scenarios.

duckbanditdan commented 5 days ago

I would also like to see broader support for static typing. Specific to this proposal though, typed Callable's could be used to allow signals to be connected in a type safe manner (assuming that signals were adapted to leverage them). This would go some way to solving #2557 as well (it would not solve the emitting of signals). Since the documentation strongly encourages the use of signals, I think this is an important use case.

edit: corrected link to wrong proposal