-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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
Typed GDScript #19264
Typed GDScript #19264
Conversation
Fantastic addition! Thank you very much for working on this! |
Some weird stuff when using extends Node2D
var my_int : int = 10
signal my_signal(param1, param2)
func _ready() -> void:
var p1 : int = 0
var p2 : int = 1
emit_signal("my_signal", p1, p2)
|
@Xrayez seems I missed a check for varargs. Thanks for pointing it out. |
I really want to like this because it seems like a lot of work but I don't think this is a good addition to gdscript. It will add more segmentation, a harder entry barrier and distance itself further more from Python. Imagine the confusion of new comers when they start watching tutorials of people who prefer typed and others that don't. Maybe it would be a good idea to separate this with a different extension? something like .gdt not sure. Maybe I'm just too much into Python. |
Considering it is both backwards compatible and it follow Python's Typed Syntax spec, how would it segment or distanct itself further from python? Typing code is not a hard thing (though I would prefer if it were enforced, preferably with ML unification abilities ala OCaml or so would fit perfectly, hmm, maybe I should make an OCaml'ish native language interface...). |
@coppolaemilio Python has the same syntax for optional typing, if anything this will bring GDScript closer to Python. I don't think there should be that much confusion. Newcomers will probably just ask about it and learn while doing so. Since this is optional, both kind of tutorials and can even be mixed without (much) problem. There's a problem of mixing type hints and duck-typing, which may bring errors, but I still think people will just ask and learn. It doesn't sound like a big of a deal to me. Also, I'm not sure if we should nuke a wanted feature because of potential newcomer confusion. There's a lot of positive reactions not only to this PR but also to the related issue and my posts on Twitter. We know those people like this feature, should we not add it because the confusion it might cause (which we don't know)? If this were to be made into a separate file type then it would be better to make a new language altogether. But that would be a great effort in itself and really increase the fragmentation. Of course, I have a bit of passion for a feature I wrote myself, but I'm still open to feedback. If for the greater good this is decided to be a bad thing I won't push it further. |
For note, Python Typing: https://www.python.org/dev/peps/pep-0484/ ╰─➤ python3 -i
Python 3.5.2 (default, Nov 23 2017, 16:37:01)
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> def greeting(name: str) -> str:
... return 'Hello ' + name
...
>>> greeting("world")
'Hello world'
>>> |
Sorry guys, my bad! I wasn't aware that it was already implemented in Python. |
b02ae2f
to
dabba99
Compare
Solved the issue with vararg functions. Hopefully fixed compilation/style issues as well. |
The last build issue seems to be on Android, is there a missing
|
modules/gdscript/gdscript_editor.cpp
Outdated
@@ -54,16 +54,17 @@ void GDScriptLanguage::get_string_delimiters(List<String> *p_delimiters) const { | |||
} | |||
Ref<Script> GDScriptLanguage::get_template(const String &p_class_name, const String &p_base_class_name) const { | |||
|
|||
bool th = EDITOR_DEF("text_editor/completion/add_type_hints", true); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Android build fails here, but I guess the whole file should be in #ifdef TOOLS_ENABLED
, and not just a handful of duplicate includes as done currently?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This really needs I cleanup, but since I intend to refactor the completion code anyway, I'll fix it then.
@vnen This is crash sample project at starting editor. |
I think there is a design problem here. This is what you would expect in an statically type language. You get an instance up-casted to a base type. If you want to use the methods from the derived type, you have to down-cast it first. This is common in C#: var sprite = GetNode("/root/Sprite") as Sprite;
sprite.Centered = true; This would be totally fine if the new GDScript were to be only statically typed. The problem is the intention is to be backwards compatible with dynamically typed GDScript. The above is unacceptable. This means Did you remove the need for the cast only from |
@neikeq I'm still not entirely sure about that. Full static typing means that you can't do something simple like: $AnimationPlay.play("animation") This would give an error because Node does not have a ($AnimationPlayer as AnimationPlayer).play("animation") I have a feeling that most of the time this would be cumbersome, especially if you are used to GDScript already. Maybe it's better if I remove this exceptional case and if people complain during usage I really change it.
Only for
That's the catch: should type hints imply that GDScript is fully statically typed or should just be a convenience when assigned? The former sounds more sane but latter is more backwards compatible (and makes types truly optional). The thing is that if you add a type hint your code is subject to static checks, which might raise a parse-time error somewhere even if the code worked flawlessly with dynamic typing. If that's what we want, I'm fine with it. |
My two cents is, that static type checks would be more fitting for GDscript with parse time errors only. Maybe we could use some of the type guessing from the autocomplete, to handle specific cases, like get_node, better. |
Also, I do not even see a reason to downcast any Node on the tree, that should stay dynamic. |
O think if you want your script to be typed u would probably use onready vars which are of the correct type. |
dabba99
to
fafead8
Compare
@volzhs thanks for the repro, I fixed the issue. |
fafead8
to
2012252
Compare
const INDEX = ["index1", "index2", "index3"]
var dic = {}
func _ready():
dic["index1"] = 1 # fine
dic[INDEX[0]] = 1 # Parse Error: Only strings can be used as index in the base type 'Array'.
|
@volzhs oops, that was my mistake in a later change. Will fix right away. |
2012252
to
f2ee361
Compare
@vnen If type checks are only removed from
I think we could mark a script as |
Probably we can have Typed GDScript by default and then have a keyword to disable it. |
The line number is hightlighted to indicate that the line contains only type-safe code.
Syntax: var x : = 42 Infers the type of "x" to be an integer.
- Use data type struct from the parser. - Avail from type hints when type can't be guessed. - Consider inner classes and other scripts when looking for candidates.
29ac0b0
to
3e87ad5
Compare
Fixed some issues in release builds. Should be good to merge. |
Alright, this seems pretty ripe for merging and wider testing in the master branch! Note: Regressions are fully possible at this stage, even though @vnen and @chanon did a great job testing the PR and fixing many issues. Please report any issue you stumble upon, and give @vnen a few days to have a look at fixing them :) If you're adventurous and use dev builds in "production", you may want to stick to 2b9902d for a bit while we're ironing out the main issues (if any). |
@vnen Just a quick question, is there a way to set the type in a |
No, it's not possible in the current state. |
As /u/Cheekydood asked on Reddit, does this allow overloading of functions with different typed args? |
@aaronfranke no, that is not possible to do in a performant way, considering typing is optional. |
Running a project on Android with Godot, 1 commit before this PR, works fine. After compiling master and testing on Android, I get this error:
gdscript_parser.cpp:6527 _set_error("Too many arguments for '" + callee_name + "()' call. Expected at most " + itos(arg_types.size()) + " but called with " + itos(arg_count) + ".", p_call->line); // Added arg_count to help debugging BTW it is working fine in Windows and Linux. |
@jahd2602 Please open a separate bug report, it's hard to keep track of issues in a merged PR. |
@akien-mga I just found the issue: #20346 |
i tried 3.1 and this typed gdscript feels very similar to a statically typed and very strict language. for example, getting errors because i forgot to use a variable in a block. which was not intended at all it was just leftover code ( i'm also getting a lot of red warnings for really weird stuff that wasn't prevalent in 3.0.6, this makes the developer feel less and less confident). this is not the gdscript i fell in love with because it was more layed back (less intrusive), and made the developer feel more free. now, it seems like there is a "strict" guideline we have to follow. in my honest opinion, I think it's striving away from the simplicity and ease of use that the original gdscript offered. with regards to the slim arrows ( i'm also using crystal and it feels even less intrusive (and that is a statically typed language!) tbh. editt: sometimes i do wonder why this came to fruition because previously i've really never had a problem with gds. but when i try out 3.1, it's like errors are just everywhere. what was so bad with the previous gds? i mean, it was working just great for me lol |
@aaronfranke i see. ty, i guess i thought this was intertwined / related to warnings since it checks gds. that's the positive of gds. it gives the developer ease of mind, you don't need to write c++ strict standard code, you can code freely. something has happened from 3.0.6 to 3.1 i think where i feel like it's mandatory to write "strict code". hard to explain |
@girng you can disable warnings in the project settings if you want. I'm closing this thread because bugs and suggestions about Typed GDScript should be made in a new clean issue. This thread is already too long. |
Alright, big change coming! Let me add a bit of documentation in here.
FAQ
Things people asked me during the development.
Yes. You can use GDScript dynamically as it is now. Type hints can be used only in parts of the code.
It shouldn't. If it does then it's a bug. Whenever a type check is possible it will make one, but this won't affect duck-typing. Lines that are fully type-checked are indicated by a highlight in the line number. However, GDScript was very lenient about some behaviors that can be considered an error, so your script might break if it relied on those behaviors.
As it is now: no. However, this enables the possibility of future improvements in performance. A set of benchmarks are needed before we go this path.
No, this was discussed at length before. The syntax is similar to Python. It's made to be easy to parse without changing the GDScript syntax in itself, considering the types are optional.
Syntax
var my_int : int
var my_int : int = 42
var my_int : = 42
const my_const : String = "Something"
func (arg1 : int, arg2 : String = "") -> float:
event as InputEventKey
null
if the cast is not possible.Possible types
int
,float
,Vector2
,Basis
, etc.).class_name
keyword. Includes their inner classes too.class
statement).Static checks
As long as there any type can be fully determined, the parser will try to detect mismatches. This will be shown as an error in the editor.
int
andString
).2 * 2
is anint
, but2 * 2.0
is afloat
).Note that since this is meant to be fully optional and still compatible with duck-typing, it won't mark as an error if the member variable/method could be available in a subtype. Instead, type-safe lines will be marked with a subtle green tint in the number line. Non-safe lines will just not be marked:
Completion
The code completion was rewritten to make use of the type hints, and also fixed many long-standing bugs. The code is now somewhat cleaner and easier to add new features. Some improvements:
Wanted feedback
Any feedback is welcome but there's some things in particular that I want to know. In any case it's great to have sample scripts for me to test.
Future
Before anyone asks, here's a bit of ideas for the future.
emit_signal
andconnect
calls.var int_array : int[]
as an array of integers).Closes #10630.