godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.26k stars 101 forks source link

Add a `@static` annotation to GDScript #12639

Open uintsareawesome opened 2 weeks ago

uintsareawesome commented 2 weeks ago

Describe the project you are working on

n/a

Describe the problem or limitation you are having in your project

The introduction of the abstract keyword in 4.5, and the intention of the GDScript team to change it to an @abstract annotation, as per https://godotengine.org/article/dev-snapshot-godot-4-5-beta-1/#gdscript creates an inconsistency in the way GDScript is currently written.

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

See: https://www.reddit.com/r/godot/comments/1lew9zn/comment/myl0yxx/

Given that the static keyword would be an annotation if added today, and since removing it would break compatibility, an @static annotation should be added alongside it and be the recommended style for GDScript until the keyword will be removed.

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

@static var collector: int = 0

@static func collect(amount: int) -> void:
    collector += amount
@static 
var collector: int = 0

@static 
func collect(amount: int) -> void:
    collector += amount

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

This can be worked around by modifying the engine source code and compiling your own custom version, but it is not particularly convenient.

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

It allows GDScript users to align with the vision for the future of the language whilst minimizing the suffering of people with varying levels of OCD.

AThousandShips commented 2 weeks ago

Did you mean to make the examples show @static?

Meorge commented 2 weeks ago

This has been discussed quite a bit in the GDScript contributor channel and meetings the past couple of weeks. I'm personally a bit split on the @static annotation specifically.

For things like @private and @protected, as I understand, the function itself remains identical. All that the annotations would do is cause a warning or error to be raised if the user attempts to call the function from a different class.

Meanwhile, static changes the function's behavior more fundamentally - it doesn't belong to a specific instance of the class anymore, doesn't have the same meaning for self, etc. Because of this fundamental change to the function's execution, I'm feeling a bit more on the side of keeping static as a keyword.

AThousandShips commented 2 weeks ago

I think there's no reason to add a separate annotation as a parallel way to do the same thing, transitioning to Godot 5/GDScript 3.0 (we're not going to remove static in any 4.x version) is going to be a major disruption anyway so I don't see how @static instead of static will help in any real way to make that any smoother, you'd be largely able to just replace the past use of the keyword for the annotation with relatively little focus, if it would even be reasonable to expect much migration between these versions at all, especially if we want major improvements in the next iteration

On the flip side adding a duplicate annotation makes for a lot of extra details, it makes error messages more confusing (should they mention both, or only one?), makes documentation more cumbersome

But worst of all: It breaks forward compatibility for templates etc. as we'd necessarily deprecate static if this is going to be of any value. If we are to introduce a new syntax as an alternative, to make a future (far in the future, at least several years) transition easier, we should realistically prefer that new syntax being used

But now code written after this new annotation is added is not backwards compatible and can't be used in older versions, so anyone making plugins etc. that supports multiple versions have to use the keyword

tl;dr; This is "future proofing" for something that's several years at least in the future, if ever, and makes working with multiple versions impossible while also providing forward compatibility for this future change. And few users are going to take any code written with these versions and use it in Godot 5 anyway