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

Classes are not considered constants in GDScript #33531

Open
Zylann opened this issue Nov 10, 2019 · 11 comments
Open

Classes are not considered constants in GDScript #33531

Zylann opened this issue Nov 10, 2019 · 11 comments

Comments

@Zylann
Copy link
Contributor

Zylann commented Nov 10, 2019

Godot 3.2 alpha1

The following examples all produce an Expected a constant expression error:

class Test:
    var a

const test = Test
const test2 = [Test]
const test3 = {"test": Test}

I wanted to use a class in a constant, but it's not possible, while it is possible with scripts obtained with preload.

@ThakeeNathees
Copy link
Contributor

ThakeeNathees commented Mar 11, 2020

our const are compile time constants so when compiling the script the class Test is not a gd script instance (until the compilation ends), but the preload returns the gd script instance which was compiled before.

I think we have to make our const as runtime constants, or may be we could add a "subclass compiler" to the parser to compile the subclass after parsing the subclass to make a script instance.
or may be any other workaround ??

@vnen @bojidar-bg

@bojidar-bg
Copy link
Contributor

bojidar-bg commented Mar 11, 2020

This might be related to the usual reference cycle problem. Consider:

class X:
    func do_stuff():
        return Y[0].new()
const Y = [X]

@ThakeeNathees
Copy link
Contributor

ThakeeNathees commented Mar 12, 2020

yeah, still we can do this

class X:
    func do_stuff() -> X:
        return [X][0].new()

runtime constant resolve the reference cycle problem (but changing runtime const might break our old stuff).
how about introduce a new keyword like readonly for runtime const (like c#)??
@bojidar-bg

@Calinou
Copy link
Member

Calinou commented Mar 12, 2020

how about introduce a new keyword like readonly for runtime const (like c#)??

Support for immutable variables is being tracked in #23695.

@ThakeeNathees
Copy link
Contributor

ThakeeNathees commented Mar 12, 2020

@Calinou
But const are static to the script not var this issue need something to be static to the script value can be set at runtime (and may be immutable)

## script.gd
extends Node
const c = 3
var v = 3
extends Node2D
var script = preload("res://script.gd")
func _init():
    script.c ## valid
    script.v ## invalid
    script.new().v ## valid

@vnen
Copy link
Member

vnen commented Mar 12, 2020

Doesn't need to be runtime, we can tell which class it is at compilation time. We just need to make the parser know that this case can be considered constant. The compiler will already have a script reference to place there when needed.

But const are static to the script not var this issue need something to be static to the script value can be set at runtime (and may be immutable)

This can become quite complex, but it isn't need to solve this particular issue. If you think this can be useful in an specific case, you can open a proposal: godotengine/godot-proposals#573

@charliewhitfield
Copy link

charliewhitfield commented Apr 2, 2020

I'm not sure if this is the same or related issue...

If the class is defined in a separate file, then assignment to a const is allowed. HOWEVER, GDScript doesn't infer static type as it does with a var...

# math.gd

class_name Math

static func sum(a: float, b: float) -> float:
	return a + b

Different files...

const math := Math # this is ok

var c: float = math.sum(1.0, 2.0) # this is ok
var d := math.sum(1.0, 2.0) # Error: "The assigned value does not have a set type..."
var math := Math

var d := math.sum(1.0, 2.0) # this is ok
const math := preload("res://math.gd")

var d := math.sum(1.0, 2.0) # this is ok

(3.2.1 stable)

@ThakeeNathees
Copy link
Contributor

ThakeeNathees commented Apr 2, 2020

@charliewhitfield
Copy link

charliewhitfield commented Apr 2, 2020

@ThakeeNathees, thanks for the links, but I'm failing to see the relevance. My post is about the behavior of regular file classes assigned to const, which "works" (unlike inner classes) but does not allow static typing as I expected. I edited my code and comments above to make this point more clear. I may have misjudged its relationship to this issue (or even if I have an issue). Please enlighten me before I open a separate issue.

@ThakeeNathees
Copy link
Contributor

@charliewhitfield oh It's a completely different situation, sorry for that, I think you should create a new issue so someone can fix it.

@charliewhitfield
Copy link

OK. I agree it is different than either existing issue. I'll open a new one.

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

7 participants