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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 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.
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
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 |
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 |
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 |
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 |
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 |
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 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.
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
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 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.
_______________________________________________ vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc |
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 |
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 |
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 |
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 |
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 |
Free forum by Nabble | Edit this page |