[vwnc] BraceConstructor breaks refactorings (tentative fix included)

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
38 messages Options
12
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Andres Valloud-4
Ahh, cool!

Stéphane Ducasse wrote:

> On Jun 30, 2009, at 9:48 AM, Valloud, Andres wrote:
>
>  
>> IIRC, when I first saw {...} in Squeak, the result of each
>> subexpression was evaluated at compile time.  Stef, does {...}
>> behave like that these days?  If so, doesn't it cause problems when
>> the lists become stale?
>>    
>
> subexpression are evaluated at runtime.
>
>
> zork
>         "self new zork"
>         ^ {Smalltalk at: #Zork}
>
> will only complain at runtime since Zork is not defined as global or
> class in Squeak.
>
>
>
>  
>> Vassili, to borrow from the macro expansion metaphor for the sake of
>> illustration only, do you mean {1. 2. 3} to be replaced like this
>> (mod the fact that there are only so many with:^n selectors, etc.)?
>>
>> (Array with: [1] value with: [2] value with: [3] value)
>>
>> Or do you mean for objects to live inside complex compiled method
>> literals?  If you mean the latter, consider the case where at first
>> I make a mistake an implement:
>>
>> Integer>>factorial
>>
>>  self < 1 ifTrue: [^nil].
>>  ^"do the calculation somehow"
>>
>>
>> After implementing this method, I go ahead and write:
>>
>> WhateverObject>>someFactorials
>>
>>  ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>
>>
>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>
>> Integer>>factorial
>>
>>  self < 0 ifTrue: [^nil].
>>  ^"do the calculation somehow"
>>
>>
>> It would seem weird to me that modifying the above method should
>> trigger recompiling #someFactorials (by hand?).  To some extent, the
>> problem would be that some portion of the app would be created
>> imperatively as opposed to declaratively... in a way, it would be a
>> special case of the more general problem of creating an arbitrary
>> image from source code or from a specification.  On the other hand,
>> if the "expansion" executed code to create the list from scratch
>> each time {...} is encountered, then the problem would go away.
>>
>>
>> -----Original Message-----
>> From: [hidden email] [mailto:[hidden email]] On
>> Behalf Of Vassili Bykov
>> Sent: Tuesday, June 30, 2009 12:17 AM
>> To: [hidden email]
>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
>> fixincluded)
>>
>> I would be satisfied with anything that (1) satisfies the spec and
>> (2) is practically viable. Given those two, I don't care how it's
>> implemented. Discussing an equivalent macro expansion is only useful
>> to clarify the semantics but not the motivation (though your
>> expansion doesn't work for the general case).
>>
>> The motivation here, to make it reasonably general, is allowing
>> lexically nested named contexts to represent nested entities of the
>> model. For example:
>>
>> row: {
>>    prefix.
>>    column: {
>>        header.
>>        row: {item1. item2. item3. item4. item5. item6. item7}.
>>        row: {item8. item9}.
>>        footer.
>>    }.
>>    suffix.
>> }
>>
>> One can come up with other schemes to encode such things, but
>> nothing with as little extraneous gunk as in this. (This is a real
>> example of a Hopscotch presenter definition).
>>
>> --Vassili
>>
>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>> Valloud<[hidden email]> wrote:
>>    
>>> So, if braces were taken care of by a macro preprocessor that
>>> replaced
>>>
>>> {1. 2. 3.}
>>>
>>> with
>>>
>>> (Array with: (1) with: (2) with: (3))
>>>
>>> would you be satisfied as far as the results go?  Is this just a
>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>> syntax of the language?
>>>
>>>
>>> Vassili Bykov wrote:
>>>      
>>>> It's all in the language spec, and your criticism assumes a
>>>> suboptimal spec. The spec should say that a brace expression
>>>> evaluates to an object that conforms to an immutable list protocol.
>>>> Not an Array or any other specific class. It should also state that
>>>> it is unspecified whether or not results of multiple evaluations can
>>>> be identical or otherwise share their structure.
>>>>
>>>> What this achieves is:
>>>>
>>>> 1) It shifts the focus from the implementation to the interface. The
>>>> point of having braces is syntactically cheap list specification,
>>>> not
>>>> syntactically cheap Array creation. The divide is easily and safely
>>>> crossed if the immutable list protocol includes a message like
>>>> #asArray to produce a mutable Array.
>>>>
>>>> 2) Immutability requires no AI in the compiler, while the compiler
>>>> is
>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>
>>>> 3) The code is safe because immutability is on and has to be
>>>> explicitly turned off and not vice versa.
>>>>
>>>> --Vassili
>>>>
>>>>
>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>
>>>>        
>>>>> Vassili,
>>>>>
>>>>> From a language theory point of view, I must disagree that
>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>> compile time with immutable values and state.  This is /not/ true
>>>>> of any constructed list, and almost all modern languages
>>>>> recognize this.
>>>>>
>>>>> It is also incorrect to assume that the compiler can determine
>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>
>>>>>        #{ 5  6 )
>>>>>        #[ 5, 6 ]
>>>>>
>>>>> Here the first one is a literal array that is marked immutable
>>>>> (invariant), while the second is a constructed array that is /
>>>>> not/ immutable.  While it is true that both arrays can be
>>>>> statically constructed by the compiler, the reference semantics
>>>>> are quite different.  In the former case the array and its
>>>>> individual members are immutable and all references are shared
>>>>> (identity semantics);  in the latter the members may or may not
>>>>> be immutable and at least all top-most references must be copies
>>>>> (equality semantics).  This gets even more complicated or obvious
>>>>> with embedded constructs:
>>>>>
>>>>>        #( 5  #( 7  8 )  6 )
>>>>>        #[ 5, #[ 7, 8 ], 6 ]
>>>>>
>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>> it must be defined by the language specification, which is why
>>>>> you need two separate representations.  Making them /more/
>>>>> similar in syntax is perhaps desirable.  For example, I would be
>>>>> perfectly happy with:
>>>>>
>>>>>         #( 5. 6 )
>>>>>        ##( 5. 6 )
>>>>>
>>>>> [choose your favorite syntax], where the former only permits
>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>> periods should be optional for the former, but would be required
>>>>> for the latter to prevent ambiguity with unary message sends.
>>>>>
>>>>> Eliminating the case of the literal form actually will make code
>>>>> unsafe and less unreadable because you must explicitly
>>>>> recursively mark the result as immutable - something we'll all
>>>>> forget to do.
>>>>>
>>>>> Cheers!
>>>>>
>>>>> Tom Hawker
>>>>> --------------------------
>>>>> Senior Framework Developer
>>>>> --------------------------
>>>>> Home    +1 (408) 274-4128
>>>>> Office  +1 (408) 576-6591
>>>>> Mobile  +1 (408) 835-3643
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]] On
>>>>> Behalf Of Vassili Bykov
>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>> To: vwnc
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
>>>>> fix included)
>>>>>
>>>>> To clarify a few points:
>>>>>
>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>> with: expr 1 with:
>>>>> expr2)".
>>>>>
>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>> usable syntax for specifying lists of things, without the random
>>>>> limitations of literal array syntax. This is immensely useful in
>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>> Smalltalk
>>>>> got it wrong, literal arrays are a wart. Something like the braces,
>>>>> with arbitrary expressions inside, should have been the default and
>>>>> *the only* way to specify arrays. It should be up to the compiler
>>>>> to
>>>>> optimize array expressions with constant elements to (read-only)
>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>> ConsArray bytecode).
>>>>>
>>>>> Redundancy, as in "we already have Array with:", has nothing to do
>>>>> with this. By the same logic nil, true, and false as
>>>>> pseudo-variables should have been unnecessary. They could have been
>>>>> implemented instead as "UndefinedObject default", "True default"
>>>>> and "False default."
>>>>>
>>>>> Thank you, David, for looking after this.
>>>>>
>>>>> --Vassili
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> IMPORTANT NOTICE
>>>>> Email from OOCL is confidential and may be legally privileged.  If
>>>>> it is not intended for you, please delete it immediately unread.
>>>>> The internet cannot guarantee that this communication is free of
>>>>> viruses, interception or interference and anyone who communicates
>>>>> with us by email is taken to accept the risks in doing so.  Without
>>>>> limitation, OOCL and its affiliates accept no liability whatsoever
>>>>> and howsoever arising in connection with the use of this email.
>>>>> Under no circumstances shall this email constitute a binding
>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>> which is subject to the availability of carrier's equipment and
>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>> lading which is also available at http://www.oocl.com.
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>    
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

thomas.hawker
In reply to this post by Andres Valloud-6
Andres:
 
Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
 
This should not be an issue.  The compiler can count the subexpressions in each {...} list, so it does not need to use the "with:*" variants except as an optimization.  Code generation is done after program node construction, and node construction can be deferred so that the size is known.
 
I have a compiler variant that recognizes GemStone array constructor syntax (#[a, b, ...]).  I programmed it to build VW nodes that use #add: on an OrderedCollection, converting later with #asArray, but could just as easily have delayed node construction to prebuild the array at the correct size and used #at:put: on the individual elements.  The latter approach requires you maintain a stack of open constructions since you can have arrays in arrays, #[a, #[b, c], ...], etc.
 
Cheers!
 
Tom Hawker
--------------------------
Senior Framework Developer
--------------------------
Home    +1 (408) 274-4128
Office  +1 (408) 576-6591
Mobile  +1 (408) 835-3643
 
 
-----Original Message-----
From: [hidden email] [[hidden email]] On Behalf Of Valloud, Andres
Sent: Tuesday, June 30, 2009 12:48 AM
To: [hidden email]
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
 
IIRC, when I first saw {...} in Squeak, the result of each subexpression was evaluated at compile time.  Stef, does {...} behave like that these days?  If so, doesn't it cause problems when the lists become stale?
 
Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
 
(Array with: [1] value with: [2] value with: [3] value)
 
Or do you mean for objects to live inside complex compiled method literals?  If you mean the latter, consider the case where at first I make a mistake an implement:
 
Integer>>factorial
 
  self < 1 ifTrue: [^nil].
  ^"do the calculation somehow"
 
 
After implementing this method, I go ahead and write:
 
WhateverObject>>someFactorials
 
  ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
 
 
Then, I realize I messed up Integer>>factorial, so I correct it:
 
Integer>>factorial
 
  self < 0 ifTrue: [^nil].
  ^"do the calculation somehow"
 
 
It would seem weird to me that modifying the above method should trigger recompiling #someFactorials (by hand?).  To some extent, the problem would be that some portion of the app would be created imperatively as opposed to declaratively... in a way, it would be a special case of the more general problem of creating an arbitrary image from source code or from a specification.  On the other hand, if the "expansion" executed code to create the list from scratch each time {...} is encountered, then the problem would go away.
 
 
-----Original Message-----
From: [hidden email] [[hidden email]] On Behalf Of Vassili Bykov
Sent: Tuesday, June 30, 2009 12:17 AM
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
 
I would be satisfied with anything that (1) satisfies the spec and (2) is practically viable. Given those two, I don't care how it's implemented. Discussing an equivalent macro expansion is only useful to clarify the semantics but not the motivation (though your expansion doesn't work for the general case).
 
The motivation here, to make it reasonably general, is allowing lexically nested named contexts to represent nested entities of the model. For example:
 
row: {
    prefix.
    column: {
        header.
        row: {item1. item2. item3. item4. item5. item6. item7}.
        row: {item8. item9}.
        footer.
    }.
    suffix.
}
 
One can come up with other schemes to encode such things, but nothing with as little extraneous gunk as in this. (This is a real example of a Hopscotch presenter definition).
 
--Vassili
 
On Mon, Jun 29, 2009 at 6:05 PM, Andres
Valloud<[hidden email]> wrote:
> So, if braces were taken care of by a macro preprocessor that replaced
>
> {1. 2. 3.}
>
> with
>
> (Array with: (1) with: (2) with: (3))
>
> would you be satisfied as far as the results go?  Is this just a
> matter of keyboard shorthand?  If so, why does it need to be in the
> syntax of the language?
>
>
> Vassili Bykov wrote:
>> It's all in the language spec, and your criticism assumes a
>> suboptimal spec. The spec should say that a brace expression
>> evaluates to an object that conforms to an immutable list protocol.
>> Not an Array or any other specific class. It should also state that
>> it is unspecified whether or not results of multiple evaluations can
>> be identical or otherwise share their structure.
>>
>> What this achieves is:
>>
>> 1) It shifts the focus from the implementation to the interface. The
>> point of having braces is syntactically cheap list specification, not
>> syntactically cheap Array creation. The divide is easily and safely
>> crossed if the immutable list protocol includes a message like
>> #asArray to produce a mutable Array.
>>
>> 2) Immutability requires no AI in the compiler, while the compiler is
>> free to optimize deeply immutable lists to literals. Or not.
>>
>> 3) The code is safe because immutability is on and has to be
>> explicitly turned off and not vice versa.
>>
>> --Vassili
>>
>>
>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>
>>> Vassili,
>>>
>>> From a language theory point of view, I must disagree that literal arrays are "warts".  They epresent constants defined at compile time with immutable values and state.  This is /not/ true of any constructed list, and almost all modern languages recognize this.
>>>
>>> It is also incorrect to assume that the compiler can determine immutability on its own.  Consider this case (using GS/S syntax):
>>>
>>>        #{ 5  6 )
>>>        #[ 5, 6 ]
>>>
>>> Here the first one is a literal array that is marked immutable (invariant), while the second is a constructed array that is /not/ immutable.  While it is true that both arrays can be statically constructed by the compiler, the reference semantics are quite different.  In the former case the array and its individual members are immutable and all references are shared (identity semantics);  in the latter the members may or may not be immutable and at least all top-most references must be copies (equality semantics).  This gets even more complicated or obvious with embedded constructs:
>>>
>>>        #( 5  #( 7  8 )  6 )
>>>        #[ 5, #[ 7, 8 ], 6 ]
>>>
>>> A compiler cannot /intuit/ that either one should be invariant; it must be defined by the language specification, which is why you need two separate representations.  Making them /more/ similar in syntax is perhaps desirable.  For example, I would be perfectly happy with:
>>>
>>>         #( 5. 6 )
>>>        ##( 5. 6 )
>>>
>>> [choose your favorite syntax], where the former only permits literals while the latter permits arbitrary expressions.  Using periods should be optional for the former, but would be required for the latter to prevent ambiguity with unary message sends.
>>>
>>> Eliminating the case of the literal form actually will make code unsafe and less unreadable because you must explicitly recursively mark the result as immutable - something we'll all forget to do.
>>>
>>> Cheers!
>>>
>>> Tom Hawker
>>> --------------------------
>>> Senior Framework Developer
>>> --------------------------
>>> Home    +1 (408) 274-4128
>>> Office  +1 (408) 576-6591
>>> Mobile  +1 (408) 835-3643
>>>
>>> -----Original Message-----
>>> Behalf Of Vassili Bykov
>>> Sent: Monday, June 29, 2009 3:22 PM
>>> To: vwnc
>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
>>> fix included)
>>>
>>> To clarify a few points:
>>>
>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array with: expr 1 with:
>>> expr2)".
>>>
>>> Speed has nothing to do with this. The motivation is to provide a
>>> usable syntax for specifying lists of things, without the random
>>> limitations of literal array syntax. This is immensely useful in
>>> embedded DSLs, for example. Let me put it bluntly: classic Smalltalk
>>> got it wrong, literal arrays are a wart. Something like the braces,
>>> with arbitrary expressions inside, should have been the default and
>>> *the only* way to specify arrays. It should be up to the compiler to
>>> optimize array expressions with constant elements to (read-only)
>>> literals. (But speaking of raw speed, the VW version of braces
>>> doesn't create arrays by talking to the Array class, it uses the
>>> ConsArray bytecode).
>>>
>>> Redundancy, as in "we already have Array with:", has nothing to do
>>> with this. By the same logic nil, true, and false as
>>> pseudo-variables should have been unnecessary. They could have been
>>> implemented instead as "UndefinedObject default", "True default" and "False default."
>>>
>>> Thank you, David, for looking after this.
>>>
>>> --Vassili
>>> _______________________________________________
>>> vwnc mailing list
>>>
>>> IMPORTANT NOTICE
>>> Email from OOCL is confidential and may be legally privileged.  If
>>> it is not intended for you, please delete it immediately unread.  
>>> The internet cannot guarantee that this communication is free of
>>> viruses, interception or interference and anyone who communicates
>>> with us by email is taken to accept the risks in doing so.  Without
>>> limitation, OOCL and its affiliates accept no liability whatsoever
>>> and howsoever arising in connection with the use of this email.  
>>> Under no circumstances shall this email constitute a binding
>>> agreement to carry or for provision of carriage services by OOCL,
>>> which is subject to the availability of carrier's equipment and
>>> vessels and the terms and conditions of OOCL's standard bill of lading which is also available at http://www.oocl.com.
>>>
>>>
>>
>> _______________________________________________
>> vwnc mailing list
>> .
>>
>>
> _______________________________________________
> vwnc mailing list
>
 
_______________________________________________
vwnc mailing list
 
_______________________________________________
vwnc mailing list
 
IMPORTANT NOTICE
Email from OOCL is confidential and may be legally privileged.  If it is not
intended for you, please delete it immediately unread.  The internet
cannot guarantee that this communication is free of viruses, interception
or interference and anyone who communicates with us by email is taken
to accept the risks in doing so.  Without limitation, OOCL and its affiliates
accept no liability whatsoever and howsoever arising in connection with
the use of this email.  Under no circumstances shall this email constitute
a binding agreement to carry or for provision of carriage services by OOCL,
which is subject to the availability of carrier's equipment and vessels and
the terms and conditions of OOCL's standard bill of lading which is also
available at http://www.oocl.com.

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Andres Valloud-4
Thomas,

Regarding with:^n, yes... I just meant that with:with:with:etc: was
being used for the sake of illustration as opposed to an actual means of
implementation.

Andres.

[hidden email] wrote:

> Andres:
>  
> Vassili, to borrow from the macro expansion metaphor for the sake of
> illustration only, do you mean {1. 2. 3} to be replaced like this (mod
> the fact that there are only so many with:^n selectors, etc.)?
>  
> This should not be an issue.  The compiler can count the
> subexpressions in each {...} list, so it does not need to use the
> "with:*" variants except as an optimization.  Code generation is done
> after program node construction, and node construction can be deferred
> so that the size is known.
>  
> I have a compiler variant that recognizes GemStone array constructor
> syntax (#[a, b, ...]).  I programmed it to build VW nodes that use
> #add: on an OrderedCollection, converting later with #asArray, but
> could just as easily have delayed node construction to prebuild the
> array at the correct size and used #at:put: on the individual
> elements.  The latter approach requires you maintain a stack of open
> constructions since you can have arrays in arrays, #[a, #[b, c], ...],
> etc.
>  
> Cheers!
>  
> Tom Hawker
> --------------------------
> Senior Framework Developer
> --------------------------
> Home    +1 (408) 274-4128
> Office  +1 (408) 576-6591
> Mobile  +1 (408) 835-3643
>  
>  
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On
> Behalf Of Valloud, Andres
> Sent: Tuesday, June 30, 2009 12:48 AM
> To: [hidden email]
> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
> fixincluded)
>  
> IIRC, when I first saw {...} in Squeak, the result of each
> subexpression was evaluated at compile time.  Stef, does {...} behave
> like that these days?  If so, doesn't it cause problems when the lists
> become stale?
>  
> Vassili, to borrow from the macro expansion metaphor for the sake of
> illustration only, do you mean {1. 2. 3} to be replaced like this (mod
> the fact that there are only so many with:^n selectors, etc.)?
>  
> (Array with: [1] value with: [2] value with: [3] value)
>  
> Or do you mean for objects to live inside complex compiled method
> literals?  If you mean the latter, consider the case where at first I
> make a mistake an implement:
>  
> Integer>>factorial
>  
>   self < 1 ifTrue: [^nil].
>   ^"do the calculation somehow"
>  
>  
> After implementing this method, I go ahead and write:
>  
> WhateverObject>>someFactorials
>  
>   ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>  
>  
> Then, I realize I messed up Integer>>factorial, so I correct it:
>  
> Integer>>factorial
>  
>   self < 0 ifTrue: [^nil].
>   ^"do the calculation somehow"
>  
>  
> It would seem weird to me that modifying the above method should
> trigger recompiling #someFactorials (by hand?).  To some extent, the
> problem would be that some portion of the app would be created
> imperatively as opposed to declaratively... in a way, it would be a
> special case of the more general problem of creating an arbitrary
> image from source code or from a specification.  On the other hand, if
> the "expansion" executed code to create the list from scratch each
> time {...} is encountered, then the problem would go away.
>  
>  
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On
> Behalf Of Vassili Bykov
> Sent: Tuesday, June 30, 2009 12:17 AM
> To: [hidden email]
> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
> fixincluded)
>  
> I would be satisfied with anything that (1) satisfies the spec and (2)
> is practically viable. Given those two, I don't care how it's
> implemented. Discussing an equivalent macro expansion is only useful
> to clarify the semantics but not the motivation (though your expansion
> doesn't work for the general case).
>  
> The motivation here, to make it reasonably general, is allowing
> lexically nested named contexts to represent nested entities of the
> model. For example:
>  
> row: {
>     prefix.
>     column: {
>         header.
>         row: {item1. item2. item3. item4. item5. item6. item7}.
>         row: {item8. item9}.
>         footer.
>     }.
>     suffix.
> }
>  
> One can come up with other schemes to encode such things, but nothing
> with as little extraneous gunk as in this. (This is a real example of
> a Hopscotch presenter definition).
>  
> --Vassili
>  
> On Mon, Jun 29, 2009 at 6:05 PM, Andres
> Valloud<[hidden email]> wrote:
> > So, if braces were taken care of by a macro preprocessor that replaced
> >
> > {1. 2. 3.}
> >
> > with
> >
> > (Array with: (1) with: (2) with: (3))
> >
> > would you be satisfied as far as the results go?  Is this just a
> > matter of keyboard shorthand?  If so, why does it need to be in the
> > syntax of the language?
> >
> >
> > Vassili Bykov wrote:
> >> It's all in the language spec, and your criticism assumes a
> >> suboptimal spec. The spec should say that a brace expression
> >> evaluates to an object that conforms to an immutable list protocol.
> >> Not an Array or any other specific class. It should also state that
> >> it is unspecified whether or not results of multiple evaluations can
> >> be identical or otherwise share their structure.
> >>
> >> What this achieves is:
> >>
> >> 1) It shifts the focus from the implementation to the interface. The
> >> point of having braces is syntactically cheap list specification, not
> >> syntactically cheap Array creation. The divide is easily and safely
> >> crossed if the immutable list protocol includes a message like
> >> #asArray to produce a mutable Array.
> >>
> >> 2) Immutability requires no AI in the compiler, while the compiler is
> >> free to optimize deeply immutable lists to literals. Or not.
> >>
> >> 3) The code is safe because immutability is on and has to be
> >> explicitly turned off and not vice versa.
> >>
> >> --Vassili
> >>
> >>
> >> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
> >>
> >>> Vassili,
> >>>
> >>> From a language theory point of view, I must disagree that literal
> arrays are "warts".  They epresent constants defined at compile time
> with immutable values and state.  This is /not/ true of any
> constructed list, and almost all modern languages recognize this.
> >>>
> >>> It is also incorrect to assume that the compiler can determine
> immutability on its own.  Consider this case (using GS/S syntax):
> >>>
> >>>        #{ 5  6 )
> >>>        #[ 5, 6 ]
> >>>
> >>> Here the first one is a literal array that is marked immutable
> (invariant), while the second is a constructed array that is /not/
> immutable.  While it is true that both arrays can be statically
> constructed by the compiler, the reference semantics are quite
> different.  In the former case the array and its individual members
> are immutable and all references are shared (identity semantics);  in
> the latter the members may or may not be immutable and at least all
> top-most references must be copies (equality semantics).  This gets
> even more complicated or obvious with embedded constructs:
> >>>
> >>>        #( 5  #( 7  8 )  6 )
> >>>        #[ 5, #[ 7, 8 ], 6 ]
> >>>
> >>> A compiler cannot /intuit/ that either one should be invariant; it
> must be defined by the language specification, which is why you need
> two separate representations.  Making them /more/ similar in syntax is
> perhaps desirable.  For example, I would be perfectly happy with:
> >>>
> >>>         #( 5. 6 )
> >>>        ##( 5. 6 )
> >>>
> >>> [choose your favorite syntax], where the former only permits
> literals while the latter permits arbitrary expressions.  Using
> periods should be optional for the former, but would be required for
> the latter to prevent ambiguity with unary message sends.
> >>>
> >>> Eliminating the case of the literal form actually will make code
> unsafe and less unreadable because you must explicitly recursively
> mark the result as immutable - something we'll all forget to do.
> >>>
> >>> Cheers!
> >>>
> >>> Tom Hawker
> >>> --------------------------
> >>> Senior Framework Developer
> >>> --------------------------
> >>> Home    +1 (408) 274-4128
> >>> Office  +1 (408) 576-6591
> >>> Mobile  +1 (408) 835-3643
> >>>
> >>> -----Original Message-----
> >>> From: [hidden email] [mailto:[hidden email]] On
> >>> Behalf Of Vassili Bykov
> >>> Sent: Monday, June 29, 2009 3:22 PM
> >>> To: vwnc
> >>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
> >>> fix included)
> >>>
> >>> To clarify a few points:
> >>>
> >>> Literals have nothing to do with this. "{expr1. expr2}" is
> >>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
> with: expr 1 with:
> >>> expr2)".
> >>>
> >>> Speed has nothing to do with this. The motivation is to provide a
> >>> usable syntax for specifying lists of things, without the random
> >>> limitations of literal array syntax. This is immensely useful in
> >>> embedded DSLs, for example. Let me put it bluntly: classic Smalltalk
> >>> got it wrong, literal arrays are a wart. Something like the braces,
> >>> with arbitrary expressions inside, should have been the default and
> >>> *the only* way to specify arrays. It should be up to the compiler to
> >>> optimize array expressions with constant elements to (read-only)
> >>> literals. (But speaking of raw speed, the VW version of braces
> >>> doesn't create arrays by talking to the Array class, it uses the
> >>> ConsArray bytecode).
> >>>
> >>> Redundancy, as in "we already have Array with:", has nothing to do
> >>> with this. By the same logic nil, true, and false as
> >>> pseudo-variables should have been unnecessary. They could have been
> >>> implemented instead as "UndefinedObject default", "True default"
> and "False default."
> >>>
> >>> Thank you, David, for looking after this.
> >>>
> >>> --Vassili
> >>> _______________________________________________
> >>> vwnc mailing list
> >>> [hidden email]
> >>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> >>>
> >>> IMPORTANT NOTICE
> >>> Email from OOCL is confidential and may be legally privileged.  If
> >>> it is not intended for you, please delete it immediately unread.  
> >>> The internet cannot guarantee that this communication is free of
> >>> viruses, interception or interference and anyone who communicates
> >>> with us by email is taken to accept the risks in doing so.  Without
> >>> limitation, OOCL and its affiliates accept no liability whatsoever
> >>> and howsoever arising in connection with the use of this email.  
> >>> Under no circumstances shall this email constitute a binding
> >>> agreement to carry or for provision of carriage services by OOCL,
> >>> which is subject to the availability of carrier's equipment and
> >>> vessels and the terms and conditions of OOCL's standard bill of
> lading which is also available at http://www.oocl.com.
> >>>
> >>>
> >>
> >> _______________________________________________
> >> vwnc mailing list
> >> [hidden email]
> >> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> >> .
> >>
> >>
> > _______________________________________________
> > vwnc mailing list
> > [hidden email]
> > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> >
>  
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>  
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>  
> IMPORTANT NOTICE
> Email from OOCL is confidential and may be legally privileged.  If it is not
> intended for you, please delete it immediately unread.  The internet
> cannot guarantee that this communication is free of viruses, interception
> or interference and anyone who communicates with us by email is taken
> to accept the risks in doing so.  Without limitation, OOCL and its affiliates
> accept no liability whatsoever and howsoever arising in connection with
> the use of this email.  Under no circumstances shall this email constitute
> a binding agreement to carry or for provision of carriage services by OOCL,
> which is subject to the availability of carrier's equipment and vessels and
> the terms and conditions of OOCL's standard bill of lading which is also
> available at http://www.oocl.com.
>
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Vassili Bykov-2
In reply to this post by Andres Valloud-6
On Tue, Jun 30, 2009 at 12:48 AM, Valloud, Andres<[hidden email]> wrote:
> Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
>
> (Array with: [1] value with: [2] value with: [3] value)

No, your original expansion proposal was in fact OK as an illustration
for this particular example. I said it was wrong for the general case
because the real expansion scheme should be

((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN); beImmutable)

However a real implementation should ideally be cheaper than this.


>
> Or do you mean for objects to live inside complex compiled method literals?  If you mean the latter, consider the case where at first I make a mistake an implement:
>
> Integer>>factorial
>
>  self < 1 ifTrue: [^nil].
>  ^"do the calculation somehow"
>
>
> After implementing this method, I go ahead and write:
>
> WhateverObject>>someFactorials
>
>  ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>
>
> Then, I realize I messed up Integer>>factorial, so I correct it:
>
> Integer>>factorial
>
>  self < 0 ifTrue: [^nil].
>  ^"do the calculation somehow"
>
>
> It would seem weird to me that modifying the above method should trigger recompiling #someFactorials (by hand?).  To some extent, the problem would be that some portion of the app would be created imperatively as opposed to declaratively... in a way, it would be a special case of the more general problem of creating an arbitrary image from source code or from a specification.  On the other hand, if the "expansion" executed code to create the list from scratch each time {...} is encountered, then the problem would go away.
>
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Vassili Bykov
> Sent: Tuesday, June 30, 2009 12:17 AM
> To: [hidden email]
> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
>
> I would be satisfied with anything that (1) satisfies the spec and (2) is practically viable. Given those two, I don't care how it's implemented. Discussing an equivalent macro expansion is only useful to clarify the semantics but not the motivation (though your expansion doesn't work for the general case).
>
> The motivation here, to make it reasonably general, is allowing lexically nested named contexts to represent nested entities of the model. For example:
>
> row: {
>    prefix.
>    column: {
>        header.
>        row: {item1. item2. item3. item4. item5. item6. item7}.
>        row: {item8. item9}.
>        footer.
>    }.
>    suffix.
> }
>
> One can come up with other schemes to encode such things, but nothing with as little extraneous gunk as in this. (This is a real example of a Hopscotch presenter definition).
>
> --Vassili
>
> On Mon, Jun 29, 2009 at 6:05 PM, Andres
> Valloud<[hidden email]> wrote:
>> So, if braces were taken care of by a macro preprocessor that replaced
>>
>> {1. 2. 3.}
>>
>> with
>>
>> (Array with: (1) with: (2) with: (3))
>>
>> would you be satisfied as far as the results go?  Is this just a
>> matter of keyboard shorthand?  If so, why does it need to be in the
>> syntax of the language?
>>
>>
>> Vassili Bykov wrote:
>>> It's all in the language spec, and your criticism assumes a
>>> suboptimal spec. The spec should say that a brace expression
>>> evaluates to an object that conforms to an immutable list protocol.
>>> Not an Array or any other specific class. It should also state that
>>> it is unspecified whether or not results of multiple evaluations can
>>> be identical or otherwise share their structure.
>>>
>>> What this achieves is:
>>>
>>> 1) It shifts the focus from the implementation to the interface. The
>>> point of having braces is syntactically cheap list specification, not
>>> syntactically cheap Array creation. The divide is easily and safely
>>> crossed if the immutable list protocol includes a message like
>>> #asArray to produce a mutable Array.
>>>
>>> 2) Immutability requires no AI in the compiler, while the compiler is
>>> free to optimize deeply immutable lists to literals. Or not.
>>>
>>> 3) The code is safe because immutability is on and has to be
>>> explicitly turned off and not vice versa.
>>>
>>> --Vassili
>>>
>>>
>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>
>>>> Vassili,
>>>>
>>>> From a language theory point of view, I must disagree that literal arrays are "warts".  They epresent constants defined at compile time with immutable values and state.  This is /not/ true of any constructed list, and almost all modern languages recognize this.
>>>>
>>>> It is also incorrect to assume that the compiler can determine immutability on its own.  Consider this case (using GS/S syntax):
>>>>
>>>>        #{ 5  6 )
>>>>        #[ 5, 6 ]
>>>>
>>>> Here the first one is a literal array that is marked immutable (invariant), while the second is a constructed array that is /not/ immutable.  While it is true that both arrays can be statically constructed by the compiler, the reference semantics are quite different.  In the former case the array and its individual members are immutable and all references are shared (identity semantics);  in the latter the members may or may not be immutable and at least all top-most references must be copies (equality semantics).  This gets even more complicated or obvious with embedded constructs:
>>>>
>>>>        #( 5  #( 7  8 )  6 )
>>>>        #[ 5, #[ 7, 8 ], 6 ]
>>>>
>>>> A compiler cannot /intuit/ that either one should be invariant; it must be defined by the language specification, which is why you need two separate representations.  Making them /more/ similar in syntax is perhaps desirable.  For example, I would be perfectly happy with:
>>>>
>>>>         #( 5. 6 )
>>>>        ##( 5. 6 )
>>>>
>>>> [choose your favorite syntax], where the former only permits literals while the latter permits arbitrary expressions.  Using periods should be optional for the former, but would be required for the latter to prevent ambiguity with unary message sends.
>>>>
>>>> Eliminating the case of the literal form actually will make code unsafe and less unreadable because you must explicitly recursively mark the result as immutable - something we'll all forget to do.
>>>>
>>>> Cheers!
>>>>
>>>> Tom Hawker
>>>> --------------------------
>>>> Senior Framework Developer
>>>> --------------------------
>>>> Home    +1 (408) 274-4128
>>>> Office  +1 (408) 576-6591
>>>> Mobile  +1 (408) 835-3643
>>>>
>>>> -----Original Message-----
>>>> From: [hidden email] [mailto:[hidden email]] On
>>>> Behalf Of Vassili Bykov
>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>> To: vwnc
>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
>>>> fix included)
>>>>
>>>> To clarify a few points:
>>>>
>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array with: expr 1 with:
>>>> expr2)".
>>>>
>>>> Speed has nothing to do with this. The motivation is to provide a
>>>> usable syntax for specifying lists of things, without the random
>>>> limitations of literal array syntax. This is immensely useful in
>>>> embedded DSLs, for example. Let me put it bluntly: classic Smalltalk
>>>> got it wrong, literal arrays are a wart. Something like the braces,
>>>> with arbitrary expressions inside, should have been the default and
>>>> *the only* way to specify arrays. It should be up to the compiler to
>>>> optimize array expressions with constant elements to (read-only)
>>>> literals. (But speaking of raw speed, the VW version of braces
>>>> doesn't create arrays by talking to the Array class, it uses the
>>>> ConsArray bytecode).
>>>>
>>>> Redundancy, as in "we already have Array with:", has nothing to do
>>>> with this. By the same logic nil, true, and false as
>>>> pseudo-variables should have been unnecessary. They could have been
>>>> implemented instead as "UndefinedObject default", "True default" and "False default."
>>>>
>>>> Thank you, David, for looking after this.
>>>>
>>>> --Vassili
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>> IMPORTANT NOTICE
>>>> Email from OOCL is confidential and may be legally privileged.  If
>>>> it is not intended for you, please delete it immediately unread.
>>>> The internet cannot guarantee that this communication is free of
>>>> viruses, interception or interference and anyone who communicates
>>>> with us by email is taken to accept the risks in doing so.  Without
>>>> limitation, OOCL and its affiliates accept no liability whatsoever
>>>> and howsoever arising in connection with the use of this email.
>>>> Under no circumstances shall this email constitute a binding
>>>> agreement to carry or for provision of carriage services by OOCL,
>>>> which is subject to the availability of carrier's equipment and
>>>> vessels and the terms and conditions of OOCL's standard bill of lading which is also available at http://www.oocl.com.
>>>>
>>>>
>>>
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>> .
>>>
>>>
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Andres Valloud-4
Mod implementation details, which we are all well capable of figuring
out, I do see the motivation for {...}.  However, I am not sure it's a
good idea.  Right now, it feels too much like a C struct and, to me,
these reek a bit too much of flattened data and little semantic
meaning.  But, it's a feeling.  I'll think about it for a week or so,
and then I'll have a better idea.

Vassili Bykov wrote:

> On Tue, Jun 30, 2009 at 12:48 AM, Valloud, Andres<[hidden email]> wrote:
>  
>> Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
>>
>> (Array with: [1] value with: [2] value with: [3] value)
>>    
>
> No, your original expansion proposal was in fact OK as an illustration
> for this particular example. I said it was wrong for the general case
> because the real expansion scheme should be
>
> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN); beImmutable)
>
> However a real implementation should ideally be cheaper than this.
>
>
>  
>> Or do you mean for objects to live inside complex compiled method literals?  If you mean the latter, consider the case where at first I make a mistake an implement:
>>
>> Integer>>factorial
>>
>>  self < 1 ifTrue: [^nil].
>>  ^"do the calculation somehow"
>>
>>
>> After implementing this method, I go ahead and write:
>>
>> WhateverObject>>someFactorials
>>
>>  ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>
>>
>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>
>> Integer>>factorial
>>
>>  self < 0 ifTrue: [^nil].
>>  ^"do the calculation somehow"
>>
>>
>> It would seem weird to me that modifying the above method should trigger recompiling #someFactorials (by hand?).  To some extent, the problem would be that some portion of the app would be created imperatively as opposed to declaratively... in a way, it would be a special case of the more general problem of creating an arbitrary image from source code or from a specification.  On the other hand, if the "expansion" executed code to create the list from scratch each time {...} is encountered, then the problem would go away.
>>
>>
>> -----Original Message-----
>> From: [hidden email] [mailto:[hidden email]] On Behalf Of Vassili Bykov
>> Sent: Tuesday, June 30, 2009 12:17 AM
>> To: [hidden email]
>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
>>
>> I would be satisfied with anything that (1) satisfies the spec and (2) is practically viable. Given those two, I don't care how it's implemented. Discussing an equivalent macro expansion is only useful to clarify the semantics but not the motivation (though your expansion doesn't work for the general case).
>>
>> The motivation here, to make it reasonably general, is allowing lexically nested named contexts to represent nested entities of the model. For example:
>>
>> row: {
>>    prefix.
>>    column: {
>>        header.
>>        row: {item1. item2. item3. item4. item5. item6. item7}.
>>        row: {item8. item9}.
>>        footer.
>>    }.
>>    suffix.
>> }
>>
>> One can come up with other schemes to encode such things, but nothing with as little extraneous gunk as in this. (This is a real example of a Hopscotch presenter definition).
>>
>> --Vassili
>>
>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>> Valloud<[hidden email]> wrote:
>>    
>>> So, if braces were taken care of by a macro preprocessor that replaced
>>>
>>> {1. 2. 3.}
>>>
>>> with
>>>
>>> (Array with: (1) with: (2) with: (3))
>>>
>>> would you be satisfied as far as the results go?  Is this just a
>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>> syntax of the language?
>>>
>>>
>>> Vassili Bykov wrote:
>>>      
>>>> It's all in the language spec, and your criticism assumes a
>>>> suboptimal spec. The spec should say that a brace expression
>>>> evaluates to an object that conforms to an immutable list protocol.
>>>> Not an Array or any other specific class. It should also state that
>>>> it is unspecified whether or not results of multiple evaluations can
>>>> be identical or otherwise share their structure.
>>>>
>>>> What this achieves is:
>>>>
>>>> 1) It shifts the focus from the implementation to the interface. The
>>>> point of having braces is syntactically cheap list specification, not
>>>> syntactically cheap Array creation. The divide is easily and safely
>>>> crossed if the immutable list protocol includes a message like
>>>> #asArray to produce a mutable Array.
>>>>
>>>> 2) Immutability requires no AI in the compiler, while the compiler is
>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>
>>>> 3) The code is safe because immutability is on and has to be
>>>> explicitly turned off and not vice versa.
>>>>
>>>> --Vassili
>>>>
>>>>
>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>
>>>>        
>>>>> Vassili,
>>>>>
>>>>> From a language theory point of view, I must disagree that literal arrays are "warts".  They epresent constants defined at compile time with immutable values and state.  This is /not/ true of any constructed list, and almost all modern languages recognize this.
>>>>>
>>>>> It is also incorrect to assume that the compiler can determine immutability on its own.  Consider this case (using GS/S syntax):
>>>>>
>>>>>        #{ 5  6 )
>>>>>        #[ 5, 6 ]
>>>>>
>>>>> Here the first one is a literal array that is marked immutable (invariant), while the second is a constructed array that is /not/ immutable.  While it is true that both arrays can be statically constructed by the compiler, the reference semantics are quite different.  In the former case the array and its individual members are immutable and all references are shared (identity semantics);  in the latter the members may or may not be immutable and at least all top-most references must be copies (equality semantics).  This gets even more complicated or obvious with embedded constructs:
>>>>>
>>>>>        #( 5  #( 7  8 )  6 )
>>>>>        #[ 5, #[ 7, 8 ], 6 ]
>>>>>
>>>>> A compiler cannot /intuit/ that either one should be invariant; it must be defined by the language specification, which is why you need two separate representations.  Making them /more/ similar in syntax is perhaps desirable.  For example, I would be perfectly happy with:
>>>>>
>>>>>         #( 5. 6 )
>>>>>        ##( 5. 6 )
>>>>>
>>>>> [choose your favorite syntax], where the former only permits literals while the latter permits arbitrary expressions.  Using periods should be optional for the former, but would be required for the latter to prevent ambiguity with unary message sends.
>>>>>
>>>>> Eliminating the case of the literal form actually will make code unsafe and less unreadable because you must explicitly recursively mark the result as immutable - something we'll all forget to do.
>>>>>
>>>>> Cheers!
>>>>>
>>>>> Tom Hawker
>>>>> --------------------------
>>>>> Senior Framework Developer
>>>>> --------------------------
>>>>> Home    +1 (408) 274-4128
>>>>> Office  +1 (408) 576-6591
>>>>> Mobile  +1 (408) 835-3643
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]] On
>>>>> Behalf Of Vassili Bykov
>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>> To: vwnc
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative
>>>>> fix included)
>>>>>
>>>>> To clarify a few points:
>>>>>
>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array with: expr 1 with:
>>>>> expr2)".
>>>>>
>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>> usable syntax for specifying lists of things, without the random
>>>>> limitations of literal array syntax. This is immensely useful in
>>>>> embedded DSLs, for example. Let me put it bluntly: classic Smalltalk
>>>>> got it wrong, literal arrays are a wart. Something like the braces,
>>>>> with arbitrary expressions inside, should have been the default and
>>>>> *the only* way to specify arrays. It should be up to the compiler to
>>>>> optimize array expressions with constant elements to (read-only)
>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>> ConsArray bytecode).
>>>>>
>>>>> Redundancy, as in "we already have Array with:", has nothing to do
>>>>> with this. By the same logic nil, true, and false as
>>>>> pseudo-variables should have been unnecessary. They could have been
>>>>> implemented instead as "UndefinedObject default", "True default" and "False default."
>>>>>
>>>>> Thank you, David, for looking after this.
>>>>>
>>>>> --Vassili
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> IMPORTANT NOTICE
>>>>> Email from OOCL is confidential and may be legally privileged.  If
>>>>> it is not intended for you, please delete it immediately unread.
>>>>> The internet cannot guarantee that this communication is free of
>>>>> viruses, interception or interference and anyone who communicates
>>>>> with us by email is taken to accept the risks in doing so.  Without
>>>>> limitation, OOCL and its affiliates accept no liability whatsoever
>>>>> and howsoever arising in connection with the use of this email.
>>>>> Under no circumstances shall this email constitute a binding
>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>> which is subject to the availability of carrier's equipment and
>>>>> vessels and the terms and conditions of OOCL's standard bill of lading which is also available at http://www.oocl.com.
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>
>>    
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Stéphane Ducasse
I understand what you mean!!!!
I got the same concerns.  Clearly you are afraid that if you give to  
people an easy
  array creation they will not produce object but arrays. It was the  
case in Squeak before {}
You have a lot of code with first second ...fifth....yeah pretty cool.
Now you should consider that { } is still cool because it is compact  
and dynamic.
In fact { } is much more smalltalkish than #() which is so parse time  
boring.

Stef


On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:

> Mod implementation details, which we are all well capable of figuring
> out, I do see the motivation for {...}.  However, I am not sure it's a
> good idea.  Right now, it feels too much like a C struct and, to me,
> these reek a bit too much of flattened data and little semantic
> meaning.  But, it's a feeling.  I'll think about it for a week or so,
> and then I'll have a better idea.
>
> Vassili Bykov wrote:
>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,  
>> Andres<[hidden email]> wrote:
>>
>>> Vassili, to borrow from the macro expansion metaphor for the sake  
>>> of illustration only, do you mean {1. 2. 3} to be replaced like  
>>> this (mod the fact that there are only so many with:^n selectors,  
>>> etc.)?
>>>
>>> (Array with: [1] value with: [2] value with: [3] value)
>>>
>>
>> No, your original expansion proposal was in fact OK as an  
>> illustration
>> for this particular example. I said it was wrong for the general case
>> because the real expansion scheme should be
>>
>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);  
>> beImmutable)
>>
>> However a real implementation should ideally be cheaper than this.
>>
>>
>>
>>> Or do you mean for objects to live inside complex compiled method  
>>> literals?  If you mean the latter, consider the case where at  
>>> first I make a mistake an implement:
>>>
>>> Integer>>factorial
>>>
>>> self < 1 ifTrue: [^nil].
>>> ^"do the calculation somehow"
>>>
>>>
>>> After implementing this method, I go ahead and write:
>>>
>>> WhateverObject>>someFactorials
>>>
>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>
>>>
>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>
>>> Integer>>factorial
>>>
>>> self < 0 ifTrue: [^nil].
>>> ^"do the calculation somehow"
>>>
>>>
>>> It would seem weird to me that modifying the above method should  
>>> trigger recompiling #someFactorials (by hand?).  To some extent,  
>>> the problem would be that some portion of the app would be created  
>>> imperatively as opposed to declaratively... in a way, it would be  
>>> a special case of the more general problem of creating an  
>>> arbitrary image from source code or from a specification.  On the  
>>> other hand, if the "expansion" executed code to create the list  
>>> from scratch each time {...} is encountered, then the problem  
>>> would go away.
>>>
>>>
>>> -----Original Message-----
>>> From: [hidden email] [mailto:[hidden email]]  
>>> On Behalf Of Vassili Bykov
>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>> To: [hidden email]
>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings  
>>> (tentative fixincluded)
>>>
>>> I would be satisfied with anything that (1) satisfies the spec and  
>>> (2) is practically viable. Given those two, I don't care how it's  
>>> implemented. Discussing an equivalent macro expansion is only  
>>> useful to clarify the semantics but not the motivation (though  
>>> your expansion doesn't work for the general case).
>>>
>>> The motivation here, to make it reasonably general, is allowing  
>>> lexically nested named contexts to represent nested entities of  
>>> the model. For example:
>>>
>>> row: {
>>>   prefix.
>>>   column: {
>>>       header.
>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>       row: {item8. item9}.
>>>       footer.
>>>   }.
>>>   suffix.
>>> }
>>>
>>> One can come up with other schemes to encode such things, but  
>>> nothing with as little extraneous gunk as in this. (This is a real  
>>> example of a Hopscotch presenter definition).
>>>
>>> --Vassili
>>>
>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>> Valloud<[hidden email]> wrote:
>>>
>>>> So, if braces were taken care of by a macro preprocessor that  
>>>> replaced
>>>>
>>>> {1. 2. 3.}
>>>>
>>>> with
>>>>
>>>> (Array with: (1) with: (2) with: (3))
>>>>
>>>> would you be satisfied as far as the results go?  Is this just a
>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>> syntax of the language?
>>>>
>>>>
>>>> Vassili Bykov wrote:
>>>>
>>>>> It's all in the language spec, and your criticism assumes a
>>>>> suboptimal spec. The spec should say that a brace expression
>>>>> evaluates to an object that conforms to an immutable list  
>>>>> protocol.
>>>>> Not an Array or any other specific class. It should also state  
>>>>> that
>>>>> it is unspecified whether or not results of multiple evaluations  
>>>>> can
>>>>> be identical or otherwise share their structure.
>>>>>
>>>>> What this achieves is:
>>>>>
>>>>> 1) It shifts the focus from the implementation to the interface.  
>>>>> The
>>>>> point of having braces is syntactically cheap list  
>>>>> specification, not
>>>>> syntactically cheap Array creation. The divide is easily and  
>>>>> safely
>>>>> crossed if the immutable list protocol includes a message like
>>>>> #asArray to produce a mutable Array.
>>>>>
>>>>> 2) Immutability requires no AI in the compiler, while the  
>>>>> compiler is
>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>
>>>>> 3) The code is safe because immutability is on and has to be
>>>>> explicitly turned off and not vice versa.
>>>>>
>>>>> --Vassili
>>>>>
>>>>>
>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>
>>>>>
>>>>>> Vassili,
>>>>>>
>>>>>> From a language theory point of view, I must disagree that  
>>>>>> literal arrays are "warts".  They epresent constants defined at  
>>>>>> compile time with immutable values and state.  This is /not/  
>>>>>> true of any constructed list, and almost all modern languages  
>>>>>> recognize this.
>>>>>>
>>>>>> It is also incorrect to assume that the compiler can determine  
>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>
>>>>>>       #{ 5  6 )
>>>>>>       #[ 5, 6 ]
>>>>>>
>>>>>> Here the first one is a literal array that is marked immutable  
>>>>>> (invariant), while the second is a constructed array that is /
>>>>>> not/ immutable.  While it is true that both arrays can be  
>>>>>> statically constructed by the compiler, the reference semantics  
>>>>>> are quite different.  In the former case the array and its  
>>>>>> individual members are immutable and all references are shared  
>>>>>> (identity semantics);  in the latter the members may or may not  
>>>>>> be immutable and at least all top-most references must be  
>>>>>> copies (equality semantics).  This gets even more complicated  
>>>>>> or obvious with embedded constructs:
>>>>>>
>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>
>>>>>> A compiler cannot /intuit/ that either one should be invariant;  
>>>>>> it must be defined by the language specification, which is why  
>>>>>> you need two separate representations.  Making them /more/  
>>>>>> similar in syntax is perhaps desirable.  For example, I would  
>>>>>> be perfectly happy with:
>>>>>>
>>>>>>        #( 5. 6 )
>>>>>>       ##( 5. 6 )
>>>>>>
>>>>>> [choose your favorite syntax], where the former only permits  
>>>>>> literals while the latter permits arbitrary expressions.  Using  
>>>>>> periods should be optional for the former, but would be  
>>>>>> required for the latter to prevent ambiguity with unary message  
>>>>>> sends.
>>>>>>
>>>>>> Eliminating the case of the literal form actually will make  
>>>>>> code unsafe and less unreadable because you must explicitly  
>>>>>> recursively mark the result as immutable - something we'll all  
>>>>>> forget to do.
>>>>>>
>>>>>> Cheers!
>>>>>>
>>>>>> Tom Hawker
>>>>>> --------------------------
>>>>>> Senior Framework Developer
>>>>>> --------------------------
>>>>>> Home    +1 (408) 274-4128
>>>>>> Office  +1 (408) 576-6591
>>>>>> Mobile  +1 (408) 835-3643
>>>>>>
>>>>>> -----Original Message-----
>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>> [hidden email]] On
>>>>>> Behalf Of Vassili Bykov
>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>> To: vwnc
>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings  
>>>>>> (tentative
>>>>>> fix included)
>>>>>>
>>>>>> To clarify a few points:
>>>>>>
>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array  
>>>>>> with: expr 1 with:
>>>>>> expr2)".
>>>>>>
>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>> usable syntax for specifying lists of things, without the random
>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>> embedded DSLs, for example. Let me put it bluntly: classic  
>>>>>> Smalltalk
>>>>>> got it wrong, literal arrays are a wart. Something like the  
>>>>>> braces,
>>>>>> with arbitrary expressions inside, should have been the default  
>>>>>> and
>>>>>> *the only* way to specify arrays. It should be up to the  
>>>>>> compiler to
>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>> ConsArray bytecode).
>>>>>>
>>>>>> Redundancy, as in "we already have Array with:", has nothing to  
>>>>>> do
>>>>>> with this. By the same logic nil, true, and false as
>>>>>> pseudo-variables should have been unnecessary. They could have  
>>>>>> been
>>>>>> implemented instead as "UndefinedObject default", "True  
>>>>>> default" and "False default."
>>>>>>
>>>>>> Thank you, David, for looking after this.
>>>>>>
>>>>>> --Vassili
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>> IMPORTANT NOTICE
>>>>>> Email from OOCL is confidential and may be legally privileged.  
>>>>>> If
>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>> The internet cannot guarantee that this communication is free of
>>>>>> viruses, interception or interference and anyone who communicates
>>>>>> with us by email is taken to accept the risks in doing so.  
>>>>>> Without
>>>>>> limitation, OOCL and its affiliates accept no liability  
>>>>>> whatsoever
>>>>>> and howsoever arising in connection with the use of this email.
>>>>>> Under no circumstances shall this email constitute a binding
>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>> which is subject to the availability of carrier's equipment and
>>>>>> vessels and the terms and conditions of OOCL's standard bill of  
>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>
>>>>>>
>>>>>>
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>> .
>>>>>
>>>>>
>>>>>
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>>
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>
>>
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Andres Valloud-4
Stef,

Well, I wouldn't say that {...} enables what we have seen daily over the
years :)... the feeling I get, and it's just a feeling right now, is
that the convenience will detract from domain object design.  In other
words, if it's too convenient to use {...} and write stuff in terms of
lists, then how much does the convenience affect how objects are
structured so that they fit a POV where everything is a list?  And it's
not that "everything is a list" doesn't work, either.  But...

Andres.


Stéphane Ducasse wrote:

> I understand what you mean!!!!
> I got the same concerns.  Clearly you are afraid that if you give to
> people an easy
>   array creation they will not produce object but arrays. It was the
> case in Squeak before {}
> You have a lot of code with first second ...fifth....yeah pretty cool.
> Now you should consider that { } is still cool because it is compact
> and dynamic.
> In fact { } is much more smalltalkish than #() which is so parse time
> boring.
>
> Stef
>
>
> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>
>  
>> Mod implementation details, which we are all well capable of figuring
>> out, I do see the motivation for {...}.  However, I am not sure it's a
>> good idea.  Right now, it feels too much like a C struct and, to me,
>> these reek a bit too much of flattened data and little semantic
>> meaning.  But, it's a feeling.  I'll think about it for a week or so,
>> and then I'll have a better idea.
>>
>> Vassili Bykov wrote:
>>    
>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>> Andres<[hidden email]> wrote:
>>>
>>>      
>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>> this (mod the fact that there are only so many with:^n selectors,
>>>> etc.)?
>>>>
>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>
>>>>        
>>> No, your original expansion proposal was in fact OK as an
>>> illustration
>>> for this particular example. I said it was wrong for the general case
>>> because the real expansion scheme should be
>>>
>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>> beImmutable)
>>>
>>> However a real implementation should ideally be cheaper than this.
>>>
>>>
>>>
>>>      
>>>> Or do you mean for objects to live inside complex compiled method
>>>> literals?  If you mean the latter, consider the case where at
>>>> first I make a mistake an implement:
>>>>
>>>> Integer>>factorial
>>>>
>>>> self < 1 ifTrue: [^nil].
>>>> ^"do the calculation somehow"
>>>>
>>>>
>>>> After implementing this method, I go ahead and write:
>>>>
>>>> WhateverObject>>someFactorials
>>>>
>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>
>>>>
>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>
>>>> Integer>>factorial
>>>>
>>>> self < 0 ifTrue: [^nil].
>>>> ^"do the calculation somehow"
>>>>
>>>>
>>>> It would seem weird to me that modifying the above method should
>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>> the problem would be that some portion of the app would be created
>>>> imperatively as opposed to declaratively... in a way, it would be
>>>> a special case of the more general problem of creating an
>>>> arbitrary image from source code or from a specification.  On the
>>>> other hand, if the "expansion" executed code to create the list
>>>> from scratch each time {...} is encountered, then the problem
>>>> would go away.
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: [hidden email] [mailto:[hidden email]]
>>>> On Behalf Of Vassili Bykov
>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>> To: [hidden email]
>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>> (tentative fixincluded)
>>>>
>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>> (2) is practically viable. Given those two, I don't care how it's
>>>> implemented. Discussing an equivalent macro expansion is only
>>>> useful to clarify the semantics but not the motivation (though
>>>> your expansion doesn't work for the general case).
>>>>
>>>> The motivation here, to make it reasonably general, is allowing
>>>> lexically nested named contexts to represent nested entities of
>>>> the model. For example:
>>>>
>>>> row: {
>>>>   prefix.
>>>>   column: {
>>>>       header.
>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>       row: {item8. item9}.
>>>>       footer.
>>>>   }.
>>>>   suffix.
>>>> }
>>>>
>>>> One can come up with other schemes to encode such things, but
>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>> example of a Hopscotch presenter definition).
>>>>
>>>> --Vassili
>>>>
>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>> Valloud<[hidden email]> wrote:
>>>>
>>>>        
>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>> replaced
>>>>>
>>>>> {1. 2. 3.}
>>>>>
>>>>> with
>>>>>
>>>>> (Array with: (1) with: (2) with: (3))
>>>>>
>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>>> syntax of the language?
>>>>>
>>>>>
>>>>> Vassili Bykov wrote:
>>>>>
>>>>>          
>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>> evaluates to an object that conforms to an immutable list
>>>>>> protocol.
>>>>>> Not an Array or any other specific class. It should also state
>>>>>> that
>>>>>> it is unspecified whether or not results of multiple evaluations
>>>>>> can
>>>>>> be identical or otherwise share their structure.
>>>>>>
>>>>>> What this achieves is:
>>>>>>
>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>> The
>>>>>> point of having braces is syntactically cheap list
>>>>>> specification, not
>>>>>> syntactically cheap Array creation. The divide is easily and
>>>>>> safely
>>>>>> crossed if the immutable list protocol includes a message like
>>>>>> #asArray to produce a mutable Array.
>>>>>>
>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>> compiler is
>>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>>
>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>> explicitly turned off and not vice versa.
>>>>>>
>>>>>> --Vassili
>>>>>>
>>>>>>
>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> Vassili,
>>>>>>>
>>>>>>> From a language theory point of view, I must disagree that
>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>> recognize this.
>>>>>>>
>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>
>>>>>>>       #{ 5  6 )
>>>>>>>       #[ 5, 6 ]
>>>>>>>
>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>> are quite different.  In the former case the array and its
>>>>>>> individual members are immutable and all references are shared
>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>> be immutable and at least all top-most references must be
>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>> or obvious with embedded constructs:
>>>>>>>
>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>
>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>> it must be defined by the language specification, which is why
>>>>>>> you need two separate representations.  Making them /more/
>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>> be perfectly happy with:
>>>>>>>
>>>>>>>        #( 5. 6 )
>>>>>>>       ##( 5. 6 )
>>>>>>>
>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>> periods should be optional for the former, but would be
>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>> sends.
>>>>>>>
>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>> forget to do.
>>>>>>>
>>>>>>> Cheers!
>>>>>>>
>>>>>>> Tom Hawker
>>>>>>> --------------------------
>>>>>>> Senior Framework Developer
>>>>>>> --------------------------
>>>>>>> Home    +1 (408) 274-4128
>>>>>>> Office  +1 (408) 576-6591
>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>> [hidden email]] On
>>>>>>> Behalf Of Vassili Bykov
>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>> To: vwnc
>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>> (tentative
>>>>>>> fix included)
>>>>>>>
>>>>>>> To clarify a few points:
>>>>>>>
>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>> with: expr 1 with:
>>>>>>> expr2)".
>>>>>>>
>>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>>> usable syntax for specifying lists of things, without the random
>>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>>>> Smalltalk
>>>>>>> got it wrong, literal arrays are a wart. Something like the
>>>>>>> braces,
>>>>>>> with arbitrary expressions inside, should have been the default
>>>>>>> and
>>>>>>> *the only* way to specify arrays. It should be up to the
>>>>>>> compiler to
>>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>>> ConsArray bytecode).
>>>>>>>
>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>> do
>>>>>>> with this. By the same logic nil, true, and false as
>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>> been
>>>>>>> implemented instead as "UndefinedObject default", "True
>>>>>>> default" and "False default."
>>>>>>>
>>>>>>> Thank you, David, for looking after this.
>>>>>>>
>>>>>>> --Vassili
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>
>>>>>>> IMPORTANT NOTICE
>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>> If
>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>> The internet cannot guarantee that this communication is free of
>>>>>>> viruses, interception or interference and anyone who communicates
>>>>>>> with us by email is taken to accept the risks in doing so.
>>>>>>> Without
>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>> whatsoever
>>>>>>> and howsoever arising in connection with the use of this email.
>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>>> which is subject to the availability of carrier's equipment and
>>>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>> .
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>> .
>>>
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>    
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)

Boris Popov, DeepCove Labs (SNN)
Andres,

I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.

Dialog
        choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
        labels:
                (Array
                        with: #Yes << #dialogs >> 'Yes'
                        with: #No << #dialogs >> 'No'
                        with: #Cancel << #dialogs >> 'Cancel')
        values: #(#saveThenQuit #exit #cancel)
        default: #saveThenQuit

Dialog
        choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
        labels: {#Yes << #dialogs >> 'Yes'.
                   #No << #dialogs >> 'No'.
                   #Cancel << #dialogs >> 'Cancel'}
        values: #(#saveThenQuit #exit #cancel)
        default: #saveThenQuit

-Boris

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
Sent: Tuesday, June 30, 2009 3:12 PM
To: Visualworks Mailing List
Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)

Stef,

Well, I wouldn't say that {...} enables what we have seen daily over the
years :)... the feeling I get, and it's just a feeling right now, is
that the convenience will detract from domain object design.  In other
words, if it's too convenient to use {...} and write stuff in terms of
lists, then how much does the convenience affect how objects are
structured so that they fit a POV where everything is a list?  And it's
not that "everything is a list" doesn't work, either.  But...

Andres.


Stéphane Ducasse wrote:

> I understand what you mean!!!!
> I got the same concerns.  Clearly you are afraid that if you give to
> people an easy
>   array creation they will not produce object but arrays. It was the
> case in Squeak before {}
> You have a lot of code with first second ...fifth....yeah pretty cool.
> Now you should consider that { } is still cool because it is compact
> and dynamic.
> In fact { } is much more smalltalkish than #() which is so parse time
> boring.
>
> Stef
>
>
> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>
>  
>> Mod implementation details, which we are all well capable of figuring
>> out, I do see the motivation for {...}.  However, I am not sure it's a
>> good idea.  Right now, it feels too much like a C struct and, to me,
>> these reek a bit too much of flattened data and little semantic
>> meaning.  But, it's a feeling.  I'll think about it for a week or so,
>> and then I'll have a better idea.
>>
>> Vassili Bykov wrote:
>>    
>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>> Andres<[hidden email]> wrote:
>>>
>>>      
>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>> this (mod the fact that there are only so many with:^n selectors,
>>>> etc.)?
>>>>
>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>
>>>>        
>>> No, your original expansion proposal was in fact OK as an
>>> illustration
>>> for this particular example. I said it was wrong for the general case
>>> because the real expansion scheme should be
>>>
>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>> beImmutable)
>>>
>>> However a real implementation should ideally be cheaper than this.
>>>
>>>
>>>
>>>      
>>>> Or do you mean for objects to live inside complex compiled method
>>>> literals?  If you mean the latter, consider the case where at
>>>> first I make a mistake an implement:
>>>>
>>>> Integer>>factorial
>>>>
>>>> self < 1 ifTrue: [^nil].
>>>> ^"do the calculation somehow"
>>>>
>>>>
>>>> After implementing this method, I go ahead and write:
>>>>
>>>> WhateverObject>>someFactorials
>>>>
>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>
>>>>
>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>
>>>> Integer>>factorial
>>>>
>>>> self < 0 ifTrue: [^nil].
>>>> ^"do the calculation somehow"
>>>>
>>>>
>>>> It would seem weird to me that modifying the above method should
>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>> the problem would be that some portion of the app would be created
>>>> imperatively as opposed to declaratively... in a way, it would be
>>>> a special case of the more general problem of creating an
>>>> arbitrary image from source code or from a specification.  On the
>>>> other hand, if the "expansion" executed code to create the list
>>>> from scratch each time {...} is encountered, then the problem
>>>> would go away.
>>>>
>>>>
>>>> -----Original Message-----
>>>> From: [hidden email] [mailto:[hidden email]]
>>>> On Behalf Of Vassili Bykov
>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>> To: [hidden email]
>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>> (tentative fixincluded)
>>>>
>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>> (2) is practically viable. Given those two, I don't care how it's
>>>> implemented. Discussing an equivalent macro expansion is only
>>>> useful to clarify the semantics but not the motivation (though
>>>> your expansion doesn't work for the general case).
>>>>
>>>> The motivation here, to make it reasonably general, is allowing
>>>> lexically nested named contexts to represent nested entities of
>>>> the model. For example:
>>>>
>>>> row: {
>>>>   prefix.
>>>>   column: {
>>>>       header.
>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>       row: {item8. item9}.
>>>>       footer.
>>>>   }.
>>>>   suffix.
>>>> }
>>>>
>>>> One can come up with other schemes to encode such things, but
>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>> example of a Hopscotch presenter definition).
>>>>
>>>> --Vassili
>>>>
>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>> Valloud<[hidden email]> wrote:
>>>>
>>>>        
>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>> replaced
>>>>>
>>>>> {1. 2. 3.}
>>>>>
>>>>> with
>>>>>
>>>>> (Array with: (1) with: (2) with: (3))
>>>>>
>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>>> syntax of the language?
>>>>>
>>>>>
>>>>> Vassili Bykov wrote:
>>>>>
>>>>>          
>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>> evaluates to an object that conforms to an immutable list
>>>>>> protocol.
>>>>>> Not an Array or any other specific class. It should also state
>>>>>> that
>>>>>> it is unspecified whether or not results of multiple evaluations
>>>>>> can
>>>>>> be identical or otherwise share their structure.
>>>>>>
>>>>>> What this achieves is:
>>>>>>
>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>> The
>>>>>> point of having braces is syntactically cheap list
>>>>>> specification, not
>>>>>> syntactically cheap Array creation. The divide is easily and
>>>>>> safely
>>>>>> crossed if the immutable list protocol includes a message like
>>>>>> #asArray to produce a mutable Array.
>>>>>>
>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>> compiler is
>>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>>
>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>> explicitly turned off and not vice versa.
>>>>>>
>>>>>> --Vassili
>>>>>>
>>>>>>
>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> Vassili,
>>>>>>>
>>>>>>> From a language theory point of view, I must disagree that
>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>> recognize this.
>>>>>>>
>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>
>>>>>>>       #{ 5  6 )
>>>>>>>       #[ 5, 6 ]
>>>>>>>
>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>> are quite different.  In the former case the array and its
>>>>>>> individual members are immutable and all references are shared
>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>> be immutable and at least all top-most references must be
>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>> or obvious with embedded constructs:
>>>>>>>
>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>
>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>> it must be defined by the language specification, which is why
>>>>>>> you need two separate representations.  Making them /more/
>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>> be perfectly happy with:
>>>>>>>
>>>>>>>        #( 5. 6 )
>>>>>>>       ##( 5. 6 )
>>>>>>>
>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>> periods should be optional for the former, but would be
>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>> sends.
>>>>>>>
>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>> forget to do.
>>>>>>>
>>>>>>> Cheers!
>>>>>>>
>>>>>>> Tom Hawker
>>>>>>> --------------------------
>>>>>>> Senior Framework Developer
>>>>>>> --------------------------
>>>>>>> Home    +1 (408) 274-4128
>>>>>>> Office  +1 (408) 576-6591
>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>
>>>>>>> -----Original Message-----
>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>> [hidden email]] On
>>>>>>> Behalf Of Vassili Bykov
>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>> To: vwnc
>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>> (tentative
>>>>>>> fix included)
>>>>>>>
>>>>>>> To clarify a few points:
>>>>>>>
>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>> with: expr 1 with:
>>>>>>> expr2)".
>>>>>>>
>>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>>> usable syntax for specifying lists of things, without the random
>>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>>>> Smalltalk
>>>>>>> got it wrong, literal arrays are a wart. Something like the
>>>>>>> braces,
>>>>>>> with arbitrary expressions inside, should have been the default
>>>>>>> and
>>>>>>> *the only* way to specify arrays. It should be up to the
>>>>>>> compiler to
>>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>>> ConsArray bytecode).
>>>>>>>
>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>> do
>>>>>>> with this. By the same logic nil, true, and false as
>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>> been
>>>>>>> implemented instead as "UndefinedObject default", "True
>>>>>>> default" and "False default."
>>>>>>>
>>>>>>> Thank you, David, for looking after this.
>>>>>>>
>>>>>>> --Vassili
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>
>>>>>>> IMPORTANT NOTICE
>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>> If
>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>> The internet cannot guarantee that this communication is free of
>>>>>>> viruses, interception or interference and anyone who communicates
>>>>>>> with us by email is taken to accept the risks in doing so.
>>>>>>> Without
>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>> whatsoever
>>>>>>> and howsoever arising in connection with the use of this email.
>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>>> which is subject to the availability of carrier's equipment and
>>>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>> .
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>> .
>>>
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>    
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)

Andres Valloud-4
While we are at it, why does the below code need two parallel lists
instead of

Dialog
  choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before
exiting?'
  from: {
    #Yes << #dialogs >> 'Yes' => #saveThenQuit.
    #No << #dialogs >> 'No' => #exit.
    #Cancel << #dialogs >> 'Cancel' => #cancel}
  default: #saveThenQuit

And maybe the default answer could be encoded in a different =>
selector, and then we can get rid of #default: too...

Oh well.

Andres.

Boris Popov wrote:

> Andres,
>
> I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels:
>                 (Array
>                         with: #Yes << #dialogs >> 'Yes'
>                         with: #No << #dialogs >> 'No'
>                         with: #Cancel << #dialogs >> 'Cancel')
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels: {#Yes << #dialogs >> 'Yes'.
>                    #No << #dialogs >> 'No'.
>                    #Cancel << #dialogs >> 'Cancel'}
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> -Boris
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
> Sent: Tuesday, June 30, 2009 3:12 PM
> To: Visualworks Mailing List
> Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)
>
> Stef,
>
> Well, I wouldn't say that {...} enables what we have seen daily over the
> years :)... the feeling I get, and it's just a feeling right now, is
> that the convenience will detract from domain object design.  In other
> words, if it's too convenient to use {...} and write stuff in terms of
> lists, then how much does the convenience affect how objects are
> structured so that they fit a POV where everything is a list?  And it's
> not that "everything is a list" doesn't work, either.  But...
>
> Andres.
>
>
> Stéphane Ducasse wrote:
>  
>> I understand what you mean!!!!
>> I got the same concerns.  Clearly you are afraid that if you give to
>> people an easy
>>   array creation they will not produce object but arrays. It was the
>> case in Squeak before {}
>> You have a lot of code with first second ...fifth....yeah pretty cool.
>> Now you should consider that { } is still cool because it is compact
>> and dynamic.
>> In fact { } is much more smalltalkish than #() which is so parse time
>> boring.
>>
>> Stef
>>
>>
>> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>>
>>
>>    
>>> Mod implementation details, which we are all well capable of figuring
>>> out, I do see the motivation for {...}.  However, I am not sure it's a
>>> good idea.  Right now, it feels too much like a C struct and, to me,
>>> these reek a bit too much of flattened data and little semantic
>>> meaning.  But, it's a feeling.  I'll think about it for a week or so,
>>> and then I'll have a better idea.
>>>
>>> Vassili Bykov wrote:
>>>
>>>      
>>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>>> Andres<[hidden email]> wrote:
>>>>
>>>>
>>>>        
>>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>>> this (mod the fact that there are only so many with:^n selectors,
>>>>> etc.)?
>>>>>
>>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>>
>>>>>
>>>>>          
>>>> No, your original expansion proposal was in fact OK as an
>>>> illustration
>>>> for this particular example. I said it was wrong for the general case
>>>> because the real expansion scheme should be
>>>>
>>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>>> beImmutable)
>>>>
>>>> However a real implementation should ideally be cheaper than this.
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>> Or do you mean for objects to live inside complex compiled method
>>>>> literals?  If you mean the latter, consider the case where at
>>>>> first I make a mistake an implement:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 1 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> After implementing this method, I go ahead and write:
>>>>>
>>>>> WhateverObject>>someFactorials
>>>>>
>>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>>
>>>>>
>>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 0 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> It would seem weird to me that modifying the above method should
>>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>>> the problem would be that some portion of the app would be created
>>>>> imperatively as opposed to declaratively... in a way, it would be
>>>>> a special case of the more general problem of creating an
>>>>> arbitrary image from source code or from a specification.  On the
>>>>> other hand, if the "expansion" executed code to create the list
>>>>> from scratch each time {...} is encountered, then the problem
>>>>> would go away.
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]]
>>>>> On Behalf Of Vassili Bykov
>>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>>> To: [hidden email]
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>> (tentative fixincluded)
>>>>>
>>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>>> (2) is practically viable. Given those two, I don't care how it's
>>>>> implemented. Discussing an equivalent macro expansion is only
>>>>> useful to clarify the semantics but not the motivation (though
>>>>> your expansion doesn't work for the general case).
>>>>>
>>>>> The motivation here, to make it reasonably general, is allowing
>>>>> lexically nested named contexts to represent nested entities of
>>>>> the model. For example:
>>>>>
>>>>> row: {
>>>>>   prefix.
>>>>>   column: {
>>>>>       header.
>>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>>       row: {item8. item9}.
>>>>>       footer.
>>>>>   }.
>>>>>   suffix.
>>>>> }
>>>>>
>>>>> One can come up with other schemes to encode such things, but
>>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>>> example of a Hopscotch presenter definition).
>>>>>
>>>>> --Vassili
>>>>>
>>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>>> Valloud<[hidden email]> wrote:
>>>>>
>>>>>
>>>>>          
>>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>>> replaced
>>>>>>
>>>>>> {1. 2. 3.}
>>>>>>
>>>>>> with
>>>>>>
>>>>>> (Array with: (1) with: (2) with: (3))
>>>>>>
>>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>>>> syntax of the language?
>>>>>>
>>>>>>
>>>>>> Vassili Bykov wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>>> evaluates to an object that conforms to an immutable list
>>>>>>> protocol.
>>>>>>> Not an Array or any other specific class. It should also state
>>>>>>> that
>>>>>>> it is unspecified whether or not results of multiple evaluations
>>>>>>> can
>>>>>>> be identical or otherwise share their structure.
>>>>>>>
>>>>>>> What this achieves is:
>>>>>>>
>>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>>> The
>>>>>>> point of having braces is syntactically cheap list
>>>>>>> specification, not
>>>>>>> syntactically cheap Array creation. The divide is easily and
>>>>>>> safely
>>>>>>> crossed if the immutable list protocol includes a message like
>>>>>>> #asArray to produce a mutable Array.
>>>>>>>
>>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>>> compiler is
>>>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>>>
>>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>>> explicitly turned off and not vice versa.
>>>>>>>
>>>>>>> --Vassili
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>>>> Vassili,
>>>>>>>>
>>>>>>>> From a language theory point of view, I must disagree that
>>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>>> recognize this.
>>>>>>>>
>>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>>
>>>>>>>>       #{ 5  6 )
>>>>>>>>       #[ 5, 6 ]
>>>>>>>>
>>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>>> are quite different.  In the former case the array and its
>>>>>>>> individual members are immutable and all references are shared
>>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>>> be immutable and at least all top-most references must be
>>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>>> or obvious with embedded constructs:
>>>>>>>>
>>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>>
>>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>>> it must be defined by the language specification, which is why
>>>>>>>> you need two separate representations.  Making them /more/
>>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>>> be perfectly happy with:
>>>>>>>>
>>>>>>>>        #( 5. 6 )
>>>>>>>>       ##( 5. 6 )
>>>>>>>>
>>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>>> periods should be optional for the former, but would be
>>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>>> sends.
>>>>>>>>
>>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>>> forget to do.
>>>>>>>>
>>>>>>>> Cheers!
>>>>>>>>
>>>>>>>> Tom Hawker
>>>>>>>> --------------------------
>>>>>>>> Senior Framework Developer
>>>>>>>> --------------------------
>>>>>>>> Home    +1 (408) 274-4128
>>>>>>>> Office  +1 (408) 576-6591
>>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>>> [hidden email]] On
>>>>>>>> Behalf Of Vassili Bykov
>>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>>> To: vwnc
>>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>>> (tentative
>>>>>>>> fix included)
>>>>>>>>
>>>>>>>> To clarify a few points:
>>>>>>>>
>>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>>> with: expr 1 with:
>>>>>>>> expr2)".
>>>>>>>>
>>>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>>>> usable syntax for specifying lists of things, without the random
>>>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>>>>> Smalltalk
>>>>>>>> got it wrong, literal arrays are a wart. Something like the
>>>>>>>> braces,
>>>>>>>> with arbitrary expressions inside, should have been the default
>>>>>>>> and
>>>>>>>> *the only* way to specify arrays. It should be up to the
>>>>>>>> compiler to
>>>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>>>> ConsArray bytecode).
>>>>>>>>
>>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>>> do
>>>>>>>> with this. By the same logic nil, true, and false as
>>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>>> been
>>>>>>>> implemented instead as "UndefinedObject default", "True
>>>>>>>> default" and "False default."
>>>>>>>>
>>>>>>>> Thank you, David, for looking after this.
>>>>>>>>
>>>>>>>> --Vassili
>>>>>>>> _______________________________________________
>>>>>>>> vwnc mailing list
>>>>>>>> [hidden email]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>>
>>>>>>>> IMPORTANT NOTICE
>>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>>> If
>>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>>> The internet cannot guarantee that this communication is free of
>>>>>>>> viruses, interception or interference and anyone who communicates
>>>>>>>> with us by email is taken to accept the risks in doing so.
>>>>>>>> Without
>>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>>> whatsoever
>>>>>>>> and howsoever arising in connection with the use of this email.
>>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>>>> which is subject to the availability of carrier's equipment and
>>>>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>> .
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
>>    
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)

Andres Valloud-4
In reply to this post by Boris Popov, DeepCove Labs (SNN)
A constructive argument could be:

* Binary selectors for concatenation such as the comma message are
convenient, but there's priority issues because what happens when you
want to concatenate keyword message expressions... you get unwanted
parentheses, and that's not so convenient anymore.

* In addition, not all concatenation binary messages work on every
object.  The "good" ones such as comma or -> are already used.

* Therefore, instead of adopting a universal concatenation binary
message and deal with the above problems, just provide a way to create
lists with a minimum of syntax and obviate the need for list
construction by concatenation in the first place.

{...} feels better to me now.

Andres.


Boris Popov wrote:

> Andres,
>
> I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels:
>                 (Array
>                         with: #Yes << #dialogs >> 'Yes'
>                         with: #No << #dialogs >> 'No'
>                         with: #Cancel << #dialogs >> 'Cancel')
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels: {#Yes << #dialogs >> 'Yes'.
>                    #No << #dialogs >> 'No'.
>                    #Cancel << #dialogs >> 'Cancel'}
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> -Boris
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
> Sent: Tuesday, June 30, 2009 3:12 PM
> To: Visualworks Mailing List
> Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)
>
> Stef,
>
> Well, I wouldn't say that {...} enables what we have seen daily over the
> years :)... the feeling I get, and it's just a feeling right now, is
> that the convenience will detract from domain object design.  In other
> words, if it's too convenient to use {...} and write stuff in terms of
> lists, then how much does the convenience affect how objects are
> structured so that they fit a POV where everything is a list?  And it's
> not that "everything is a list" doesn't work, either.  But...
>
> Andres.
>
>
> Stéphane Ducasse wrote:
>  
>> I understand what you mean!!!!
>> I got the same concerns.  Clearly you are afraid that if you give to
>> people an easy
>>   array creation they will not produce object but arrays. It was the
>> case in Squeak before {}
>> You have a lot of code with first second ...fifth....yeah pretty cool.
>> Now you should consider that { } is still cool because it is compact
>> and dynamic.
>> In fact { } is much more smalltalkish than #() which is so parse time
>> boring.
>>
>> Stef
>>
>>
>> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>>
>>
>>    
>>> Mod implementation details, which we are all well capable of figuring
>>> out, I do see the motivation for {...}.  However, I am not sure it's a
>>> good idea.  Right now, it feels too much like a C struct and, to me,
>>> these reek a bit too much of flattened data and little semantic
>>> meaning.  But, it's a feeling.  I'll think about it for a week or so,
>>> and then I'll have a better idea.
>>>
>>> Vassili Bykov wrote:
>>>
>>>      
>>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>>> Andres<[hidden email]> wrote:
>>>>
>>>>
>>>>        
>>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>>> this (mod the fact that there are only so many with:^n selectors,
>>>>> etc.)?
>>>>>
>>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>>
>>>>>
>>>>>          
>>>> No, your original expansion proposal was in fact OK as an
>>>> illustration
>>>> for this particular example. I said it was wrong for the general case
>>>> because the real expansion scheme should be
>>>>
>>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>>> beImmutable)
>>>>
>>>> However a real implementation should ideally be cheaper than this.
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>> Or do you mean for objects to live inside complex compiled method
>>>>> literals?  If you mean the latter, consider the case where at
>>>>> first I make a mistake an implement:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 1 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> After implementing this method, I go ahead and write:
>>>>>
>>>>> WhateverObject>>someFactorials
>>>>>
>>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>>
>>>>>
>>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 0 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> It would seem weird to me that modifying the above method should
>>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>>> the problem would be that some portion of the app would be created
>>>>> imperatively as opposed to declaratively... in a way, it would be
>>>>> a special case of the more general problem of creating an
>>>>> arbitrary image from source code or from a specification.  On the
>>>>> other hand, if the "expansion" executed code to create the list
>>>>> from scratch each time {...} is encountered, then the problem
>>>>> would go away.
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]]
>>>>> On Behalf Of Vassili Bykov
>>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>>> To: [hidden email]
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>> (tentative fixincluded)
>>>>>
>>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>>> (2) is practically viable. Given those two, I don't care how it's
>>>>> implemented. Discussing an equivalent macro expansion is only
>>>>> useful to clarify the semantics but not the motivation (though
>>>>> your expansion doesn't work for the general case).
>>>>>
>>>>> The motivation here, to make it reasonably general, is allowing
>>>>> lexically nested named contexts to represent nested entities of
>>>>> the model. For example:
>>>>>
>>>>> row: {
>>>>>   prefix.
>>>>>   column: {
>>>>>       header.
>>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>>       row: {item8. item9}.
>>>>>       footer.
>>>>>   }.
>>>>>   suffix.
>>>>> }
>>>>>
>>>>> One can come up with other schemes to encode such things, but
>>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>>> example of a Hopscotch presenter definition).
>>>>>
>>>>> --Vassili
>>>>>
>>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>>> Valloud<[hidden email]> wrote:
>>>>>
>>>>>
>>>>>          
>>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>>> replaced
>>>>>>
>>>>>> {1. 2. 3.}
>>>>>>
>>>>>> with
>>>>>>
>>>>>> (Array with: (1) with: (2) with: (3))
>>>>>>
>>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>>>> syntax of the language?
>>>>>>
>>>>>>
>>>>>> Vassili Bykov wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>>> evaluates to an object that conforms to an immutable list
>>>>>>> protocol.
>>>>>>> Not an Array or any other specific class. It should also state
>>>>>>> that
>>>>>>> it is unspecified whether or not results of multiple evaluations
>>>>>>> can
>>>>>>> be identical or otherwise share their structure.
>>>>>>>
>>>>>>> What this achieves is:
>>>>>>>
>>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>>> The
>>>>>>> point of having braces is syntactically cheap list
>>>>>>> specification, not
>>>>>>> syntactically cheap Array creation. The divide is easily and
>>>>>>> safely
>>>>>>> crossed if the immutable list protocol includes a message like
>>>>>>> #asArray to produce a mutable Array.
>>>>>>>
>>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>>> compiler is
>>>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>>>
>>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>>> explicitly turned off and not vice versa.
>>>>>>>
>>>>>>> --Vassili
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>>>> Vassili,
>>>>>>>>
>>>>>>>> From a language theory point of view, I must disagree that
>>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>>> recognize this.
>>>>>>>>
>>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>>
>>>>>>>>       #{ 5  6 )
>>>>>>>>       #[ 5, 6 ]
>>>>>>>>
>>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>>> are quite different.  In the former case the array and its
>>>>>>>> individual members are immutable and all references are shared
>>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>>> be immutable and at least all top-most references must be
>>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>>> or obvious with embedded constructs:
>>>>>>>>
>>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>>
>>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>>> it must be defined by the language specification, which is why
>>>>>>>> you need two separate representations.  Making them /more/
>>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>>> be perfectly happy with:
>>>>>>>>
>>>>>>>>        #( 5. 6 )
>>>>>>>>       ##( 5. 6 )
>>>>>>>>
>>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>>> periods should be optional for the former, but would be
>>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>>> sends.
>>>>>>>>
>>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>>> forget to do.
>>>>>>>>
>>>>>>>> Cheers!
>>>>>>>>
>>>>>>>> Tom Hawker
>>>>>>>> --------------------------
>>>>>>>> Senior Framework Developer
>>>>>>>> --------------------------
>>>>>>>> Home    +1 (408) 274-4128
>>>>>>>> Office  +1 (408) 576-6591
>>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>>> [hidden email]] On
>>>>>>>> Behalf Of Vassili Bykov
>>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>>> To: vwnc
>>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>>> (tentative
>>>>>>>> fix included)
>>>>>>>>
>>>>>>>> To clarify a few points:
>>>>>>>>
>>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>>> with: expr 1 with:
>>>>>>>> expr2)".
>>>>>>>>
>>>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>>>> usable syntax for specifying lists of things, without the random
>>>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>>>>> Smalltalk
>>>>>>>> got it wrong, literal arrays are a wart. Something like the
>>>>>>>> braces,
>>>>>>>> with arbitrary expressions inside, should have been the default
>>>>>>>> and
>>>>>>>> *the only* way to specify arrays. It should be up to the
>>>>>>>> compiler to
>>>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>>>> ConsArray bytecode).
>>>>>>>>
>>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>>> do
>>>>>>>> with this. By the same logic nil, true, and false as
>>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>>> been
>>>>>>>> implemented instead as "UndefinedObject default", "True
>>>>>>>> default" and "False default."
>>>>>>>>
>>>>>>>> Thank you, David, for looking after this.
>>>>>>>>
>>>>>>>> --Vassili
>>>>>>>> _______________________________________________
>>>>>>>> vwnc mailing list
>>>>>>>> [hidden email]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>>
>>>>>>>> IMPORTANT NOTICE
>>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>>> If
>>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>>> The internet cannot guarantee that this communication is free of
>>>>>>>> viruses, interception or interference and anyone who communicates
>>>>>>>> with us by email is taken to accept the risks in doing so.
>>>>>>>> Without
>>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>>> whatsoever
>>>>>>>> and howsoever arising in connection with the use of this email.
>>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>>>> which is subject to the availability of carrier's equipment and
>>>>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>> .
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
>>    
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)

Boris Popov, DeepCove Labs (SNN)
In reply to this post by Andres Valloud-4
... and why use symbols then?

Dialog
  choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
  from: {
    #Yes << #dialogs >> 'Yes' ==> [self snapshotThenQuit].
    #No << #dialogs >> 'No' => [self warnThenQuit].
    #Cancel << #dialogs >> 'Cancel' => nil}

-Boris

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
Sent: Tuesday, June 30, 2009 3:36 PM
To: Visualworks Mailing List
Subject: Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)

While we are at it, why does the below code need two parallel lists
instead of

Dialog
  choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before
exiting?'
  from: {
    #Yes << #dialogs >> 'Yes' => #saveThenQuit.
    #No << #dialogs >> 'No' => #exit.
    #Cancel << #dialogs >> 'Cancel' => #cancel}
  default: #saveThenQuit

And maybe the default answer could be encoded in a different =>
selector, and then we can get rid of #default: too...

Oh well.

Andres.

Boris Popov wrote:

> Andres,
>
> I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels:
>                 (Array
>                         with: #Yes << #dialogs >> 'Yes'
>                         with: #No << #dialogs >> 'No'
>                         with: #Cancel << #dialogs >> 'Cancel')
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels: {#Yes << #dialogs >> 'Yes'.
>                    #No << #dialogs >> 'No'.
>                    #Cancel << #dialogs >> 'Cancel'}
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> -Boris
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
> Sent: Tuesday, June 30, 2009 3:12 PM
> To: Visualworks Mailing List
> Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)
>
> Stef,
>
> Well, I wouldn't say that {...} enables what we have seen daily over the
> years :)... the feeling I get, and it's just a feeling right now, is
> that the convenience will detract from domain object design.  In other
> words, if it's too convenient to use {...} and write stuff in terms of
> lists, then how much does the convenience affect how objects are
> structured so that they fit a POV where everything is a list?  And it's
> not that "everything is a list" doesn't work, either.  But...
>
> Andres.
>
>
> Stéphane Ducasse wrote:
>  
>> I understand what you mean!!!!
>> I got the same concerns.  Clearly you are afraid that if you give to
>> people an easy
>>   array creation they will not produce object but arrays. It was the
>> case in Squeak before {}
>> You have a lot of code with first second ...fifth....yeah pretty cool.
>> Now you should consider that { } is still cool because it is compact
>> and dynamic.
>> In fact { } is much more smalltalkish than #() which is so parse time
>> boring.
>>
>> Stef
>>
>>
>> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>>
>>
>>    
>>> Mod implementation details, which we are all well capable of figuring
>>> out, I do see the motivation for {...}.  However, I am not sure it's a
>>> good idea.  Right now, it feels too much like a C struct and, to me,
>>> these reek a bit too much of flattened data and little semantic
>>> meaning.  But, it's a feeling.  I'll think about it for a week or so,
>>> and then I'll have a better idea.
>>>
>>> Vassili Bykov wrote:
>>>
>>>      
>>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>>> Andres<[hidden email]> wrote:
>>>>
>>>>
>>>>        
>>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>>> this (mod the fact that there are only so many with:^n selectors,
>>>>> etc.)?
>>>>>
>>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>>
>>>>>
>>>>>          
>>>> No, your original expansion proposal was in fact OK as an
>>>> illustration
>>>> for this particular example. I said it was wrong for the general case
>>>> because the real expansion scheme should be
>>>>
>>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>>> beImmutable)
>>>>
>>>> However a real implementation should ideally be cheaper than this.
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>> Or do you mean for objects to live inside complex compiled method
>>>>> literals?  If you mean the latter, consider the case where at
>>>>> first I make a mistake an implement:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 1 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> After implementing this method, I go ahead and write:
>>>>>
>>>>> WhateverObject>>someFactorials
>>>>>
>>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>>
>>>>>
>>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 0 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> It would seem weird to me that modifying the above method should
>>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>>> the problem would be that some portion of the app would be created
>>>>> imperatively as opposed to declaratively... in a way, it would be
>>>>> a special case of the more general problem of creating an
>>>>> arbitrary image from source code or from a specification.  On the
>>>>> other hand, if the "expansion" executed code to create the list
>>>>> from scratch each time {...} is encountered, then the problem
>>>>> would go away.
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]]
>>>>> On Behalf Of Vassili Bykov
>>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>>> To: [hidden email]
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>> (tentative fixincluded)
>>>>>
>>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>>> (2) is practically viable. Given those two, I don't care how it's
>>>>> implemented. Discussing an equivalent macro expansion is only
>>>>> useful to clarify the semantics but not the motivation (though
>>>>> your expansion doesn't work for the general case).
>>>>>
>>>>> The motivation here, to make it reasonably general, is allowing
>>>>> lexically nested named contexts to represent nested entities of
>>>>> the model. For example:
>>>>>
>>>>> row: {
>>>>>   prefix.
>>>>>   column: {
>>>>>       header.
>>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>>       row: {item8. item9}.
>>>>>       footer.
>>>>>   }.
>>>>>   suffix.
>>>>> }
>>>>>
>>>>> One can come up with other schemes to encode such things, but
>>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>>> example of a Hopscotch presenter definition).
>>>>>
>>>>> --Vassili
>>>>>
>>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>>> Valloud<[hidden email]> wrote:
>>>>>
>>>>>
>>>>>          
>>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>>> replaced
>>>>>>
>>>>>> {1. 2. 3.}
>>>>>>
>>>>>> with
>>>>>>
>>>>>> (Array with: (1) with: (2) with: (3))
>>>>>>
>>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>>> matter of keyboard shorthand?  If so, why does it need to be in the
>>>>>> syntax of the language?
>>>>>>
>>>>>>
>>>>>> Vassili Bykov wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>>> evaluates to an object that conforms to an immutable list
>>>>>>> protocol.
>>>>>>> Not an Array or any other specific class. It should also state
>>>>>>> that
>>>>>>> it is unspecified whether or not results of multiple evaluations
>>>>>>> can
>>>>>>> be identical or otherwise share their structure.
>>>>>>>
>>>>>>> What this achieves is:
>>>>>>>
>>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>>> The
>>>>>>> point of having braces is syntactically cheap list
>>>>>>> specification, not
>>>>>>> syntactically cheap Array creation. The divide is easily and
>>>>>>> safely
>>>>>>> crossed if the immutable list protocol includes a message like
>>>>>>> #asArray to produce a mutable Array.
>>>>>>>
>>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>>> compiler is
>>>>>>> free to optimize deeply immutable lists to literals. Or not.
>>>>>>>
>>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>>> explicitly turned off and not vice versa.
>>>>>>>
>>>>>>> --Vassili
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>>>> Vassili,
>>>>>>>>
>>>>>>>> From a language theory point of view, I must disagree that
>>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>>> recognize this.
>>>>>>>>
>>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>>
>>>>>>>>       #{ 5  6 )
>>>>>>>>       #[ 5, 6 ]
>>>>>>>>
>>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>>> are quite different.  In the former case the array and its
>>>>>>>> individual members are immutable and all references are shared
>>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>>> be immutable and at least all top-most references must be
>>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>>> or obvious with embedded constructs:
>>>>>>>>
>>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>>
>>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>>> it must be defined by the language specification, which is why
>>>>>>>> you need two separate representations.  Making them /more/
>>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>>> be perfectly happy with:
>>>>>>>>
>>>>>>>>        #( 5. 6 )
>>>>>>>>       ##( 5. 6 )
>>>>>>>>
>>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>>> periods should be optional for the former, but would be
>>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>>> sends.
>>>>>>>>
>>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>>> forget to do.
>>>>>>>>
>>>>>>>> Cheers!
>>>>>>>>
>>>>>>>> Tom Hawker
>>>>>>>> --------------------------
>>>>>>>> Senior Framework Developer
>>>>>>>> --------------------------
>>>>>>>> Home    +1 (408) 274-4128
>>>>>>>> Office  +1 (408) 576-6591
>>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>>> [hidden email]] On
>>>>>>>> Behalf Of Vassili Bykov
>>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>>> To: vwnc
>>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>>> (tentative
>>>>>>>> fix included)
>>>>>>>>
>>>>>>>> To clarify a few points:
>>>>>>>>
>>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>>> with: expr 1 with:
>>>>>>>> expr2)".
>>>>>>>>
>>>>>>>> Speed has nothing to do with this. The motivation is to provide a
>>>>>>>> usable syntax for specifying lists of things, without the random
>>>>>>>> limitations of literal array syntax. This is immensely useful in
>>>>>>>> embedded DSLs, for example. Let me put it bluntly: classic
>>>>>>>> Smalltalk
>>>>>>>> got it wrong, literal arrays are a wart. Something like the
>>>>>>>> braces,
>>>>>>>> with arbitrary expressions inside, should have been the default
>>>>>>>> and
>>>>>>>> *the only* way to specify arrays. It should be up to the
>>>>>>>> compiler to
>>>>>>>> optimize array expressions with constant elements to (read-only)
>>>>>>>> literals. (But speaking of raw speed, the VW version of braces
>>>>>>>> doesn't create arrays by talking to the Array class, it uses the
>>>>>>>> ConsArray bytecode).
>>>>>>>>
>>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>>> do
>>>>>>>> with this. By the same logic nil, true, and false as
>>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>>> been
>>>>>>>> implemented instead as "UndefinedObject default", "True
>>>>>>>> default" and "False default."
>>>>>>>>
>>>>>>>> Thank you, David, for looking after this.
>>>>>>>>
>>>>>>>> --Vassili
>>>>>>>> _______________________________________________
>>>>>>>> vwnc mailing list
>>>>>>>> [hidden email]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>>
>>>>>>>> IMPORTANT NOTICE
>>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>>> If
>>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>>> The internet cannot guarantee that this communication is free of
>>>>>>>> viruses, interception or interference and anyone who communicates
>>>>>>>> with us by email is taken to accept the risks in doing so.
>>>>>>>> Without
>>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>>> whatsoever
>>>>>>>> and howsoever arising in connection with the use of this email.
>>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>>> agreement to carry or for provision of carriage services by OOCL,
>>>>>>>> which is subject to the availability of carrier's equipment and
>>>>>>>> vessels and the terms and conditions of OOCL's standard bill of
>>>>>>>> lading which is also available at http://www.oocl.com.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>> .
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
>>    
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)

Andres Valloud-6
Even better :).

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Boris Popov
Sent: Tuesday, June 30, 2009 3:49 PM
To: [hidden email]; Visualworks Mailing List
Subject: Re: [vwnc]BraceConstructorbreaksrefactorings (tentative fixincluded)

... and why use symbols then?

Dialog
  choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
  from: {
    #Yes << #dialogs >> 'Yes' ==> [self snapshotThenQuit].
    #No << #dialogs >> 'No' => [self warnThenQuit].
    #Cancel << #dialogs >> 'Cancel' => nil}

-Boris

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
Sent: Tuesday, June 30, 2009 3:36 PM
To: Visualworks Mailing List
Subject: Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)

While we are at it, why does the below code need two parallel lists instead of

Dialog
  choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
  from: {
    #Yes << #dialogs >> 'Yes' => #saveThenQuit.
    #No << #dialogs >> 'No' => #exit.
    #Cancel << #dialogs >> 'Cancel' => #cancel}
  default: #saveThenQuit

And maybe the default answer could be encoded in a different => selector, and then we can get rid of #default: too...

Oh well.

Andres.

Boris Popov wrote:

> Andres,
>
> I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels:
>                 (Array
>                         with: #Yes << #dialogs >> 'Yes'
>                         with: #No << #dialogs >> 'No'
>                         with: #Cancel << #dialogs >> 'Cancel')
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> Dialog
>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>         labels: {#Yes << #dialogs >> 'Yes'.
>                    #No << #dialogs >> 'No'.
>                    #Cancel << #dialogs >> 'Cancel'}
>         values: #(#saveThenQuit #exit #cancel)
>         default: #saveThenQuit
>
> -Boris
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On
> Behalf Of Andres Valloud
> Sent: Tuesday, June 30, 2009 3:12 PM
> To: Visualworks Mailing List
> Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative
> fixincluded)
>
> Stef,
>
> Well, I wouldn't say that {...} enables what we have seen daily over
> the years :)... the feeling I get, and it's just a feeling right now,
> is that the convenience will detract from domain object design.  In
> other words, if it's too convenient to use {...} and write stuff in
> terms of lists, then how much does the convenience affect how objects
> are structured so that they fit a POV where everything is a list?  And
> it's not that "everything is a list" doesn't work, either.  But...
>
> Andres.
>
>
> Stéphane Ducasse wrote:
>  
>> I understand what you mean!!!!
>> I got the same concerns.  Clearly you are afraid that if you give to
>> people an easy
>>   array creation they will not produce object but arrays. It was the
>> case in Squeak before {} You have a lot of code with first second
>> ...fifth....yeah pretty cool.
>> Now you should consider that { } is still cool because it is compact
>> and dynamic.
>> In fact { } is much more smalltalkish than #() which is so parse time
>> boring.
>>
>> Stef
>>
>>
>> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>>
>>
>>    
>>> Mod implementation details, which we are all well capable of
>>> figuring out, I do see the motivation for {...}.  However, I am not
>>> sure it's a good idea.  Right now, it feels too much like a C struct
>>> and, to me, these reek a bit too much of flattened data and little
>>> semantic meaning.  But, it's a feeling.  I'll think about it for a
>>> week or so, and then I'll have a better idea.
>>>
>>> Vassili Bykov wrote:
>>>
>>>      
>>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>>> Andres<[hidden email]> wrote:
>>>>
>>>>
>>>>        
>>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>>> this (mod the fact that there are only so many with:^n selectors,
>>>>> etc.)?
>>>>>
>>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>>
>>>>>
>>>>>          
>>>> No, your original expansion proposal was in fact OK as an
>>>> illustration for this particular example. I said it was wrong for
>>>> the general case because the real expansion scheme should be
>>>>
>>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>>> beImmutable)
>>>>
>>>> However a real implementation should ideally be cheaper than this.
>>>>
>>>>
>>>>
>>>>
>>>>        
>>>>> Or do you mean for objects to live inside complex compiled method
>>>>> literals?  If you mean the latter, consider the case where at
>>>>> first I make a mistake an implement:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 1 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> After implementing this method, I go ahead and write:
>>>>>
>>>>> WhateverObject>>someFactorials
>>>>>
>>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>>
>>>>>
>>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>>
>>>>> Integer>>factorial
>>>>>
>>>>> self < 0 ifTrue: [^nil].
>>>>> ^"do the calculation somehow"
>>>>>
>>>>>
>>>>> It would seem weird to me that modifying the above method should
>>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>>> the problem would be that some portion of the app would be created
>>>>> imperatively as opposed to declaratively... in a way, it would be
>>>>> a special case of the more general problem of creating an
>>>>> arbitrary image from source code or from a specification.  On the
>>>>> other hand, if the "expansion" executed code to create the list
>>>>> from scratch each time {...} is encountered, then the problem
>>>>> would go away.
>>>>>
>>>>>
>>>>> -----Original Message-----
>>>>> From: [hidden email] [mailto:[hidden email]]
>>>>> On Behalf Of Vassili Bykov
>>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>>> To: [hidden email]
>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>> (tentative fixincluded)
>>>>>
>>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>>> (2) is practically viable. Given those two, I don't care how it's
>>>>> implemented. Discussing an equivalent macro expansion is only
>>>>> useful to clarify the semantics but not the motivation (though
>>>>> your expansion doesn't work for the general case).
>>>>>
>>>>> The motivation here, to make it reasonably general, is allowing
>>>>> lexically nested named contexts to represent nested entities of
>>>>> the model. For example:
>>>>>
>>>>> row: {
>>>>>   prefix.
>>>>>   column: {
>>>>>       header.
>>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>>       row: {item8. item9}.
>>>>>       footer.
>>>>>   }.
>>>>>   suffix.
>>>>> }
>>>>>
>>>>> One can come up with other schemes to encode such things, but
>>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>>> example of a Hopscotch presenter definition).
>>>>>
>>>>> --Vassili
>>>>>
>>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>>> Valloud<[hidden email]> wrote:
>>>>>
>>>>>
>>>>>          
>>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>>> replaced
>>>>>>
>>>>>> {1. 2. 3.}
>>>>>>
>>>>>> with
>>>>>>
>>>>>> (Array with: (1) with: (2) with: (3))
>>>>>>
>>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>>> matter of keyboard shorthand?  If so, why does it need to be in
>>>>>> the syntax of the language?
>>>>>>
>>>>>>
>>>>>> Vassili Bykov wrote:
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>>> evaluates to an object that conforms to an immutable list
>>>>>>> protocol.
>>>>>>> Not an Array or any other specific class. It should also state
>>>>>>> that it is unspecified whether or not results of multiple
>>>>>>> evaluations can be identical or otherwise share their structure.
>>>>>>>
>>>>>>> What this achieves is:
>>>>>>>
>>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>>> The
>>>>>>> point of having braces is syntactically cheap list
>>>>>>> specification, not syntactically cheap Array creation. The
>>>>>>> divide is easily and safely crossed if the immutable list
>>>>>>> protocol includes a message like #asArray to produce a mutable
>>>>>>> Array.
>>>>>>>
>>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>>> compiler is free to optimize deeply immutable lists to literals.
>>>>>>> Or not.
>>>>>>>
>>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>>> explicitly turned off and not vice versa.
>>>>>>>
>>>>>>> --Vassili
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>>>> Vassili,
>>>>>>>>
>>>>>>>> From a language theory point of view, I must disagree that
>>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>>> recognize this.
>>>>>>>>
>>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>>
>>>>>>>>       #{ 5  6 )
>>>>>>>>       #[ 5, 6 ]
>>>>>>>>
>>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>>> are quite different.  In the former case the array and its
>>>>>>>> individual members are immutable and all references are shared
>>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>>> be immutable and at least all top-most references must be
>>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>>> or obvious with embedded constructs:
>>>>>>>>
>>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>>
>>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>>> it must be defined by the language specification, which is why
>>>>>>>> you need two separate representations.  Making them /more/
>>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>>> be perfectly happy with:
>>>>>>>>
>>>>>>>>        #( 5. 6 )
>>>>>>>>       ##( 5. 6 )
>>>>>>>>
>>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>>> periods should be optional for the former, but would be
>>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>>> sends.
>>>>>>>>
>>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>>> forget to do.
>>>>>>>>
>>>>>>>> Cheers!
>>>>>>>>
>>>>>>>> Tom Hawker
>>>>>>>> --------------------------
>>>>>>>> Senior Framework Developer
>>>>>>>> --------------------------
>>>>>>>> Home    +1 (408) 274-4128
>>>>>>>> Office  +1 (408) 576-6591
>>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>>
>>>>>>>> -----Original Message-----
>>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>>> [hidden email]] On Behalf Of Vassili Bykov
>>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>>> To: vwnc
>>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>>> (tentative fix included)
>>>>>>>>
>>>>>>>> To clarify a few points:
>>>>>>>>
>>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>>> with: expr 1 with:
>>>>>>>> expr2)".
>>>>>>>>
>>>>>>>> Speed has nothing to do with this. The motivation is to provide
>>>>>>>> a usable syntax for specifying lists of things, without the
>>>>>>>> random limitations of literal array syntax. This is immensely
>>>>>>>> useful in embedded DSLs, for example. Let me put it bluntly:
>>>>>>>> classic Smalltalk got it wrong, literal arrays are a wart.
>>>>>>>> Something like the braces, with arbitrary expressions inside,
>>>>>>>> should have been the default and *the only* way to specify
>>>>>>>> arrays. It should be up to the compiler to optimize array
>>>>>>>> expressions with constant elements to (read-only) literals.
>>>>>>>> (But speaking of raw speed, the VW version of braces doesn't
>>>>>>>> create arrays by talking to the Array class, it uses the
>>>>>>>> ConsArray bytecode).
>>>>>>>>
>>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>>> do with this. By the same logic nil, true, and false as
>>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>>> been implemented instead as "UndefinedObject default", "True
>>>>>>>> default" and "False default."
>>>>>>>>
>>>>>>>> Thank you, David, for looking after this.
>>>>>>>>
>>>>>>>> --Vassili
>>>>>>>> _______________________________________________
>>>>>>>> vwnc mailing list
>>>>>>>> [hidden email]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>>
>>>>>>>> IMPORTANT NOTICE
>>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>>> If
>>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>>> The internet cannot guarantee that this communication is free
>>>>>>>> of viruses, interception or interference and anyone who
>>>>>>>> communicates with us by email is taken to accept the risks in doing so.
>>>>>>>> Without
>>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>>> whatsoever and howsoever arising in connection with the use of
>>>>>>>> this email.
>>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>>> agreement to carry or for provision of carriage services by
>>>>>>>> OOCL, which is subject to the availability of carrier's
>>>>>>>> equipment and vessels and the terms and conditions of OOCL's
>>>>>>>> standard bill of lading which is also available at http://www.oocl.com.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>> .
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>> .
>>>>
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
>>    
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)

Andres Valloud-4
Now we just need a brave soul to write some RB rewrite rules...

Valloud, Andres wrote:

> Even better :).
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Boris Popov
> Sent: Tuesday, June 30, 2009 3:49 PM
> To: [hidden email]; Visualworks Mailing List
> Subject: Re: [vwnc]BraceConstructorbreaksrefactorings (tentative fixincluded)
>
> ... and why use symbols then?
>
> Dialog
>   choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>   from: {
>     #Yes << #dialogs >> 'Yes' ==> [self snapshotThenQuit].
>     #No << #dialogs >> 'No' => [self warnThenQuit].
>     #Cancel << #dialogs >> 'Cancel' => nil}
>
> -Boris
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Andres Valloud
> Sent: Tuesday, June 30, 2009 3:36 PM
> To: Visualworks Mailing List
> Subject: Re: [vwnc] BraceConstructorbreaksrefactorings (tentative fixincluded)
>
> While we are at it, why does the below code need two parallel lists instead of
>
> Dialog
>   choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>   from: {
>     #Yes << #dialogs >> 'Yes' => #saveThenQuit.
>     #No << #dialogs >> 'No' => #exit.
>     #Cancel << #dialogs >> 'Cancel' => #cancel}
>   default: #saveThenQuit
>
> And maybe the default answer could be encoded in a different => selector, and then we can get rid of #default: too...
>
> Oh well.
>
> Andres.
>
> Boris Popov wrote:
>  
>> Andres,
>>
>> I certainly see the angle you're presenting, but there are plenty of cases already where lists are natural API elements and simpler, more concise expression might go some way toward improving readability without really encouraging list abuse that you're referring to.
>>
>> Dialog
>>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>>         labels:
>>                 (Array
>>                         with: #Yes << #dialogs >> 'Yes'
>>                         with: #No << #dialogs >> 'No'
>>                         with: #Cancel << #dialogs >> 'Cancel')
>>         values: #(#saveThenQuit #exit #cancel)
>>         default: #saveThenQuit
>>
>> Dialog
>>         choose: #saveImageBeforeExiting << #dialogs >> 'Save the image before exiting?'
>>         labels: {#Yes << #dialogs >> 'Yes'.
>>                    #No << #dialogs >> 'No'.
>>                    #Cancel << #dialogs >> 'Cancel'}
>>         values: #(#saveThenQuit #exit #cancel)
>>         default: #saveThenQuit
>>
>> -Boris
>>
>> -----Original Message-----
>> From: [hidden email] [mailto:[hidden email]] On
>> Behalf Of Andres Valloud
>> Sent: Tuesday, June 30, 2009 3:12 PM
>> To: Visualworks Mailing List
>> Subject: Re: [vwnc] BraceConstructor breaksrefactorings (tentative
>> fixincluded)
>>
>> Stef,
>>
>> Well, I wouldn't say that {...} enables what we have seen daily over
>> the years :)... the feeling I get, and it's just a feeling right now,
>> is that the convenience will detract from domain object design.  In
>> other words, if it's too convenient to use {...} and write stuff in
>> terms of lists, then how much does the convenience affect how objects
>> are structured so that they fit a POV where everything is a list?  And
>> it's not that "everything is a list" doesn't work, either.  But...
>>
>> Andres.
>>
>>
>> Stéphane Ducasse wrote:
>>
>>    
>>> I understand what you mean!!!!
>>> I got the same concerns.  Clearly you are afraid that if you give to
>>> people an easy
>>>   array creation they will not produce object but arrays. It was the
>>> case in Squeak before {} You have a lot of code with first second
>>> ...fifth....yeah pretty cool.
>>> Now you should consider that { } is still cool because it is compact
>>> and dynamic.
>>> In fact { } is much more smalltalkish than #() which is so parse time
>>> boring.
>>>
>>> Stef
>>>
>>>
>>> On Jun 30, 2009, at 10:17 PM, Andres Valloud wrote:
>>>
>>>
>>>
>>>      
>>>> Mod implementation details, which we are all well capable of
>>>> figuring out, I do see the motivation for {...}.  However, I am not
>>>> sure it's a good idea.  Right now, it feels too much like a C struct
>>>> and, to me, these reek a bit too much of flattened data and little
>>>> semantic meaning.  But, it's a feeling.  I'll think about it for a
>>>> week or so, and then I'll have a better idea.
>>>>
>>>> Vassili Bykov wrote:
>>>>
>>>>
>>>>        
>>>>> On Tue, Jun 30, 2009 at 12:48 AM, Valloud,
>>>>> Andres<[hidden email]> wrote:
>>>>>
>>>>>
>>>>>
>>>>>          
>>>>>> Vassili, to borrow from the macro expansion metaphor for the sake
>>>>>> of illustration only, do you mean {1. 2. 3} to be replaced like
>>>>>> this (mod the fact that there are only so many with:^n selectors,
>>>>>> etc.)?
>>>>>>
>>>>>> (Array with: [1] value with: [2] value with: [3] value)
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> No, your original expansion proposal was in fact OK as an
>>>>> illustration for this particular example. I said it was wrong for
>>>>> the general case because the real expansion scheme should be
>>>>>
>>>>> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN);
>>>>> beImmutable)
>>>>>
>>>>> However a real implementation should ideally be cheaper than this.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>          
>>>>>> Or do you mean for objects to live inside complex compiled method
>>>>>> literals?  If you mean the latter, consider the case where at
>>>>>> first I make a mistake an implement:
>>>>>>
>>>>>> Integer>>factorial
>>>>>>
>>>>>> self < 1 ifTrue: [^nil].
>>>>>> ^"do the calculation somehow"
>>>>>>
>>>>>>
>>>>>> After implementing this method, I go ahead and write:
>>>>>>
>>>>>> WhateverObject>>someFactorials
>>>>>>
>>>>>> ^{0 factorial.  1 factorial.  2 factorial.  3 factorial}
>>>>>>
>>>>>>
>>>>>> Then, I realize I messed up Integer>>factorial, so I correct it:
>>>>>>
>>>>>> Integer>>factorial
>>>>>>
>>>>>> self < 0 ifTrue: [^nil].
>>>>>> ^"do the calculation somehow"
>>>>>>
>>>>>>
>>>>>> It would seem weird to me that modifying the above method should
>>>>>> trigger recompiling #someFactorials (by hand?).  To some extent,
>>>>>> the problem would be that some portion of the app would be created
>>>>>> imperatively as opposed to declaratively... in a way, it would be
>>>>>> a special case of the more general problem of creating an
>>>>>> arbitrary image from source code or from a specification.  On the
>>>>>> other hand, if the "expansion" executed code to create the list
>>>>>> from scratch each time {...} is encountered, then the problem
>>>>>> would go away.
>>>>>>
>>>>>>
>>>>>> -----Original Message-----
>>>>>> From: [hidden email] [mailto:[hidden email]]
>>>>>> On Behalf Of Vassili Bykov
>>>>>> Sent: Tuesday, June 30, 2009 12:17 AM
>>>>>> To: [hidden email]
>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>> (tentative fixincluded)
>>>>>>
>>>>>> I would be satisfied with anything that (1) satisfies the spec and
>>>>>> (2) is practically viable. Given those two, I don't care how it's
>>>>>> implemented. Discussing an equivalent macro expansion is only
>>>>>> useful to clarify the semantics but not the motivation (though
>>>>>> your expansion doesn't work for the general case).
>>>>>>
>>>>>> The motivation here, to make it reasonably general, is allowing
>>>>>> lexically nested named contexts to represent nested entities of
>>>>>> the model. For example:
>>>>>>
>>>>>> row: {
>>>>>>   prefix.
>>>>>>   column: {
>>>>>>       header.
>>>>>>       row: {item1. item2. item3. item4. item5. item6. item7}.
>>>>>>       row: {item8. item9}.
>>>>>>       footer.
>>>>>>   }.
>>>>>>   suffix.
>>>>>> }
>>>>>>
>>>>>> One can come up with other schemes to encode such things, but
>>>>>> nothing with as little extraneous gunk as in this. (This is a real
>>>>>> example of a Hopscotch presenter definition).
>>>>>>
>>>>>> --Vassili
>>>>>>
>>>>>> On Mon, Jun 29, 2009 at 6:05 PM, Andres
>>>>>> Valloud<[hidden email]> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>>>> So, if braces were taken care of by a macro preprocessor that
>>>>>>> replaced
>>>>>>>
>>>>>>> {1. 2. 3.}
>>>>>>>
>>>>>>> with
>>>>>>>
>>>>>>> (Array with: (1) with: (2) with: (3))
>>>>>>>
>>>>>>> would you be satisfied as far as the results go?  Is this just a
>>>>>>> matter of keyboard shorthand?  If so, why does it need to be in
>>>>>>> the syntax of the language?
>>>>>>>
>>>>>>>
>>>>>>> Vassili Bykov wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>>>> It's all in the language spec, and your criticism assumes a
>>>>>>>> suboptimal spec. The spec should say that a brace expression
>>>>>>>> evaluates to an object that conforms to an immutable list
>>>>>>>> protocol.
>>>>>>>> Not an Array or any other specific class. It should also state
>>>>>>>> that it is unspecified whether or not results of multiple
>>>>>>>> evaluations can be identical or otherwise share their structure.
>>>>>>>>
>>>>>>>> What this achieves is:
>>>>>>>>
>>>>>>>> 1) It shifts the focus from the implementation to the interface.
>>>>>>>> The
>>>>>>>> point of having braces is syntactically cheap list
>>>>>>>> specification, not syntactically cheap Array creation. The
>>>>>>>> divide is easily and safely crossed if the immutable list
>>>>>>>> protocol includes a message like #asArray to produce a mutable
>>>>>>>> Array.
>>>>>>>>
>>>>>>>> 2) Immutability requires no AI in the compiler, while the
>>>>>>>> compiler is free to optimize deeply immutable lists to literals.
>>>>>>>> Or not.
>>>>>>>>
>>>>>>>> 3) The code is safe because immutability is on and has to be
>>>>>>>> explicitly turned off and not vice versa.
>>>>>>>>
>>>>>>>> --Vassili
>>>>>>>>
>>>>>>>>
>>>>>>>> On Mon, Jun 29, 2009 at 5:00 PM, <[hidden email]> wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>>>> Vassili,
>>>>>>>>>
>>>>>>>>> From a language theory point of view, I must disagree that
>>>>>>>>> literal arrays are "warts".  They epresent constants defined at
>>>>>>>>> compile time with immutable values and state.  This is /not/
>>>>>>>>> true of any constructed list, and almost all modern languages
>>>>>>>>> recognize this.
>>>>>>>>>
>>>>>>>>> It is also incorrect to assume that the compiler can determine
>>>>>>>>> immutability on its own.  Consider this case (using GS/S syntax):
>>>>>>>>>
>>>>>>>>>       #{ 5  6 )
>>>>>>>>>       #[ 5, 6 ]
>>>>>>>>>
>>>>>>>>> Here the first one is a literal array that is marked immutable
>>>>>>>>> (invariant), while the second is a constructed array that is /
>>>>>>>>> not/ immutable.  While it is true that both arrays can be
>>>>>>>>> statically constructed by the compiler, the reference semantics
>>>>>>>>> are quite different.  In the former case the array and its
>>>>>>>>> individual members are immutable and all references are shared
>>>>>>>>> (identity semantics);  in the latter the members may or may not
>>>>>>>>> be immutable and at least all top-most references must be
>>>>>>>>> copies (equality semantics).  This gets even more complicated
>>>>>>>>> or obvious with embedded constructs:
>>>>>>>>>
>>>>>>>>>       #( 5  #( 7  8 )  6 )
>>>>>>>>>       #[ 5, #[ 7, 8 ], 6 ]
>>>>>>>>>
>>>>>>>>> A compiler cannot /intuit/ that either one should be invariant;
>>>>>>>>> it must be defined by the language specification, which is why
>>>>>>>>> you need two separate representations.  Making them /more/
>>>>>>>>> similar in syntax is perhaps desirable.  For example, I would
>>>>>>>>> be perfectly happy with:
>>>>>>>>>
>>>>>>>>>        #( 5. 6 )
>>>>>>>>>       ##( 5. 6 )
>>>>>>>>>
>>>>>>>>> [choose your favorite syntax], where the former only permits
>>>>>>>>> literals while the latter permits arbitrary expressions.  Using
>>>>>>>>> periods should be optional for the former, but would be
>>>>>>>>> required for the latter to prevent ambiguity with unary message
>>>>>>>>> sends.
>>>>>>>>>
>>>>>>>>> Eliminating the case of the literal form actually will make
>>>>>>>>> code unsafe and less unreadable because you must explicitly
>>>>>>>>> recursively mark the result as immutable - something we'll all
>>>>>>>>> forget to do.
>>>>>>>>>
>>>>>>>>> Cheers!
>>>>>>>>>
>>>>>>>>> Tom Hawker
>>>>>>>>> --------------------------
>>>>>>>>> Senior Framework Developer
>>>>>>>>> --------------------------
>>>>>>>>> Home    +1 (408) 274-4128
>>>>>>>>> Office  +1 (408) 576-6591
>>>>>>>>> Mobile  +1 (408) 835-3643
>>>>>>>>>
>>>>>>>>> -----Original Message-----
>>>>>>>>> From: [hidden email] [mailto:vwnc-
>>>>>>>>> [hidden email]] On Behalf Of Vassili Bykov
>>>>>>>>> Sent: Monday, June 29, 2009 3:22 PM
>>>>>>>>> To: vwnc
>>>>>>>>> Subject: Re: [vwnc] BraceConstructor breaks refactorings
>>>>>>>>> (tentative fix included)
>>>>>>>>>
>>>>>>>>> To clarify a few points:
>>>>>>>>>
>>>>>>>>> Literals have nothing to do with this. "{expr1. expr2}" is
>>>>>>>>> equivalent to "Array with: expr 1 with: expr2", not "##(Array
>>>>>>>>> with: expr 1 with:
>>>>>>>>> expr2)".
>>>>>>>>>
>>>>>>>>> Speed has nothing to do with this. The motivation is to provide
>>>>>>>>> a usable syntax for specifying lists of things, without the
>>>>>>>>> random limitations of literal array syntax. This is immensely
>>>>>>>>> useful in embedded DSLs, for example. Let me put it bluntly:
>>>>>>>>> classic Smalltalk got it wrong, literal arrays are a wart.
>>>>>>>>> Something like the braces, with arbitrary expressions inside,
>>>>>>>>> should have been the default and *the only* way to specify
>>>>>>>>> arrays. It should be up to the compiler to optimize array
>>>>>>>>> expressions with constant elements to (read-only) literals.
>>>>>>>>> (But speaking of raw speed, the VW version of braces doesn't
>>>>>>>>> create arrays by talking to the Array class, it uses the
>>>>>>>>> ConsArray bytecode).
>>>>>>>>>
>>>>>>>>> Redundancy, as in "we already have Array with:", has nothing to
>>>>>>>>> do with this. By the same logic nil, true, and false as
>>>>>>>>> pseudo-variables should have been unnecessary. They could have
>>>>>>>>> been implemented instead as "UndefinedObject default", "True
>>>>>>>>> default" and "False default."
>>>>>>>>>
>>>>>>>>> Thank you, David, for looking after this.
>>>>>>>>>
>>>>>>>>> --Vassili
>>>>>>>>> _______________________________________________
>>>>>>>>> vwnc mailing list
>>>>>>>>> [hidden email]
>>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>>>
>>>>>>>>> IMPORTANT NOTICE
>>>>>>>>> Email from OOCL is confidential and may be legally privileged.
>>>>>>>>> If
>>>>>>>>> it is not intended for you, please delete it immediately unread.
>>>>>>>>> The internet cannot guarantee that this communication is free
>>>>>>>>> of viruses, interception or interference and anyone who
>>>>>>>>> communicates with us by email is taken to accept the risks in doing so.
>>>>>>>>> Without
>>>>>>>>> limitation, OOCL and its affiliates accept no liability
>>>>>>>>> whatsoever and howsoever arising in connection with the use of
>>>>>>>>> this email.
>>>>>>>>> Under no circumstances shall this email constitute a binding
>>>>>>>>> agreement to carry or for provision of carriage services by
>>>>>>>>> OOCL, which is subject to the availability of carrier's
>>>>>>>>> equipment and vessels and the terms and conditions of OOCL's
>>>>>>>>> standard bill of lading which is also available at http://www.oocl.com.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>                  
>>>>>>>> _______________________________________________
>>>>>>>> vwnc mailing list
>>>>>>>> [hidden email]
>>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>> .
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>                
>>>>>>> _______________________________________________
>>>>>>> vwnc mailing list
>>>>>>> [hidden email]
>>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>              
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>> _______________________________________________
>>>>>> vwnc mailing list
>>>>>> [hidden email]
>>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>            
>>>>> _______________________________________________
>>>>> vwnc mailing list
>>>>> [hidden email]
>>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>> .
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>          
>>>> _______________________________________________
>>>> vwnc mailing list
>>>> [hidden email]
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>>>
>>>>
>>>>        
>>> _______________________________________________
>>> vwnc mailing list
>>> [hidden email]
>>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>>> .
>>>
>>>
>>>
>>>      
>> _______________________________________________
>> vwnc mailing list
>> [hidden email]
>> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>> .
>>
>>
>>    
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> .
>
>  
_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaksrefactorings (tentative fixincluded)

Andre Schnoor
In reply to this post by Boris Popov, DeepCove Labs (SNN)
No! No, please no. (sigh)

The dialog examples you're citing are among the worst and most  
annoying constructs I could think of. Parallel (related) list  
arguments are 1960's LISP-style and should no longer be around today.  
I can see that ad-hoc aggregates might be useful for testing and  
scripting, but I don't want to see them in released code.

For example, I am fighting with the legacy menu and dialog API of VW  
for years and am extremely frustrated due to this. Instead of throwing  
ad-hoc lists and aggregates around, the proper way to build a menu is  
to do it programatically on a per-item basis:

        ^MenuBuilder new
                add: 'Label' -> someItem;
                add: 'Label' -> someOtherItem enabled: [ self itemIsEnabled ];
                menu

MenuBuilder could easily be enhanced by convenience methods that help  
make menu building become more readable and maintainable. The same  
goes for dialogs.

I agree with many of you that the use of aggregates encourages dirty  
hacks. The maintenance of an application that uses them is diffcult  
and error-prone (no easy way to spot uses, do refactoring, augment or  
modify existing functionality, ensure backwards compatibility, no way  
to deal with system changes, ...)

So please, any sort of {...} construct should be added as an optional  
package, but kept out of the base.

Ironically, one reason why Smalltalk has such a hard time to catch up  
with todays expectations is that it is so "easy to do complicated  
things". Why that? Because its overwhelming APIs are so stuffed with  
half-baken things that once were so "easy to do" that nobody cared  
about whether they are necessary or useful enough to justify the  
increased complexity.

Sometimes I wish it was more painful and hard to do things, because  
new paradigms and constructs would then be more thoroughly planned and  
carried out (and documented).

Andre

--
Am 01.07.2009 um 00:21 schrieb Boris Popov:

> Andres,
>
> I certainly see the angle you're presenting, but there are plenty of  
> cases already where lists are natural API elements and simpler, more  
> concise expression might go some way toward improving readability  
> without really encouraging list abuse that you're referring to.
>
> Dialog
> choose: #saveImageBeforeExiting << #dialogs >> 'Save the image  
> before exiting?'
> labels:
> (Array
> with: #Yes << #dialogs >> 'Yes'
> with: #No << #dialogs >> 'No'
> with: #Cancel << #dialogs >> 'Cancel')
> values: #(#saveThenQuit #exit #cancel)
> default: #saveThenQuit
>
> Dialog
> choose: #saveImageBeforeExiting << #dialogs >> 'Save the image  
> before exiting?'
> labels: {#Yes << #dialogs >> 'Yes'.
>   #No << #dialogs >> 'No'.
>   #Cancel << #dialogs >> 'Cancel'}
> values: #(#saveThenQuit #exit #cancel)
> default: #saveThenQuit
>
> -Boris

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Paul Baumann
In reply to this post by Vassili Bykov-2
Vasilli,

It is not immutable; nor should it be. It is a new array created by bytecodes to contain a predetermined number of objects (max 256) pushed to stack. The decompiled code shows how it works.

        {3 + 4. Date today. thisContext halt}

normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
literals: ({Date} #today #halt )
1 <D8 03> push 3
3 <D8 04> push 4
5 <DF 00> no-check send +
7 <34> push Date
8 <71> send today
9 <54> push context
10 <72> send halt
11 <D5 02> pop 3 into new array
13 <65> return


        Array with: 3 + 4 with: Date today with: thisContext halt

normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
literals: ({Array} {Date} #today #halt )
1 <34> push Array
2 <D8 03> push 3
4 <D8 04> push 4
6 <DF 00> no-check send +
8 <35> push Date
9 <72> send today
10 <54> push context
11 <73> send halt
12 <F0 BE> send with:with:with:
14 <65> return

It is cheaper because it avoids an Array reference and message send. It executes 97% faster, but large as that difference is, it should not be a determining factor in typical code. The performance difference might be relevant in some situations though.

Time millisecondsToRun: [500000000 timesRepeat: [{1. 2. 3. 4}]].
 1196
Time millisecondsToRun: [500000000 timesRepeat: [Array with: 1 with: 2 with: 3 with: 4]].
 35958

1 - (1196 / 35958) * -100.0
 -96.6739

I like how it is implemented, and I'd have some use for it. It doesn't bother me that the language is changing or that the code might become part of the VW base. What bothers me is only that syntax for this kind of thing now varies between dialects. It is like nobody else knows or cares what other dialects have done. I don't feel that it helps to have a fractured language. It looks like it was Squeak that started the syntax fork on this one though, and I don't have a strong preference for either syntax.

Regards,

Paul Baumann


-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Vassili Bykov
Sent: Tuesday, June 30, 2009 4:13 PM
To: [hidden email]
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

On Tue, Jun 30, 2009 at 12:48 AM, Valloud, Andres<[hidden email]> wrote:
> Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
>
> (Array with: [1] value with: [2] value with: [3] value)

No, your original expansion proposal was in fact OK as an illustration for this particular example. I said it was wrong for the general case because the real expansion scheme should be

((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN); beImmutable)

However a real implementation should ideally be cheaper than this.


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Paul Baumann
Whoops! The "this statement has no effect" notice on the earliar measurements also tuned away doing work. I added a #yourself send to get it to actually do some work and now there is only a 34% difference.

Time millisecondsToRun: [500000000 timesRepeat: [#(1 2 3 4) yourself]].
 2473
Time millisecondsToRun: [500000000 timesRepeat: [{1. 2. 3. 4} yourself]].
 23857
Time millisecondsToRun: [500000000 timesRepeat: [(Array with: 1 with: 2 with: 3 with: 4) yourself]].
 36321

1 - (23857 / 36321) * -100.0
 -34.3162

Paul Baumann

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Paul Baumann
Sent: Wednesday, July 01, 2009 11:13 AM
To: 'Vassili Bykov'; [hidden email]
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Vasilli,

It is not immutable; nor should it be. It is a new array created by bytecodes to contain a predetermined number of objects (max 256) pushed to stack. The decompiled code shows how it works.

        {3 + 4. Date today. thisContext halt}

normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
literals: ({Date} #today #halt )
1 <D8 03> push 3
3 <D8 04> push 4
5 <DF 00> no-check send +
7 <34> push Date
8 <71> send today
9 <54> push context
10 <72> send halt
11 <D5 02> pop 3 into new array
13 <65> return


        Array with: 3 + 4 with: Date today with: thisContext halt

normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
literals: ({Array} {Date} #today #halt )
1 <34> push Array
2 <D8 03> push 3
4 <D8 04> push 4
6 <DF 00> no-check send +
8 <35> push Date
9 <72> send today
10 <54> push context
11 <73> send halt
12 <F0 BE> send with:with:with:
14 <65> return

It is cheaper because it avoids an Array reference and message send. It executes 97% faster, but large as that difference is, it should not be a determining factor in typical code. The performance difference might be relevant in some situations though.

Time millisecondsToRun: [500000000 timesRepeat: [{1. 2. 3. 4}]].
 1196
Time millisecondsToRun: [500000000 timesRepeat: [Array with: 1 with: 2 with: 3 with: 4]].
 35958

1 - (1196 / 35958) * -100.0
 -96.6739

I like how it is implemented, and I'd have some use for it. It doesn't bother me that the language is changing or that the code might become part of the VW base. What bothers me is only that syntax for this kind of thing now varies between dialects. It is like nobody else knows or cares what other dialects have done. I don't feel that it helps to have a fractured language. It looks like it was Squeak that started the syntax fork on this one though, and I don't have a strong preference for either syntax.

Regards,

Paul Baumann


-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of Vassili Bykov
Sent: Tuesday, June 30, 2009 4:13 PM
To: [hidden email]
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

On Tue, Jun 30, 2009 at 12:48 AM, Valloud, Andres<[hidden email]> wrote:
> Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
>
> (Array with: [1] value with: [2] value with: [3] value)

No, your original expansion proposal was in fact OK as an illustration for this particular example. I said it was wrong for the general case because the real expansion scheme should be

((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN); beImmutable)

However a real implementation should ideally be cheaper than this.


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc


This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Vassili Bykov-2
In reply to this post by Paul Baumann
On Wed, Jul 1, 2009 at 8:13 AM, Paul Baumann<[hidden email]> wrote:
> Vasilli,
>
> It is not immutable; nor should it be. It is a new array created by bytecodes to contain a predetermined number of objects (max 256) pushed to stack. The decompiled code shows how it works.

I know--I wrote it. (Ask Eliot to tell you that joke). But I was
talking about the ideal solution able to subsume the standard #(), not
this specific implementation. For that, immutability would allow
arrays of literals to be as cheap as before.

> I like how it is implemented, and I'd have some use for it. It doesn't bother me that the language is changing or that the code might become part of the VW base. What bothers me is only that syntax for this kind of thing now varies between dialects. It is like nobody else knows or cares what other dialects have done. I don't feel that it helps to have a fractured language. It looks like it was Squeak that started the syntax fork on this one though, and I don't have a strong preference for either syntax.

That's unfortunate, but then again it's a fact of life. Smalltalk is
not a language, it's a language family just like Lisp. Pretty much
every dialect introduced something that others don't have.

--Vassili

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)

Vassili Bykov-2
In reply to this post by Paul Baumann
I'm not sure why #yourself is needed, if what you want to compare is
the speed of array creation. Doing work is a separate thing. It's just
a constant thrown in on both sides and pushing the ratio closer to 1
the more work you do. But even so, the ratio would change for larger
arrays as you change the expansion scheme. Here you are comparing the
ConsArray opcode against a send of #with:with:with:with:. For larger
arrays, it would be N pushes and one ConsArray on one side and 2*N
pushes and N sends of #at:put: on the other.

On Wed, Jul 1, 2009 at 8:56 AM, Paul Baumann<[hidden email]> wrote:

> Whoops! The "this statement has no effect" notice on the earliar measurements also tuned away doing work. I added a #yourself send to get it to actually do some work and now there is only a 34% difference.
>
> Time millisecondsToRun: [500000000 timesRepeat: [#(1 2 3 4) yourself]].
>  2473
> Time millisecondsToRun: [500000000 timesRepeat: [{1. 2. 3. 4} yourself]].
>  23857
> Time millisecondsToRun: [500000000 timesRepeat: [(Array with: 1 with: 2 with: 3 with: 4) yourself]].
>  36321
>
> 1 - (23857 / 36321) * -100.0
>  -34.3162
>
> Paul Baumann
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Paul Baumann
> Sent: Wednesday, July 01, 2009 11:13 AM
> To: 'Vassili Bykov'; [hidden email]
> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
>
> Vasilli,
>
> It is not immutable; nor should it be. It is a new array created by bytecodes to contain a predetermined number of objects (max 256) pushed to stack. The decompiled code shows how it works.
>
>        {3 + 4. Date today. thisContext halt}
>
> normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
> literals: ({Date} #today #halt )
> 1 <D8 03> push 3
> 3 <D8 04> push 4
> 5 <DF 00> no-check send +
> 7 <34> push Date
> 8 <71> send today
> 9 <54> push context
> 10 <72> send halt
> 11 <D5 02> pop 3 into new array
> 13 <65> return
>
>
>        Array with: 3 + 4 with: Date today with: thisContext halt
>
> normal AnnotatedMethod numArgs=0 numTemps=0 frameSize=12
> literals: ({Array} {Date} #today #halt )
> 1 <34> push Array
> 2 <D8 03> push 3
> 4 <D8 04> push 4
> 6 <DF 00> no-check send +
> 8 <35> push Date
> 9 <72> send today
> 10 <54> push context
> 11 <73> send halt
> 12 <F0 BE> send with:with:with:
> 14 <65> return
>
> It is cheaper because it avoids an Array reference and message send. It executes 97% faster, but large as that difference is, it should not be a determining factor in typical code. The performance difference might be relevant in some situations though.
>
> Time millisecondsToRun: [500000000 timesRepeat: [{1. 2. 3. 4}]].
>  1196
> Time millisecondsToRun: [500000000 timesRepeat: [Array with: 1 with: 2 with: 3 with: 4]].
>  35958
>
> 1 - (1196 / 35958) * -100.0
>  -96.6739
>
> I like how it is implemented, and I'd have some use for it. It doesn't bother me that the language is changing or that the code might become part of the VW base. What bothers me is only that syntax for this kind of thing now varies between dialects. It is like nobody else knows or cares what other dialects have done. I don't feel that it helps to have a fractured language. It looks like it was Squeak that started the syntax fork on this one though, and I don't have a strong preference for either syntax.
>
> Regards,
>
> Paul Baumann
>
>
> -----Original Message-----
> From: [hidden email] [mailto:[hidden email]] On Behalf Of Vassili Bykov
> Sent: Tuesday, June 30, 2009 4:13 PM
> To: [hidden email]
> Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)
>
> On Tue, Jun 30, 2009 at 12:48 AM, Valloud, Andres<[hidden email]> wrote:
>> Vassili, to borrow from the macro expansion metaphor for the sake of illustration only, do you mean {1. 2. 3} to be replaced like this (mod the fact that there are only so many with:^n selectors, etc.)?
>>
>> (Array with: [1] value with: [2] value with: [3] value)
>
> No, your original expansion proposal was in fact OK as an illustration for this particular example. I said it was wrong for the general case because the real expansion scheme should be
>
> ((Array new: N) at: 1 put: (expr1); ...; at: N put: (exprN); beImmutable)
>
> However a real implementation should ideally be cheaper than this.
>
>
> This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.
>
>
> _______________________________________________
> vwnc mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>
>
> This message may contain confidential information and is intended for specific recipients unless explicitly noted otherwise. If you have reason to believe you are not an intended recipient of this message, please delete it and notify the sender. This message may not represent the opinion of IntercontinentalExchange, Inc. (ICE), its subsidiaries or affiliates, and does not constitute a contract or guarantee. Unencrypted electronic mail is not secure and the recipient of this message is expected to provide safeguards from viruses and pursue alternate means of communication where privacy or a binding message is desired.
>
>

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
12