Question: I've always wondered what this "isSelfEvaluating" stuff is
good for. There are thirteen implementors and a single user in Array>>printOn:. Is there any *need* for Array>>printOn: to print a "self evaluating" expression? Why not just Array(element1, element2, ....) just like any other collection? We'd remove some 20 methods with no downside that I am aware of. Cheers, - Andreas |
2009/10/30 Andreas Raab <[hidden email]>:
> Question: I've always wondered what this "isSelfEvaluating" stuff is good > for. There are thirteen implementors and a single user in Array>>printOn:. > Is there any *need* for Array>>printOn: to print a "self evaluating" > expression? Why not just Array(element1, element2, ....) just like any other > collection? > > We'd remove some 20 methods with no downside that I am aware of. > > Cheers, > - Andreas > > Yes, that seems a bit expensive. Don't know about other usage... Nicolas |
In reply to this post by Andreas.Raab
On Fri, Oct 30, 2009 at 12:55 PM, Andreas Raab <[hidden email]> wrote: Question: I've always wondered what this "isSelfEvaluating" stuff is good for. There are thirteen implementors and a single user in Array>>printOn:. Is there any *need* for Array>>printOn: to print a "self evaluating" expression? Why not just Array(element1, element2, ....) just like any other collection? Shouldn't the test be isLiteral instead of isSelfEvaluating? c.f. storeOn: storeOnStream:.
|
2009/10/30 Eliot Miranda <[hidden email]>:
> > > On Fri, Oct 30, 2009 at 12:55 PM, Andreas Raab <[hidden email]> wrote: >> >> Question: I've always wondered what this "isSelfEvaluating" stuff is good >> for. There are thirteen implementors and a single user in Array>>printOn:. >> Is there any *need* for Array>>printOn: to print a "self evaluating" >> expression? Why not just Array(element1, element2, ....) just like any other >> collection? >> >> We'd remove some 20 methods with no downside that I am aware of. > > Shouldn't the test be isLiteral instead of isSelfEvaluating? c.f. storeOn: > storeOnStream:. > Yes that's the default behaviour of Object>>isSelfEvaluating. But the 3.9 team wanted to extend this to a few other objects, like Point, Rectangle, ... The reason for this extension is the presence of brace notation. Nicolas >> >> Cheers, >> - Andreas >> > > > > > |
On Fri, Oct 30, 2009 at 1:45 PM, Nicolas Cellier <[hidden email]> wrote: 2009/10/30 Eliot Miranda <[hidden email]>: Right. So with braces one either prints arrays as literals or as braces. Whether an element of an array prints as self-evaluating is up to it right? e.g. I would prefer it if
Array with: OrderedCollection new prints as { OrderedCollection () } than #(OrderedCollection ()). The first is a syntax error but the second is completely ambiguous (i.e. evaluates to #(#OrderedCollection #())).
So I don't see the need to provide isSelfEvaluating. isLiteral gives you all that you need to avoid printing an Array as a literal when it isn't. And if you've drunk the braces kool aid (which I have, while studying my agrippa) you're happy with Arrays printing themselves as brace constructs naively even when the naive print produces non-code.
|
2009/10/30 Eliot Miranda <[hidden email]>:
> > > On Fri, Oct 30, 2009 at 1:45 PM, Nicolas Cellier > <[hidden email]> wrote: >> >> 2009/10/30 Eliot Miranda <[hidden email]>: >> > >> > >> > On Fri, Oct 30, 2009 at 12:55 PM, Andreas Raab <[hidden email]> >> > wrote: >> >> >> >> Question: I've always wondered what this "isSelfEvaluating" stuff is >> >> good >> >> for. There are thirteen implementors and a single user in >> >> Array>>printOn:. >> >> Is there any *need* for Array>>printOn: to print a "self evaluating" >> >> expression? Why not just Array(element1, element2, ....) just like any >> >> other >> >> collection? >> >> >> >> We'd remove some 20 methods with no downside that I am aware of. >> > >> > Shouldn't the test be isLiteral instead of isSelfEvaluating? c.f. >> > storeOn: >> > storeOnStream:. >> > >> >> Yes that's the default behaviour of Object>>isSelfEvaluating. >> But the 3.9 team wanted to extend this to a few other objects, like >> Point, Rectangle, ... >> The reason for this extension is the presence of brace notation. > > Right. So with braces one either prints arrays as literals or as braces. > Whether an element of an array prints as self-evaluating is up to it right? > e.g. I would prefer it if > Array with: OrderedCollection new > currently it is a 3 stages rocket: Array with: 1. -> #(1) Array with: 1@2. -> {1@2} Array with: OrderedCollection new. -> an Array(an OrderedCollection()) > prints as { OrderedCollection () } than #(OrderedCollection ()). The first > is a syntax error but the second is completely ambiguous (i.e. evaluates to > #(#OrderedCollection #())). > So I don't see the need to provide isSelfEvaluating. isLiteral gives you > all that you need to avoid printing an Array as a literal when it isn't. > And if you've drunk the braces kool aid (which I have, while studying my > agrippa) you're happy with Arrays printing themselves as brace constructs > naively even when the naive print produces non-code. That's a fair and simple approach. >> >> Nicolas >> >> >> >> >> Cheers, >> >> - Andreas |
2009/10/30 Nicolas Cellier <[hidden email]>:
> 2009/10/30 Eliot Miranda <[hidden email]>: > currently it is a 3 stages rocket: > > Array with: 1. -> #(1) > Array with: 1@2. -> {1@2} > Array with: OrderedCollection new. -> an Array(an OrderedCollection()) > >> prints as { OrderedCollection () } than #(OrderedCollection ()). The first >> is a syntax error but the second is completely ambiguous (i.e. evaluates to >> #(#OrderedCollection #())). >> So I don't see the need to provide isSelfEvaluating. isLiteral gives you >> all that you need to avoid printing an Array as a literal when it isn't. >> And if you've drunk the braces kool aid (which I have, while studying my >> agrippa) you're happy with Arrays printing themselves as brace constructs >> naively even when the naive print produces non-code. > > That's a fair and simple approach. > I gave it a try, now every Array print as #( ... ) if literal, { ... } otherwise Please vote |
On 30.10.2009, at 19:13, Nicolas Cellier wrote: > 2009/10/30 Nicolas Cellier <[hidden email]>: >> 2009/10/30 Eliot Miranda <[hidden email]>: >> currently it is a 3 stages rocket: >> >> Array with: 1. -> #(1) >> Array with: 1@2. -> {1@2} >> Array with: OrderedCollection new. -> an Array(an OrderedCollection >> ()) >> >>> prints as { OrderedCollection () } than #(OrderedCollection ()). >>> The first >>> is a syntax error but the second is completely ambiguous (i.e. >>> evaluates to >>> #(#OrderedCollection #())). >>> So I don't see the need to provide isSelfEvaluating. isLiteral >>> gives you >>> all that you need to avoid printing an Array as a literal when it >>> isn't. >>> And if you've drunk the braces kool aid (which I have, while >>> studying my >>> agrippa) you're happy with Arrays printing themselves as brace >>> constructs >>> naively even when the naive print produces non-code. >> >> That's a fair and simple approach. >> > > I gave it a try, now every Array print as #( ... ) if literal, > { ... } otherwise > Please vote I like the self-evaluating print string. It's useful for interactive use and debugging. Plus shorter, usually. - Bert - |
2009/10/31 Bert Freudenberg <[hidden email]>:
> > On 30.10.2009, at 19:13, Nicolas Cellier wrote: > >> 2009/10/30 Nicolas Cellier <[hidden email]>: >>> >>> 2009/10/30 Eliot Miranda <[hidden email]>: >>> currently it is a 3 stages rocket: >>> >>> Array with: 1. -> #(1) >>> Array with: 1@2. -> {1@2} >>> Array with: OrderedCollection new. -> an Array(an OrderedCollection()) >>> >>>> prints as { OrderedCollection () } than #(OrderedCollection ()). The >>>> first >>>> is a syntax error but the second is completely ambiguous (i.e. evaluates >>>> to >>>> #(#OrderedCollection #())). >>>> So I don't see the need to provide isSelfEvaluating. isLiteral gives >>>> you >>>> all that you need to avoid printing an Array as a literal when it isn't. >>>> And if you've drunk the braces kool aid (which I have, while studying >>>> my >>>> agrippa) you're happy with Arrays printing themselves as brace >>>> constructs >>>> naively even when the naive print produces non-code. >>> >>> That's a fair and simple approach. >>> >> >> I gave it a try, now every Array print as #( ... ) if literal, { ... } >> otherwise >> Please vote > > I like the self-evaluating print string. It's useful for interactive use and > debugging. Plus shorter, usually. > > - Bert - > Hi Bert, You don't loose it. Array that previously printed as literal #( .. ) still do Array that previously printed with braces { .. } (isSelfEvaluating) still do. Array that did print anArray( ... ) now print using { ... } So, you only loose quick identification of Array that can't be re-evaluated to itself Note that isSelfEvaluating is plenty implementors for 1 sender, and was not correct anyway, and would be overkill to correct A killing example: (Array with: (0@0 extent: 1@1) -> 0) So that was the rationale to trade off quick identification Is this acceptable ? |
2009/10/31 Nicolas Cellier <[hidden email]>:
> 2009/10/31 Bert Freudenberg <[hidden email]>: >> >> On 30.10.2009, at 19:13, Nicolas Cellier wrote: >> >>> 2009/10/30 Nicolas Cellier <[hidden email]>: >>>> >>>> 2009/10/30 Eliot Miranda <[hidden email]>: >>>> currently it is a 3 stages rocket: >>>> >>>> Array with: 1. -> #(1) >>>> Array with: 1@2. -> {1@2} >>>> Array with: OrderedCollection new. -> an Array(an OrderedCollection()) >>>> >>>>> prints as { OrderedCollection () } than #(OrderedCollection ()). The >>>>> first >>>>> is a syntax error but the second is completely ambiguous (i.e. evaluates >>>>> to >>>>> #(#OrderedCollection #())). >>>>> So I don't see the need to provide isSelfEvaluating. isLiteral gives >>>>> you >>>>> all that you need to avoid printing an Array as a literal when it isn't. >>>>> And if you've drunk the braces kool aid (which I have, while studying >>>>> my >>>>> agrippa) you're happy with Arrays printing themselves as brace >>>>> constructs >>>>> naively even when the naive print produces non-code. >>>> >>>> That's a fair and simple approach. >>>> >>> >>> I gave it a try, now every Array print as #( ... ) if literal, { ... } >>> otherwise >>> Please vote >> >> I like the self-evaluating print string. It's useful for interactive use and >> debugging. Plus shorter, usually. >> >> - Bert - >> > > Hi Bert, > > You don't loose it. > Array that previously printed as literal #( .. ) still do > Array that previously printed with braces { .. } (isSelfEvaluating) still do. > Array that did print anArray( ... ) now print using { ... } > So, you only loose quick identification of Array that can't be > re-evaluated to itself > > Note that isSelfEvaluating is plenty implementors for 1 sender, and > was not correct anyway, and would be overkill to correct > A killing example: > (Array with: (0@0 extent: 1@1) -> 0) > So that was the rationale to trade off quick identification > > Is this acceptable ? > > My 2 cents. Again, this #isXXXX pattern.. As someone noted before: don't ask - tell. If array wants to print itself as an array literal, why not tell all its elements to print as literals inside the array? Something like #printAsLiteralOn: which prints the object on stream, and returns a boolean which is false if printed result can't be represented as a literal inside array. Then a wrapping #printOn: can choose to use {} syntax, if any of elements failed to print as pure literal. -- Best regards, Igor Stasenko AKA sig. |
2009/10/31 Igor Stasenko <[hidden email]>:
> 2009/10/31 Nicolas Cellier <[hidden email]>: >> 2009/10/31 Bert Freudenberg <[hidden email]>: >>> >>> On 30.10.2009, at 19:13, Nicolas Cellier wrote: >>> >>>> 2009/10/30 Nicolas Cellier <[hidden email]>: >>>>> >>>>> 2009/10/30 Eliot Miranda <[hidden email]>: >>>>> currently it is a 3 stages rocket: >>>>> >>>>> Array with: 1. -> #(1) >>>>> Array with: 1@2. -> {1@2} >>>>> Array with: OrderedCollection new. -> an Array(an OrderedCollection()) >>>>> >>>>>> prints as { OrderedCollection () } than #(OrderedCollection ()). The >>>>>> first >>>>>> is a syntax error but the second is completely ambiguous (i.e. evaluates >>>>>> to >>>>>> #(#OrderedCollection #())). >>>>>> So I don't see the need to provide isSelfEvaluating. isLiteral gives >>>>>> you >>>>>> all that you need to avoid printing an Array as a literal when it isn't. >>>>>> And if you've drunk the braces kool aid (which I have, while studying >>>>>> my >>>>>> agrippa) you're happy with Arrays printing themselves as brace >>>>>> constructs >>>>>> naively even when the naive print produces non-code. >>>>> >>>>> That's a fair and simple approach. >>>>> >>>> >>>> I gave it a try, now every Array print as #( ... ) if literal, { ... } >>>> otherwise >>>> Please vote >>> >>> I like the self-evaluating print string. It's useful for interactive use and >>> debugging. Plus shorter, usually. >>> >>> - Bert - >>> >> >> Hi Bert, >> >> You don't loose it. >> Array that previously printed as literal #( .. ) still do >> Array that previously printed with braces { .. } (isSelfEvaluating) still do. >> Array that did print anArray( ... ) now print using { ... } >> So, you only loose quick identification of Array that can't be >> re-evaluated to itself >> >> Note that isSelfEvaluating is plenty implementors for 1 sender, and >> was not correct anyway, and would be overkill to correct >> A killing example: >> (Array with: (0@0 extent: 1@1) -> 0) >> So that was the rationale to trade off quick identification >> >> Is this acceptable ? >> >> > > My 2 cents. > > Again, this #isXXXX pattern.. > As someone noted before: don't ask - tell. > If array wants to print itself as an array literal, why not tell all > its elements to print as literals inside the array? > Something like > #printAsLiteralOn: > which prints the object on stream, and returns a boolean which is > false if printed result can't be represented as a literal inside > array. > Then a wrapping #printOn: can choose to use {} syntax, if any of > elements failed to print as pure literal. > > Yes, and printing seems almost sole use of #isLiteral. but that would also mean rewinding the stream (or duplicating the print on a temporary stream if we care of non positionable streams) and I'm not sure it's particularly more simple/expandable/readable Beware, someone clever might refactor #printAsLiteralOn: code as printAsLiteralOn: aStream self isLiteral [^false]. self printOn: aStream. ^true Or another clever one would implement missing generic #isLiteral isLiteral ^self printLiteralOn: Stream null Just kidding Nicolas > -- > Best regards, > Igor Stasenko AKA sig. > > |
2009/10/31 Nicolas Cellier <[hidden email]>:
> 2009/10/31 Igor Stasenko <[hidden email]>: >> 2009/10/31 Nicolas Cellier <[hidden email]>: >>> 2009/10/31 Bert Freudenberg <[hidden email]>: >>>> >>>> On 30.10.2009, at 19:13, Nicolas Cellier wrote: >>>> >>>>> 2009/10/30 Nicolas Cellier <[hidden email]>: >>>>>> >>>>>> 2009/10/30 Eliot Miranda <[hidden email]>: >>>>>> currently it is a 3 stages rocket: >>>>>> >>>>>> Array with: 1. -> #(1) >>>>>> Array with: 1@2. -> {1@2} >>>>>> Array with: OrderedCollection new. -> an Array(an OrderedCollection()) >>>>>> >>>>>>> prints as { OrderedCollection () } than #(OrderedCollection ()). The >>>>>>> first >>>>>>> is a syntax error but the second is completely ambiguous (i.e. evaluates >>>>>>> to >>>>>>> #(#OrderedCollection #())). >>>>>>> So I don't see the need to provide isSelfEvaluating. isLiteral gives >>>>>>> you >>>>>>> all that you need to avoid printing an Array as a literal when it isn't. >>>>>>> And if you've drunk the braces kool aid (which I have, while studying >>>>>>> my >>>>>>> agrippa) you're happy with Arrays printing themselves as brace >>>>>>> constructs >>>>>>> naively even when the naive print produces non-code. >>>>>> >>>>>> That's a fair and simple approach. >>>>>> >>>>> >>>>> I gave it a try, now every Array print as #( ... ) if literal, { ... } >>>>> otherwise >>>>> Please vote >>>> >>>> I like the self-evaluating print string. It's useful for interactive use and >>>> debugging. Plus shorter, usually. >>>> >>>> - Bert - >>>> >>> >>> Hi Bert, >>> >>> You don't loose it. >>> Array that previously printed as literal #( .. ) still do >>> Array that previously printed with braces { .. } (isSelfEvaluating) still do. >>> Array that did print anArray( ... ) now print using { ... } >>> So, you only loose quick identification of Array that can't be >>> re-evaluated to itself >>> >>> Note that isSelfEvaluating is plenty implementors for 1 sender, and >>> was not correct anyway, and would be overkill to correct >>> A killing example: >>> (Array with: (0@0 extent: 1@1) -> 0) >>> So that was the rationale to trade off quick identification >>> >>> Is this acceptable ? >>> >>> >> >> My 2 cents. >> >> Again, this #isXXXX pattern.. >> As someone noted before: don't ask - tell. >> If array wants to print itself as an array literal, why not tell all >> its elements to print as literals inside the array? >> Something like >> #printAsLiteralOn: >> which prints the object on stream, and returns a boolean which is >> false if printed result can't be represented as a literal inside >> array. >> Then a wrapping #printOn: can choose to use {} syntax, if any of >> elements failed to print as pure literal. >> >> > > Yes, and printing seems almost sole use of #isLiteral. > but that would also mean rewinding the stream > (or duplicating the print on a temporary stream if we care of non > positionable streams) > and I'm not sure it's particularly more simple/expandable/readable > would be better. The problem with isXXX pattern that its often hides the real intent of developer, for what purposes this test is used. A more explanatory selector can be choosen, like #canBePrintedAsLiteral, then there will be no confusion whether such method useful or not and for what purpose. Personally, i assumed that isLiteral test exists for quite different purpose - to test whether a given object is (or can be) referenced inside one of compiled methods literal frame. So, then some code could test and avoid modifying the literal arrays, or other compound literal objects, which should be immutable, because as we know Squeak VM don't provides immutability flag for objects. > Beware, someone clever might refactor #printAsLiteralOn: code as > printAsLiteralOn: aStream > self isLiteral [^false]. > self printOn: aStream. > ^true > > Or another clever one would implement missing generic #isLiteral > isLiteral > ^self printLiteralOn: Stream null > > Just kidding > But seriously, it is important to choose carefully the message selector, to avoid confusion and abuses. > Nicolas > >> -- >> Best regards, >> Igor Stasenko AKA sig. >> >> > > -- Best regards, Igor Stasenko AKA sig. |
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote:
> Array that previously printed as literal #( .. ) still do > Array that previously printed with braces { .. } (isSelfEvaluating) still do. > Array that did print anArray( ... ) now print using { ... } > So, you only loose quick identification of Array that can't be > re-evaluated to itself > > Note that isSelfEvaluating is plenty implementors for 1 sender, and > was not correct anyway, and would be overkill to correct > A killing example: > (Array with: (0@0 extent: 1@1) -> 0) > So that was the rationale to trade off quick identification > > Is this acceptable ? +1. I like it. Cheers, - Andreas |
In reply to this post by Nicolas Cellier
> Yes, and printing seems almost sole use of #isLiteral. I use it in my package LambdaMessageSend, for block-compiling. If the meaning of #isLiteral is to indicate that what is printed can be read back (i.e. will be correctly parsed) then I think it is a very useful message that we should keep. Stef |
On 31.10.2009, at 09:19, Stéphane Rollandin wrote: > >> Yes, and printing seems almost sole use of #isLiteral. > > I use it in my package LambdaMessageSend, for block-compiling. > > If the meaning of #isLiteral is to indicate that what is printed can > be read back (i.e. will be correctly parsed) then I think it is a > very useful message that we should keep. #isLiteral mainly indicates which objects can be created at compile time. They are literally inserted in the compiled method. This must match the syntax definition of Squeak. There is no question about not keeping it. - Bert - |
>> If the meaning of #isLiteral is to indicate that what is printed can
>> be read back (i.e. will be correctly parsed) then I think it is a very >> useful message that we should keep. > > #isLiteral mainly indicates which objects can be created at compile > time. They are literally inserted in the compiled method. This must > match the syntax definition of Squeak. There is no question about not > keeping it. now I'm confused. are all objects anwering true to #isLiteral also have a printed form that can be read back ? should they ? Stef |
2009/10/31 Stéphane Rollandin <[hidden email]>:
>>> If the meaning of #isLiteral is to indicate that what is printed can be >>> read back (i.e. will be correctly parsed) then I think it is a very useful >>> message that we should keep. >> >> #isLiteral mainly indicates which objects can be created at compile time. >> They are literally inserted in the compiled method. This must match the >> syntax definition of Squeak. There is no question about not keeping it. > > now I'm confused. are all objects anwering true to #isLiteral also have a > printed form that can be read back ? should they ? > > Stef > I think this is used as a feature at least in Decompiler. But can they all be read back ? Float can't always with the current implementation (they don't print exactly). (Compiler evaluate: Float halfPi printString) = Float halfPi Nicolas |
In reply to this post by Stéphane Rollandin
On 31.10.2009, at 09:50, Stéphane Rollandin wrote: >>> If the meaning of #isLiteral is to indicate that what is printed >>> can be read back (i.e. will be correctly parsed) then I think it >>> is a very useful message that we should keep. >> #isLiteral mainly indicates which objects can be created at compile >> time. They are literally inserted in the compiled method. This must >> match the syntax definition of Squeak. There is no question about >> not keeping it. > > now I'm confused. are all objects anwering true to #isLiteral also > have a printed form that can be read back ? should they ? > > Stef It's the other way around - the objects that are recognized syntactically in a literal array #(...) must also answer true from #isLiteral. See Array>>isLiteral. This of course implies their printed form is recognized by the parser. isSelfEvaluating goes beyond literals - e.g., you cannot put a Point into a literal array because of syntactical restrictions, "#(3@4)" is parsed as "#(3 #@ 4)". But its print string can still be made self- evaluating as "{3@4}" which is readable. If you want to force a self- evaluating expression to be printed you need to use storeString In older Squeak versions like 3.8 you had this: {3@4} printString '#(3@4)' But that is not self-evaluating even if to a novice it might look like it was, which is a source of confusion. To avoid that you would need this {3@4} storeString '((Array new: 1) at: 1 put: 3@4; yourself)' which does evaluate to an object equal to the original one, but looks ugly. Now try the same expressions in a more recent Squeak and it's much nicer :) - Bert - |
2009/10/31 Bert Freudenberg <[hidden email]>:
> > On 31.10.2009, at 09:50, Stéphane Rollandin wrote: > >>>> If the meaning of #isLiteral is to indicate that what is printed can be >>>> read back (i.e. will be correctly parsed) then I think it is a very useful >>>> message that we should keep. >>> >>> #isLiteral mainly indicates which objects can be created at compile time. >>> They are literally inserted in the compiled method. This must match the >>> syntax definition of Squeak. There is no question about not keeping it. >> >> now I'm confused. are all objects anwering true to #isLiteral also have a >> printed form that can be read back ? should they ? >> >> Stef > > It's the other way around - the objects that are recognized syntactically in > a literal array #(...) must also answer true from #isLiteral. See > Array>>isLiteral. This of course implies their printed form is recognized by > the parser. > > isSelfEvaluating goes beyond literals - e.g., you cannot put a Point into a > literal array because of syntactical restrictions, "#(3@4)" is parsed as > "#(3 #@ 4)". But its print string can still be made self-evaluating as > "{3@4}" which is readable. If you want to force a self-evaluating expression > to be printed you need to use storeString > > In older Squeak versions like 3.8 you had this: > > {3@4} printString > '#(3@4)' > > But that is not self-evaluating even if to a novice it might look like it > was, which is a source of confusion. To avoid that you would need this > > {3@4} storeString > '((Array new: 1) at: 1 put: 3@4; yourself)' > > which does evaluate to an object equal to the original one, but looks ugly. > Now try the same expressions in a more recent Squeak and it's much nicer :) > > - Bert - > Hey, wait Bert, you're selling more than we have ! #isSelfEvaluating is just embellishing printString, it does nothing for storeString... If we want to use it for a better storeString, then we have to solve ((0@0 extent: 1@1) -> 0) printString first. Nicolas |
Free forum by Nabble | Edit this page |