This is awesome. Now can we get support for non-const initializers for instance fields too? :)
no more lazy singleton in Dart, it's shocking :)
There is one thing I didn't get: why static initializer has to be constant ?
Knowing that a constant constructor can do side effect, I don't see the
interest.
R�mi
>
>
> On Tue, Feb 28, 2012 at 4:22 PM, Gilad Bracha <gbr...@google.com
> <mailto:gbr...@google.com>> wrote:
>
> In Dart static variables may only be initialized with
> compile-time constants (hereafter referred to as just
> constantsin the interest of brevity). Static variables
> include all top-level variables as well as static variables of
> classes. The motivation is our desire to avoid costly
> initialization (and attendant slowness) at program startup.
> However, the requirement to use constants is quite restrictive.
>
> We plan on relaxing the restrictions on initialization of
> statics while still avoiding high latency at startup by making
> the initialization lazy. We can evaluate the initializer at
> first use rather than at library or class load time.
>
> We are aware that the interaction of laziness and imperative
> programming is problematic, because results are timing
> dependent. Currently this is a non-issue because the
> initializers evaluate constants, which are timing-independent.
>
> Nevertheless, lifting the restriction that statics be
> initialized is a clear win, and has have no semantic effect on
> currently legal programs. Code that relies on side-effects in
> initialization could behave in surprising ways, but order
> dependent initialization is a bad idea and should be avoided
> in any case.
>
> Below are the relevant spec changes. For speakers of English,
> *the executive summary* is:
>
>
> /You will be able to use any expression (not just constant
> expressions) to initialize a static variable (including top
> level variables). The initialization will be carried out upon
> the first invocation of the getter of that variable (aka first
> read). If the initialization throws an exception, the variable
> will be set to null, and the exceptionwill be propagated./
>
>
>
> Specification Changes
>
>
> As usual, changes highlighted in yellow.
>
>
> Variables
>
> Variables are storage locations in memory.
>
> variableDeclaration:
> declaredIdentifier
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.2xe95ykmes0u>(','
> identifier)*
> ;
>
> initializedVariableDeclaration:
> declaredIdentifier
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.2xe95ykmes0u>('='
> expression)? (','initializedIdentifier
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.cjgl4bau1n1l>)*
> ;
>
> initializedIdentifierList:
> initializedIdentifier (','initializedIdentifier
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.cjgl4bau1n1l>)*
> ;
>
> initializedIdentifier:
> identifier ('=' expression)?
> ;
>
> declaredIdentifier:
> finalVarOrType identifier
> ;
>
>
> finalVarOrType:
> finaltype?
> | var
> | type
> ;
>
>
>
>
> A variable that has not been initialized has the initial value
> null.
> A final variableis a variable whose declaration includes the
> modifier final.A final variable can only be assigned once,
> when it is initialized, or a compile-time error occurs.
>
> A static variableis a variable that is not associated with a
> particular instance, but rather with an entire library or class.
>
> Static variable declarations are initialized lazily. The first
> time a static variable vis read, it is set to the result of
> evaluating its initializer. The precise rules are given in
> sections 7.7
> <https://docs.google.com/a/google.com/document/d/1xnLrrLiR-hJ9vyKFl2ouZEhPNxjvRT9EBHp04nEVr2g/edit#bookmark=id.2ay2xojrdai1>and
> 10.28
> <https://docs.google.com/a/google.com/document/d/1xnLrrLiR-hJ9vyKFl2ouZEhPNxjvRT9EBHp04nEVr2g/edit#bookmark=id.h1r7vmqzkcij>.
>
>
> The lazy semantics are given because we do not want a language
> where one tends to define expensive initialization
> computations, causing long application startup times. This is
> especially crucial for Dart, which is designed for coding
> client applications.
>
>
> If a variable declaration does not explicitly specify a type,
> the type of the declared variable(s) is Dynamic, the unknown
> type
>
> A top-level variable is implicitly static. It is a
> compile-time error to preface a top level variable declaration
> with the built-in identifier static. It is a compile-time
> error if a top level variable is initialized with an
> expression that is not acompile-time constant
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.hzs87hup8wb>.
>
>
> Static Variables
>
> **
> Static variablesarevariables
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=kix.6b1cgvgf1cyq>whose
> declarations are immediately contained within a class
> declaration and that are declared static.The static variables
> of a class Care those static variables declared by C.
>
> A static variable declaration of one of the forms staticT v;,
> staticT v = e; or static finalT v = e; always induces an
> implicit staticgetter function
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=kix.wlocpej6rvqa>with
> signature
>
> staticT get v()
>
> whose invocation evaluates as described below
>
> A static variable declaration of one of the forms static
> var v;, static var v = e; or static finalv = e; always
> induces an implicit staticgetter function
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=kix.wlocpej6rvqa>with
> signature
>
> staticget v()
>
> whose invocation evaluates as described below
>
> A non-final static variable declaration of the form staticT
> v;or the form staticT v = e; always induces an implicit
> staticsetter function
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=kix.i4xvz9z9edz>with
> signature
>
> static voidset v(T x)
>
> whose execution sets the value of vto the incoming argument x.
>
> A non-final static variable declaration of the form static var
> v;or the form static varv = e; always induces an implicit
> staticsetter function
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=kix.i4xvz9z9edz>with
> signature
>
> static set v(x)
>
> whose execution sets the value of vto the incoming argument x.
>
>
> Evaluation of static variable getters
>
>
>
> Let dbe the declaration of a static variable v.The implicit
> getter method of vexecutes as follows:
>
> * If d is of one of the forms static varv = e; , static T v
> = e; , static finalv = e;or static finalT v = e;and no
> value has yet been stored into vthen the initializer
> expression eis evaluated. If the evaluation succeeded
> yielding an object o, let r = o,otherwise let r = null.In
> any case, ris stored into v.The result of executing the
> getter is r. Otherwise
> * The result of executing the getter method is the value
> stored in v.
>
>
>
>
> Identifier Reference
>
> **
> An identifier expressionconsists of a single identifier; it
> the exception of user defined operators named negateor call.
>
> Built-in identifiers are identifiers that are used as keywords
> in Dart, but are not reserved words in Javascript. To minimize
> incompatibilities when porting Javascript code to Dart, we do
> not make these into reserved words. However, a built-in
> identifier may not be used to name a class or type. In other
> words, they are treated as reserved words when used as types.
> This eliminates many confusing situations without causing
> compatibility problems.
>
> Evaluation of an identifier expression eof the form idproceeds
> as follows:
> Let dbe the innermost declaration in the enclosing lexical
> scope whose name is id. It is a compile-time error if dis a
> class, interface, type alias or type variable. If no such
> declaration exists in the lexical scope, let dbe the
> declaration of the inherited member named idif it exists.
>
> * If dis a library variable then:
> o If d is of one of the forms varv = ei; , T varv = ei;
> , finalv = ei;or finalT v = ei;and no value has yet
> been stored into vthen the initializer expression eiis
> evaluated. If the evaluation succeeded yielding an
> object o, let r = o,otherwise let r = null.In any
> case, ris stored into v.The value of eis r. Otherwise
> o eevaluates to the current binding of id.This case also
> applies if dis a library function declaration, as
> these are equivalent to function-valued variable
> declarations.
> * If dis a local variable or formal parameter then
> eevaluates to the current binding of id.This case also
> applies if dis a local function declaration, as these are
> equivalent to function-valued variable declarations.
> * If dis a static method, then eevaluates to the function
> defined by d.
> * If dis the declaration of a static variable or static
> getter declared in class C,then eis equivalent to
> thegetter invocation
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.lharm2td3qkb>C.id.
> * If dis the declaration of a top level getter, then eis
> equivalent to thegetter invocation
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.lharm2td3qkb>id.
> * Otherwise eis equivalent to theproperty extraction
> <https://docs.google.com/a/google.com/document/d/1YblLwWryUj0VZBJ2xBgat4gYgH0mSFGuyrJpbcT5bTw/edit?hl=en_US#bookmark=id.hu9dfddw6bhy>this.id.
On 02/29/2012 01:58 AM, Gilad Bracha wrote:
for /instance/ fields too? :)
On Tue, Feb 28, 2012 at 4:51 PM, Bob Nystrom <rnys...@google.com <mailto:rnys...@google.com>> wrote:
This is awesome. Now can we get support for non-const initializers
That is more complicated. Rome was not built in a day.
- bob
no more lazy singleton in Dart, it's shocking :)
There is one thing I didn't get: why static initializer has to be constant ?
Knowing that a constant constructor can do side effect, I don't see the interest.
Rémi
Hi Florian,
you can call a function in the initializer list that will do a side effect.
foo() {
print("side effect");
}
class A {
final a;
const A():a=foo();
}
A a = const A();
R�mi
On 02/29/2012 10:15 AM, Florian Loitsch wrote:
Rémi
Hi Nicolas,
I've just read the latest spec, you're right, the implementations (VM
and frog) are just too permissive.
cheers,
R�mi
Would this then just introduce a hidden aspect of implementations,
that statics initialized with a constant can be more efficient than
statics initialized with a non-constant? Or are we expecting code to
be compiled after the static is initialized, and that that code will
not do the initialization check?
What are the use cases where this change would be useful? I see
mainly the case of a singleton, with complex initialization of the
singleton.
On Wed, Feb 29, 2012 at 1:04 PM, Rémi Forax <fo...@univ-mlv.fr> wrote:
> On 02/29/2012 11:41 AM, Nicolas Geoffray wrote:
>>
>> Hi Remi,
>>
>>
>> On Wed, Feb 29, 2012 at 11:34 AM, Rémi Forax <fo...@univ-mlv.fr
>> <mailto:fo...@univ-mlv.fr>> wrote:
>>
>> On 02/29/2012 10:15 AM, Florian Loitsch wrote:
>>
>> On Wed, Feb 29, 2012 at 02:09, Rémi Forax <fo...@univ-mlv.fr
> Rémi
>
--
William Hesse
Software Engineer
whe...@google.com
Google Denmark ApS
Frederiksborggade 20B, 1 sal
1360 København K
Denmark
CVR nr. 28 86 69 84
If you received this communication by mistake, please don't forward it
to anyone else (it may contain confidential or privileged
information), please erase all copies of it, including all
attachments, and please let the sender know it went to the wrong
person. Thanks.
E.g.
var foo = () { return foo + 1; }();
or
var foo = bar + 1;
var bar = foo + 1;
We have requirements against cyclic dependencies in compile time
constants (10.1), but I don't see anything here. Rather, the getter
will just end up calling itself again, because it reads the field
before it's written, causing an infinite recursion.
Maybe we need to have a unique marker value that we can write to the
field while evaluating the initializer, and if we ever read that
value, we'll throw some cyclic-dependency-error exception instead (and
set the field to null on the way out). Or can we rely on the
stack-overflow exception to do that?
/L 'String operator+(String x)! operator==(x)! operator ()(x,y)! operator-(x)!'
--
Lasse R.H. Nielsen
l...@google.com
'Faith without judgement merely degrades the spirit divine'
Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 København K -
Denmark - CVR nr. 28 86 69 84
As far as I understand, only subsequent access to the constant variable
will returning null.
But I prefer the semantics of Java static block, if an exception occurs,
all subsequent calls will return the same exception.
R�mi
>
> On Wed, Feb 29, 2012 at 7:25 AM, Lasse R.H. Nielsen <l...@chromium.org
> <mailto:l...@chromium.org>> wrote:
>
> How does this handle (direclty or mutually) recursive initializations?
>
> E.g.
> var foo = () { return foo + 1; }();
> or
> var foo = bar + 1;
> var bar = foo + 1;
>
> We have requirements against cyclic dependencies in compile time
> constants (10.1), but I don't see anything here. Rather, the getter
> will just end up calling itself again, because it reads the field
> before it's written, causing an infinite recursion.
>
> Maybe we need to have a unique marker value that we can write to the
> field while evaluating the initializer, and if we ever read that
> value, we'll throw some cyclic-dependency-error exception instead (and
> set the field to null on the way out). Or can we rely on the
> stack-overflow exception to do that?
>
> /L 'String operator+(String x)! operator==(x)! operator ()(x,y)!
> operator-(x)!'
> --
> Lasse R.H. Nielsen
> l...@google.com <mailto:l...@google.com>
> 'Faith without judgement merely degrades the spirit divine'
> Google Denmark ApS - Frederiksborggade 20B, 1 sal - 1360 K�benhavn K -
On 02/29/2012 03:07 PM, Sean Eagan wrote:As far as I understand, only subsequent access to the constant variable
What is the reasoning behind suppressing exceptions (i.e. just returning null) on evaluating the initializer ?
will returning null.
But I prefer the semantics of Java static block, if an exception occurs,
all subsequent calls will return the same exception.
Does this change still allow implementers to perform constant
initialization eagerly?
What are the use cases where this change would be useful?
Sorry, but this fails to convince me.
If you want a shorthand for
this pattern, why not introduce the "||=" operator, whose semantics
should be obvious.
Foo get foo() => _foo ||= new Foo();
On Mar 29, 2:32 pm, Gilad Bracha <gbra...@google.com> wrote:
> On Thu, Mar 29, 2012 at 11:17 AM, John Tobey <john.to...@gmail.com> wrote:Huh? "return a+=4" means "a=a+4; return a". "return _foo ||= new
> > If you want a shorthand for
> > this pattern, why not introduce the "||=" operator, whose semantics
> > should be obvious.
>
> > Foo get foo() => _foo ||= new Foo();
>
> The obvious semantics would be compound assignment:
>
> _foo = _foo = _foo || new Foo();
>
> So that particular syntax is not viable.
Foo()" means "_foo = _foo || new Foo(); return _foo". Where's the
problem?
I'm glad you are happy, but with all due respect, you are much more
> In any case, we never want to
> allow eager initialization of statics, because we don't want to get slow
> initialization. So we if we wanted a special notation for lazy assignment
> , we'd have to ban normal assignment syntax for statics. That is certainly
> surprising.
>
> We're *very* happy with the solution we have for this particular issue.
experienced at this than Dart's target user. Any evidence of
needlessly slow pages where this would help?
On Feb 29, 3:16 pm, Bob Nystrom <rnyst...@google.com> wrote:
> On Wed, Feb 29, 2012 at 9:34 AM, Gilad Bracha <gbra...@google.com> wrote:
>Sorry, but this fails to convince me. If you want a shorthand for
> > On Wed, Feb 29, 2012 at 4:19 AM, William Hesse <whe...@google.com> wrote:
> >> What are the use cases where this change would be useful?
>
> > I think the set of useful cases is pretty much unbounded. Anywhere where
> > you want to initialize a static with something that is not a Dart constant.
> > And Dart constants are pretty restrictive.
>
> If you hunt through the repo, you can find a number of examples of code
> like:
>
> Foo get foo() {
> if (_foo == null) _foo = new Foo();
> return _foo;}
>
> Foo _foo;
>
> With this change, all of those can just be:
>
> final foo = new Foo();
this pattern, why not introduce the "||=" operator, whose semantics
should be obvious.
Foo get foo() => _foo ||= new Foo();
I just find it SOOO surprising that "final foo = new Foo()" does not
execute "new Foo()".
Can anyone cite a precedent in another language?
Where is the conservatism that kept Dart from being a fully cool, functional language when you need it?
Can anyone cite a precedent in another language?Java and C#? I believe static fields are lazy-initialized in both of those.
Don't forget that Dart is not the same language as Java,
Java doesn't have isolates so static variables can be accessed concurrently,
that's why Java does all static initializations at class init because
the code has to hold a lock.
R�mi