Open ffleurey opened 7 years ago
@vassik if you have some time, could you write a test on that and see what is the behaviour for all compilers? If you do not have time, try to push @ffleurey to write this test :-)
Well, it is not possible in Java neither, and not sure if it will ever by possible... at least not before we refactor the Java main generator to use empty constructors and setters rather than "big" constructor where we pass all params (and in which we cannot call a method on the intance being created...)
In Java, it will still be a problem with readonly properties, which are (and probably should) be generated as final attributes in a Java class. Final attributes have to be set either when declared, or at latest in the constructor. Not possible to set them after constructor has been called.
@ffleurey should we forbid the initialization from a function call for readonly properties?
@jakhog @ffleurey should we forbid properties to be initialized by a function call? This is impractical to implement in the compilers, can potentially produce "strange" results (e.g. if the function produces a result based on other properties, which might or might not be initialized, yet).
If we want that behavior, we can still set properties in the on entry of the state machine (but it cannot be read-only), that is only executed once after the rest is properly initialized.
@brice-morin I don't think this is constrained to just functions, with regards to other properties that might not be initialised, you will have the same problem with e.g.:
thing T {
property A : Int = B
property B : Int = 1
...
}
and even more complicated
thing T {
property A : Int = B
property B : Int = 1
...
}
configuration C {
instance t : T
set t.B = 2
}
And even if we disallow functions, you can still do strange things with simpler expressions, e.g.
thing T {
property A : Int = 0
property B : Int = A++ * 2
property C : Int = A++ * 3
set A = 0
}
I think, that rather than forbidding special expressions in intialisers, we should enforce a strict ordering of how they are evaluated by the compilers, so that at least you get the same behaviour when you compile the code.
As far as I can tell, there are three ways of initialising a property:
var A : Int = ...
)set
statement in the thingset
statement in the configurationI propose that we set the values of properties like this:
var ... = ...
) are evaluated in the order of appearanceset
statements from the configuration is evaluated in the order of appearanceset
statements from the thing is evaluated in the order of appearanceIt's a bit strange to evaluate the configuration set
s before the thing set
s, but that would be the only way I can think of to set read-only properties based on properties that are changed from the configuration.
This doesn't stop strange things from happening, but at least it would be possible to write predictable ThingML code.
I kind of forgot about arrays when I wrote the previous comment, which complicates things even further.
IMO we should also re-think the static-size arrays in ThingML, it makes things very complicated when the size is set by properties, even when they are read-only (e.g. if they are set in the configuration).
As far as I know, it's really only a problem for C (on Arduino and the like), where there is no malloc
. I think a better solution is to allow dynamic array size for all languages, but for C (or other languages where it might be a problem), a max size of the array can be set using annotations.
What do you guys think?
At least when using the C/C++ code generator, calling functions in property initialization results in generated code which do not compile. The generated code does not make a correct reference to the Thing Instance.