[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
|

[vwnc] BraceConstructor breaks refactorings (tentative fix included)

cdavidshaffer
For anyone who doesn't use it, the BraceConstructor parcel adds syntax like:

{ statement. statement. statement ...}

as a shortcut for creating an array (like an array literal but you
actually get to put statements in the braces rather than just
literals).  This brace syntax is very nice, especially for building tests!

One caveat is that this parcel breaks refactorings.  Any method which
uses brace constructors is generally ignored by refactorings.  For
example the method:

iUseBraces
   ^{self makeSomething. self makeSomethingElse}

if I rename the method makeSomething, the iUseBraces method would be
left unchanged.  Similar problems with other refactorings.

To correct this I loaded RBFormatterBraceConstructorExtension from the
Cincom repo and added the attached method to ParseTreeRewriter.  Things
seem to be working now but I'd appreciate feedback on if this is "the
right thing to do."

Finally I'd like to remark that the BraceConstructor parcel, as included
in VW7.6 breaks the RB formatter (loudly -> walkback) and refactorings
(silently) so it would be nice to have the comment updated to reflect
this and I suggest the inclusion of above mentioned package (plus my
change, if it is legit) as parcels.

David


<?xml version="1.0"?>

<st-source>
<time-stamp>From VisualWorks® NonCommercial, 7.6 of March 3, 2008 on June 29, 2009 at 2:20:01 pm</time-stamp>


<methods>
<class-id>Refactory.Browser.ParseTreeRewriter</class-id> <category>visitor-double dispatching</category>

<body package="Browser-Parser" selector="acceptBraceConstructionNode:">acceptBraceConstructionNode: aBraceConstructionNode
        self visitNode: aBraceConstructionNode body</body>
</methods>

</st-source>

_______________________________________________
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 fix included)

Paul Baumann

Modifying the language and tools to support the equivalent of "Array with: self makeSomething with: self makeSomethingElse"--and not even for a performance advantage. Not to discourage you, but it isn't something I would have taken the time to do. I'd have rather gone through that trouble to support the VA syntax ##() for compile-time evaluation and literal storage. That syntax extension at least has a performance advantage.

GS/S is one dialect (of perhaps three) that supports #[one, two, ...] syntax for creating a literal array as you are doing. I'm surprised you didn't use that syntax instead of the curly brackets. It is closer to a Smalltalk pseudo (or perhaps emerging) standard. It seems there are people that like syntax support for creating an Array.

Paul Baumann

-----Original Message-----
From: [hidden email] [mailto:[hidden email]] On Behalf Of C. David Shaffer
Sent: Monday, June 29, 2009 2:29 PM
To: vwnc
Subject: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

For anyone who doesn't use it, the BraceConstructor parcel adds syntax like:

{ statement. statement. statement ...}

as a shortcut for creating an array (like an array literal but you actually get to put statements in the braces rather than just literals).  This brace syntax is very nice, especially for building tests!

One caveat is that this parcel breaks refactorings.  Any method which uses brace constructors is generally ignored by refactorings.  For example the method:

iUseBraces
   ^{self makeSomething. self makeSomethingElse}

if I rename the method makeSomething, the iUseBraces method would be left unchanged.  Similar problems with other refactorings.

To correct this I loaded RBFormatterBraceConstructorExtension from the Cincom repo and added the attached method to ParseTreeRewriter.  Things seem to be working now but I'd appreciate feedback on if this is "the right thing to do."

Finally I'd like to remark that the BraceConstructor parcel, as included in VW7.6 breaks the RB formatter (loudly -> walkback) and refactorings
(silently) so it would be nice to have the comment updated to reflect this and I suggest the inclusion of above mentioned package (plus my change, if it is legit) as parcels.

David


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 fix included)

cdavidshaffer
Paul Baumann wrote:
> Modifying the language and tools to support the equivalent of "Array with: self makeSomething with: self makeSomethingElse"--and not even for a performance advantage. Not to discourage you, but it isn't something I would have taken the time to do. I'd have rather gone through that trouble to support the VA syntax ##() for compile-time evaluation and literal storage. That syntax extension at least has a performance advantage.
>
> GS/S is one dialect (of perhaps three) that supports #[one, two, ...] syntax for creating a literal array as you are doing. I'm surprised you didn't use that syntax instead of the curly brackets. It is closer to a Smalltalk pseudo (or perhaps emerging) standard. It seems there are people that like syntax support for creating an Array.
>
> Paul Baumann
>
>  
BraceConstructor isn't my package.  It was written (by Vassili Boykov, I
believe) for compatibility with Squeak's brace constructor syntax.  I'm
just adding one patch to fix compatibility with the RB.

I've seen this subject debated many times.  BraceConstructor is useful
to me, though mostly in test cases, so all of the principled discussion
really doesn't motivate me much ;-)  If someone else wants to give me
something more efficient, go ahead...although right now I have no need
for it.

David

_______________________________________________
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 fix included)

Paul Baumann

Understandable. Very few ever did care about portability and principles anyway. Can't say I'm motivated by any such discussion either, just hate being one of the ones that writes tools to support several different ways to do the same thing. Didn't realize Squeak went the curly route too. Ship has sailed--further discussion not necessary. I think you are right, discussion probably had happened years ago. I guess another example of a standard bearer being rendered incompatible by everything else that follows. Hey it happens in everything. If there are two ways to read the order of bits then naturally you get big-endian and little-endian. If the reply to a post goes after the original message, then someone will always do the opposite. I wonder why only three line ending conventions came about when an infinite number could have been created--or perhaps many had been created but complexity was the force that narrowed it to only the three we all deal with. Yeah, whatever. Efficien!
 cy is what I care about these days too.

Regards,

Paul Baumann

-----Original Message-----
From: C. David Shaffer [mailto:[hidden email]]
Sent: Monday, June 29, 2009 4:20 PM
To: Paul Baumann
Cc: vwnc
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)
Importance: High

Paul Baumann wrote:
> Modifying the language and tools to support the equivalent of "Array with: self makeSomething with: self makeSomethingElse"--and not even for a performance advantage. Not to discourage you, but it isn't something I would have taken the time to do. I'd have rather gone through that trouble to support the VA syntax ##() for compile-time evaluation and literal storage. That syntax extension at least has a performance advantage.
>
> GS/S is one dialect (of perhaps three) that supports #[one, two, ...] syntax for creating a literal array as you are doing. I'm surprised you didn't use that syntax instead of the curly brackets. It is closer to a Smalltalk pseudo (or perhaps emerging) standard. It seems there are people that like syntax support for creating an Array.
>
> Paul Baumann
>
>
BraceConstructor isn't my package.  It was written (by Vassili Boykov, I
believe) for compatibility with Squeak's brace constructor syntax.  I'm just adding one patch to fix compatibility with the RB.

I've seen this subject debated many times.  BraceConstructor is useful to me, though mostly in test cases, so all of the principled discussion really doesn't motivate me much ;-)  If someone else wants to give me something more efficient, go ahead...although right now I have no need for it.

David



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 fix included)

cdavidshaffer
Paul Baumann wrote:
> Understandable. Very few ever did care about portability and principlesanyway. Can't say I'm motivated by any such discussion either, just hatebeing one of the ones that writes tools to support several different ways to do the same thing. Didn't realize Squeak went the curly route too. Ship has sailed--further discussion not necessary. I think you are right, discussion probably had happened years ago. I guess another example of a standard bearer being rendered incompatible by everything else that follows. Hey it happens in everything. If there are two ways to read the orderof bits then naturally you get big-endian and little-endian. If the reply to a post goes after the original message, then someone will always do the opposite. I wonder why only three line ending conventions came about when an infinite number could have been created--or perhaps many had beencreated but complexity was the force that narrowed it to only the three we all deal with. Yeah, whatever. Efficiency
is what I care about these days too.
>
> Regards,
>  

I'm not sure where this is coming from?  I'm just being pragmatic.  I
want something to make it easier to create "literal arrays" like I can
in Python, Ruby, perl etc.  People can debate "the best way" until they
are blue in the face.  They also seem to debate whether we should even
be creating these arrays..."code smells" and all that.  Really?  I'm not
trying to stifle such discussion, I just think such debates are best
left for people interested in them.  I'll use /whatever/ reasonable
syntax someone wants to give me.  Your #[] suggestion look fine.  Got
code?  (Array with:* doesn't cut it unless I only plan to use arrays
with 5 elements.) Otherwise BraceConstructor is all I've got...that and
a lot of other work to do instead of trying to re-invent Smalltalk.
I've got a good text editor that can fix all of my code should the
Smalltalk powers that be ever decide on the "right way."

David



_______________________________________________
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 fix included)

Vassili Bykov-2
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
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

Andres Valloud-4
Your argument seems to imply the only useful alternative for embedded
DSLs is to use brace constructs.  Why are arrays so prevalent in
embedded DSLs?  Why don't more sophisticated (?) objects appear more
naturally in embedded DSLs, thus making the need for arrays less pressing?

Vassili Bykov wrote:

> 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
>
>  
_______________________________________________
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 fix included)

Eliot Miranda-2


On Mon, Jun 29, 2009 at 3:37 PM, Andres Valloud <[hidden email]> wrote:
Your argument seems to imply the only useful alternative for embedded
DSLs is to use brace constructs.  Why are arrays so prevalent in
embedded DSLs?  Why don't more sophisticated (?) objects appear more
naturally in embedded DSLs, thus making the need for arrays less pressing?

How do you construct those more complex objects in the first place without adding syntactic extensions for new literal constructs?  Array literals are a general "make me a tuple" construct with reasonable generality.

 


Vassili Bykov wrote:
> 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
>
>
_______________________________________________
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 fix included)

Andres Valloud-4
Back in the day I used the comma message to create tuples.  However, I
meant to ask why are tuples so prevalent in embedded DSLs, as opposed to
more specific objects.  We could certainly replace Association, Point
and a bunch of others with tuples, but we don't do that...

Eliot Miranda wrote:

>
>
> On Mon, Jun 29, 2009 at 3:37 PM, Andres Valloud
> <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Your argument seems to imply the only useful alternative for embedded
>     DSLs is to use brace constructs.  Why are arrays so prevalent in
>     embedded DSLs?  Why don't more sophisticated (?) objects appear more
>     naturally in embedded DSLs, thus making the need for arrays less
>     pressing?
>
>
> How do you construct those more complex objects in the first place
> without adding syntactic extensions for new literal constructs?  Array
> literals are a general "make me a tuple" construct with reasonable
> generality.
>
>  
>
>
>
>     Vassili Bykov wrote:
>     > 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] <mailto:[hidden email]>
>     > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>     >
>     >
>     _______________________________________________
>     vwnc mailing list
>     [hidden email] <mailto:[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 fix included)

Vassili Bykov-2
In reply to this post by Andres Valloud-4
I don't see how "immensely useful" implies "the only useful
alternative", but to answer the specific question--  Arrays, or it's
better to say "tuples" to refer to a protocol and not a particular
implementation, are common because it's nice to be able to list
things. Lists and more sophisticated objects are not alternatives.
Sophisticated objects are made of parts, and a list works great as an
operator that allows to, well, list a number of parts.

On Mon, Jun 29, 2009 at 3:37 PM, Andres
Valloud<[hidden email]> wrote:

> Your argument seems to imply the only useful alternative for embedded
> DSLs is to use brace constructs.  Why are arrays so prevalent in
> embedded DSLs?  Why don't more sophisticated (?) objects appear more
> naturally in embedded DSLs, thus making the need for arrays less pressing?
>
> Vassili Bykov wrote:
>> 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
>>
>>
> _______________________________________________
> 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 fix included)

thomas.hawker
In reply to this post by Vassili Bykov-2
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
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

Vassili Bykov-2
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
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

Andres Valloud-4
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
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

Eliot Miranda-2
In reply to this post by Andres Valloud-4


On Mon, Jun 29, 2009 at 4:20 PM, Andres Valloud <[hidden email]> wrote:
Back in the day I used the comma message to create tuples.  However, I
meant to ask why are tuples so prevalent in embedded DSLs, as opposed to
more specific objects.  We could certainly replace Association, Point
and a bunch of others with tuples, but we don't do that...

That's a bit of a non-sequitur.  Associations have a specific use as elements of Dictionaries that makes them very useful.  They're ok for pairs, although key and value are arguably not as intuitive as first and second or first and last.  Points are even more specific than associations.  Both have arity 2, so can't conveniently be used for higher arities, foo y y y is non-obvious.  If you instead state "DSLs can advantageously use arbitrary tuples for defining data" and then ask "in Smalltalk what are the most convenient ways to define tuples?" you end up with "brace construct".

If instead you're really asking "why are tuples used in DSLs" isn't it obvious that, as Vassili points out, an arbitrary list is a very useful starting point for defining arbitrary data?  Look at e.g. JavaScript's JSON.  It would be great to have JSON syntax in Smalltalk, no?  That and destructuring bind.
 


Eliot Miranda wrote:
>
>
> On Mon, Jun 29, 2009 at 3:37 PM, Andres Valloud
> <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     Your argument seems to imply the only useful alternative for embedded
>     DSLs is to use brace constructs.  Why are arrays so prevalent in
>     embedded DSLs?  Why don't more sophisticated (?) objects appear more
>     naturally in embedded DSLs, thus making the need for arrays less
>     pressing?
>
>
> How do you construct those more complex objects in the first place
> without adding syntactic extensions for new literal constructs?  Array
> literals are a general "make me a tuple" construct with reasonable
> generality.
>
>
>
>
>
>     Vassili Bykov wrote:
>     > 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] <mailto:[hidden email]>
>     > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>     >
>     >
>     _______________________________________________
>     vwnc mailing list
>     [hidden email] <mailto:[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-6
Eliot,
 
> That's a bit of a non-sequitur.
 
Sure, I am not the first one to play devil's advocate :).
 
> If you instead state "DSLs can advantageously use arbitrary tuples for defining data" and then ask "in Smalltalk what are the most convenient ways to define tuples?" you end up with "brace construct".
 
See, that's the kind of assertion I'd like more details about.  For example, why do DSLs advantageously use arbitrary tuples for defining data?  What is the nature of this data?  At one point, I was working on an application that had a bunch of new functionality implemented with domain objects passed around in arrays of size 20 or more.  You can imagine the mess.  So, how is the DSL case different?  We may disagree on the brace construct and where it belongs, but at least I'd like to know why a particular approach to implementing DSLs benefits so much from sort-of literal arrays.  Is there an example that can be shared succintly?
 
> If instead you're really asking "why are tuples used in DSLs" isn't it obvious that, as Vassili points out, an arbitrary list is a very useful starting point for defining arbitrary data?
 
Lists, sure.  But what is the purpose of using lists like that?  In other words, why is the context in which the data is defined so... umm, vague (?... or unconstrained?... or non-specific?...) that data has to be defined in terms of lists?  I'd guess I have implemented a number of DSLs within Smalltalk before, but I do not remember the need to create lists like that.  One that comes to mind is the Minesweeper solver.  It has several lists of constraints, and setting up the problem requires specifying a list initial information.  I guess I could have written something like
 
solver
  add: {1. 'ab'};
  add: {2. 'bcd'}.
 
At least in the example above, I find the use of {...} rather inexpressive.  What I did looks more like
 
solver thereAre: 1 in: 'ab'.
solver thereAre: 2 in: 'bcd'.
 
Is this the kind of situation you're talking about?
 
Andres.
 


From: [hidden email] [mailto:[hidden email]] On Behalf Of Eliot Miranda
Sent: Monday, June 29, 2009 8:46 PM
To: Visualworks Mailing List
Subject: Re: [vwnc] BraceConstructor breaks refactorings (tentative fixincluded)



On Mon, Jun 29, 2009 at 4:20 PM, Andres Valloud <[hidden email]> wrote:
Back in the day I used the comma message to create tuples.  However, I
meant to ask why are tuples so prevalent in embedded DSLs, as opposed to
more specific objects.  We could certainly replace Association, Point
and a bunch of others with tuples, but we don't do that...

That's a bit of a non-sequitur.  Associations have a specific use as elements of Dictionaries that makes them very useful.  They're ok for pairs, although key and value are arguably not as intuitive as first and second or first and last.  Points are even more specific than associations.  Both have arity 2, so can't conveniently be used for higher arities, foo y y y is non-obvious.  If you instead state "DSLs can advantageously use arbitrary tuples for defining data" and then ask "in Smalltalk what are the most convenient ways to define tuples?" you end up with "brace construct".

If instead you're really asking "why are tuples used in DSLs" isn't it obvious that, as Vassili points out, an arbitrary list is a very useful starting point for defining arbitrary data?  Look at e.g. JavaScript's JSON.  It would be great to have JSON syntax in Smalltalk, no?  That and destructuring bind.
 


Eliot Miranda wrote:
>
>
> On Mon, Jun 29, 2009 at 3:37 PM, Andres Valloud
> <[hidden email]
> <mailto:[hidden email]>> wrote:

>
>     Your argument seems to imply the only useful alternative for embedded
>     DSLs is to use brace constructs.  Why are arrays so prevalent in
>     embedded DSLs?  Why don't more sophisticated (?) objects appear more
>     naturally in embedded DSLs, thus making the need for arrays less
>     pressing?
>
>
> How do you construct those more complex objects in the first place
> without adding syntactic extensions for new literal constructs?  Array
> literals are a general "make me a tuple" construct with reasonable
> generality.
>
>
>
>
>
>     Vassili Bykov wrote:
>     > 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] <mailto:[hidden email]>
>     > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
>     >
>     >
>     _______________________________________________
>     vwnc mailing list
>     [hidden email] <mailto:[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 fix included)

Vassili Bykov-2
In reply to this post by Andres Valloud-4
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
Reply | Threaded
Open this post in threaded view
|

Re: [vwnc] BraceConstructor breaks refactorings (tentative fix included)

stephane ducasse
In reply to this post by Eliot Miranda-2
{ } got introduced in Squeak and even if at the beginning I found that  
strange, there are definitively really useful.
I agree with vassili that literal arrays are an artefact of lack of  
powerful compiler analysis.
So if VW would have { } it would be good for it.

Stef

On Jun 30, 2009, at 5:46 AM, Eliot Miranda wrote:

>
>
> On Mon, Jun 29, 2009 at 4:20 PM, Andres Valloud <[hidden email]
> > wrote:
> Back in the day I used the comma message to create tuples.  However, I
> meant to ask why are tuples so prevalent in embedded DSLs, as  
> opposed to
> more specific objects.  We could certainly replace Association, Point
> and a bunch of others with tuples, but we don't do that...
>
> That's a bit of a non-sequitur.  Associations have a specific use as  
> elements of Dictionaries that makes them very useful.  They're ok  
> for pairs, although key and value are arguably not as intuitive as  
> first and second or first and last.  Points are even more specific  
> than associations.  Both have arity 2, so can't conveniently be used  
> for higher arities, foo y y y is non-obvious.  If you instead state  
> "DSLs can advantageously use arbitrary tuples for defining data" and  
> then ask "in Smalltalk what are the most convenient ways to define  
> tuples?" you end up with "brace construct".
>
> If instead you're really asking "why are tuples used in DSLs" isn't  
> it obvious that, as Vassili points out, an arbitrary list is a very  
> useful starting point for defining arbitrary data?  Look at e.g.  
> JavaScript's JSON.  It would be great to have JSON syntax in  
> Smalltalk, no?  That and destructuring bind.
>
>
>
> Eliot Miranda wrote:
> >
> >
> > On Mon, Jun 29, 2009 at 3:37 PM, Andres Valloud
> > <[hidden email]
> > <mailto:[hidden email]>> wrote:
> >
> >     Your argument seems to imply the only useful alternative for  
> embedded
> >     DSLs is to use brace constructs.  Why are arrays so prevalent in
> >     embedded DSLs?  Why don't more sophisticated (?) objects  
> appear more
> >     naturally in embedded DSLs, thus making the need for arrays less
> >     pressing?
> >
> >
> > How do you construct those more complex objects in the first place
> > without adding syntactic extensions for new literal constructs?  
> Array
> > literals are a general "make me a tuple" construct with reasonable
> > generality.
> >
> >
> >
> >
> >
> >     Vassili Bykov wrote:
> >     > 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] <mailto:[hidden email]>
> >     > http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
> >     >
> >     >
> >     _______________________________________________
> >     vwnc mailing list
> >     [hidden email] <mailto:[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-6
In reply to this post by Vassili Bykov-2
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
Reply | Threaded
Open this post in threaded view
|

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

Andres Valloud-6
In reply to this post by Vassili Bykov-2
After I fix #someFactorials, some other package I load adds an override to #factorial.  Assuming {...} is built at compile time, should #someFactorials be recompiled?  How do I figure out which methods should or shouldn't be recompiled?

-----Original Message-----
From: 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
Reply | Threaded
Open this post in threaded view
|

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

Stéphane Ducasse
In reply to this post by Andres Valloud-6

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
12