"Variable initialization must be a constant value" error message

257 views
Skip to first unread message

Richard Lee

unread,
Oct 15, 2013, 8:15:08 PM10/15/13
to haxe...@googlegroups.com
I've got some code like this:


class Foo
{
    private var bar :Map = new Map<String, String>();

    public function new()
    {
    }
}


When I compile this, I get an error pointing the the declaration of variable 'bar' saying that it must be a constant value.  I see no conceivable reason for this restriction.  If it were, say, and 'inline' var, then, yes, I could see this being at the very most a warning, since you probably do not want to inline new, separate instances of the Map wherever 'bar' is used.  But in this case, how is the above code any different than:


class Foo
{
    private var bar : Map;
    
    public function new()
    {
        bar = new Map<String, String>();
    }
}

which compiles without error?

Also, if 'bar' above were declared 'static', it would also compile without error.

Richard

dlots

unread,
Oct 15, 2013, 9:34:49 PM10/15/13
to haxe...@googlegroups.com
Unless this was changed in haxe 3, you cannot initialize instance variables with the haxe syntax as specified. Initialization is generally done in the constructor. The tinkerbell macro library facilitates declarations as specified in your post.

Nicolas Cannasse

unread,
Oct 16, 2013, 5:08:42 AM10/16/13
to haxe...@googlegroups.com
Le 16/10/2013 02:15, Richard Lee a �crit :
> I've got some code like this:
>
>
> class Foo
> {
> private var bar :Map = new Map<String, String>();
>
> public function new()
> {
> }
> }
>
>
> When I compile this, I get an error pointing the the declaration of
> variable 'bar' saying that it must be a constant value. I see no
> conceivable reason for this restriction. If it were, say, and 'inline'
> var, then, yes, I could see this being at the very most a warning, since
> you probably do not want to inline new, separate instances of the Map
> wherever 'bar' is used. But in this case, how is the above code any
> different than:

There is a potential user misunderstanding in what "var x = new Map()"
does when it's not static.

- some users might think that a new Map instance is created for each Foo
instance created.
- some users might think that the instance is shared between all Foo
instances (as it does for statics)

That's the reason we have forbidden non-constant member variable
initialization outside of the constructor.

Best,
Nicolas




Simon Krajewski

unread,
Oct 16, 2013, 5:14:30 AM10/16/13
to haxe...@googlegroups.com
Am 16.10.2013 11:08, schrieb Nicolas Cannasse:
> - some users might think that the instance is shared between all Foo
> instances (as it does for statics)

You've brought that up in our previous discussion on this topic already,
and I still don't get it. Why would anyone think that a non-static
variable is shared between all instances just because it has an
initialization? Is there any language where this is the case?

Simon

Dan Korostelev

unread,
Oct 16, 2013, 7:43:03 AM10/16/13
to haxe...@googlegroups.com
I agree, that would be actually counter-intuitive if it was shared, like in none of popular languages :)

среда, 16 октября 2013 г., 13:14:30 UTC+4 пользователь Simon Krajewski написал:

David Peek

unread,
Oct 16, 2013, 8:06:38 AM10/16/13
to haxe...@googlegroups.com
It feels like the current behaviour is more confusing that the confusion it is attempting to avoid ;)

clemos

unread,
Oct 16, 2013, 8:12:27 AM10/16/13
to haxe...@googlegroups.com
+1000
I don't know any programming language where non static members are shared between all instances...


--
To post to this group haxe...@googlegroups.com
http://groups.google.com/group/haxelang?hl=en
---
You received this message because you are subscribed to the Google Groups "Haxe" group.
For more options, visit https://groups.google.com/groups/opt_out.

Matthew Spencer

unread,
Oct 16, 2013, 8:26:01 AM10/16/13
to haxe...@googlegroups.com
"It feels like the current behaviour is more confusing that the confusion it is attempting to avoid ;)"
 
+1
 

Benjamin Dubois

unread,
Oct 16, 2013, 8:47:49 AM10/16/13
to haxe...@googlegroups.com
I personnaly rather not having non static member variable initialisation outside of the constructor because it doesn't make it clear it will be done before or after the superclass call.
I can already see some haxe newbies saying "it's neither clear nor documented how it's processed" and some haxe vet' replying "it most certainly respect the principle of least surprise".

Plus you can't force people to declare member variable at the top of the class.

Simon Krajewski

unread,
Oct 16, 2013, 8:55:13 AM10/16/13
to haxe...@googlegroups.com
Am 16.10.2013 14:47, schrieb Benjamin Dubois:
I personnaly rather not having non static member variable initialisation outside of the constructor because it doesn't make it clear it will be done before or after the superclass call.
I can already see some haxe newbies saying "it's neither clear nor documented how it's processed" and some haxe vet' replying "it most certainly respect the principle of least surprise".

Plus you can't force people to declare member variable at the top of the class.

This is the reason I originally didn't want to implement member field initialization at all, but it's missing the point here. We already do allow this kind of initialization, but it's restricted to certain values. The super-problem is then unrelated because it applies to all initialization values anyway.

Simon

David Peek

unread,
Oct 16, 2013, 8:55:39 AM10/16/13
to haxe...@googlegroups.com
We already have instance var initialisation, and I've not seen anyone complaining. Non constant values would be initialised in the same place as constant values were I'd imagine.

Benjamin Dubois

unread,
Oct 16, 2013, 9:02:15 AM10/16/13
to haxe...@googlegroups.com
I must I've missed something :
I believed only static member could be initilised like that.
And since haxe 3, it was restricted to basic types (Int, Float, Bool...).

I was not aware non-static members could be initialised like that.

clemos

unread,
Oct 16, 2013, 9:06:21 AM10/16/13
to haxe...@googlegroups.com
IMHO, it's clear that member variable initialization should occur at the very beginning of the constructor...

In any case, it should indeed be documented somewhere...

Regards,
Clément

Richard Lee

unread,
Oct 16, 2013, 1:31:10 PM10/16/13
to haxe...@googlegroups.com
There are *no* commonly used languages I know of where non-static variables initialized at declaration are shared between all instances.  That would be extremely unexpected behavior for an *instance* variable.

Given that Haxe allows the declaration initialization of static variables with non constant values, and the declaration initialization of non-static variables with constant values, it seems very odd that it prohibits the declaration initialization of instance variables with non-constant values.

I do agree that some documentation needs to describe the order of execution of initiailization w.r.t. the constructor.  Something as simple as "instance variables are initialized before the constructor is called, in the order they are declared in the file" would be sufficient, and is what other similar languages like AS3 do.  http://livedocs.adobe.com/specs/actionscript/3/as3_specification74.html

Richard

On Wednesday, October 16, 2013 2:08:42 AM UTC-7, Nicolas Cannasse wrote:
Le 16/10/2013 02:15, Richard Lee a �crit :

Hugh

unread,
Oct 17, 2013, 12:29:29 AM10/17/13
to haxe...@googlegroups.com
Yeah, it's a very odd restriction.  I think a reasonable restriction would be "no this pointer", otherwise ordering becomes important, eg:

var x = 10;
var y = x;

would be ok in a constructor:
  x = 10;
  y = x;

but it is potentially ambiguous inline.
Haxe gets some issues by not insisting that super being the first call, so  do all base-class initializations occur before the derived constructor call?  But this problem is there whether it is a constant initialization or not.

I think any corner cases of initialization orders (eg side-effects) are insignificant compared to the very REAL issue of not initializing members.  Particularly for beginners, the former problem might never occur, while the latter problem will almost certainly happen at some time.

I just can't get away from the fact that I think initializing at declaration time is the Best Practice.

Hugh

Nicolas Cannasse

unread,
Oct 17, 2013, 3:07:10 AM10/17/13
to haxe...@googlegroups.com
Le 17/10/2013 06:29, Hugh a �crit :
> Yeah, it's a very odd restriction. I think a reasonable restriction
> would be "no this pointer", otherwise ordering becomes important, eg:
>
> var x = 10;
> var y = x;
>
> would be ok in a constructor:
> x = 10;
> y = x;
>
> but it is potentially ambiguous inline.
> Haxe gets some issues by not insisting that super being the first call,
> so do all base-class initializations occur before the derived
> constructor call? But this problem is there whether it is a constant
> initialization or not.
>
> I think any corner cases of initialization orders (eg side-effects) are
> insignificant compared to the very REAL issue of not initializing
> members. Particularly for beginners, the former problem might never
> occur, while the latter problem will almost certainly happen at some time.

Thinking again about it and weighting the pro and cons, I've concluded
that it's fine to partially lift the current restrictions.

I've opened an issue here for people which want to track the progress,
it should be available quite quickly on GIT:
https://github.com/HaxeFoundation/haxe/issues/2262

Best,
Nicolas

Benjamin Dubois

unread,
Oct 17, 2013, 3:32:03 AM10/17/13
to haxe...@googlegroups.com
So what will be the precedence of initialization ?
In order :
  • super member variable
  • member variable
  • super constructor
  • constructor
?


On Thu, Oct 17, 2013 at 9:07 AM, Nicolas Cannasse <ncan...@gmail.com> wrote:


Best,
Nicolas

Reply all
Reply to author
Forward
0 new messages