While at isSelfEvaluating, I wonder why we do not abuse {..} notation
a bit more. Instead of printing 'aSet( 0@0 1@2 )' we could just make it evaluate proof '{0@0. 1@2} asSet' Of course, with limited stream, we take the risk of loosing trailing ' asSet' information. So we can also print using a less nice but still evaluating 'Set newFrom: {0@0. 1@2}'. As a bonus, generalizing this behaviour might also eliminate a few bytecodes and methods from the Kernel. Same for storeOn: What do you think ? |
Nicolas Cellier wrote:
> While at isSelfEvaluating, I wonder why we do not abuse {..} notation > a bit more. > Instead of printing 'aSet( 0@0 1@2 )' > we could just make it evaluate proof '{0@0. 1@2} asSet' > > Of course, with limited stream, we take the risk of loosing trailing ' > asSet' information. > So we can also print using a less nice but still evaluating 'Set > newFrom: {0@0. 1@2}'. > > As a bonus, generalizing this behaviour might also eliminate a few > bytecodes and methods from the Kernel. > > Same for storeOn: > > What do you think ? -1. The goal of printing isn't to make parsing easier. In fact I find this to be the least useful application of {} - the advantage of the syntax form is that it is immediately recognized and consequently requires less effort than having "an Array(". That you can also evaluate it in some situations is a useful side effect but no more. Cheers, - Andreas |
2009/11/3 Andreas Raab <[hidden email]>:
> Nicolas Cellier wrote: >> >> While at isSelfEvaluating, I wonder why we do not abuse {..} notation >> a bit more. >> Instead of printing 'aSet( 0@0 1@2 )' >> we could just make it evaluate proof '{0@0. 1@2} asSet' >> >> Of course, with limited stream, we take the risk of loosing trailing ' >> asSet' information. >> So we can also print using a less nice but still evaluating 'Set >> newFrom: {0@0. 1@2}'. >> >> As a bonus, generalizing this behaviour might also eliminate a few >> bytecodes and methods from the Kernel. >> >> Same for storeOn: >> >> What do you think ? > > -1. The goal of printing isn't to make parsing easier. In fact I find this > to be the least useful application of {} - the advantage of the syntax form > is that it is immediately recognized and consequently requires less effort > than having "an Array(". That you can also evaluate it in some situations is > a useful side effect but no more. > > Cheers, > - Andreas > OK, I see ' newFrom: ' can be considered as noise, so we can't have our cake and eat it too ? I find the fact that simple objects print as a simple code snippet such a nice feature though... Set << {0@0. 1@2} would be short, but I guess introducing a new binary selector will be hard to sell :) Nicolas |
On Tue, Nov 3, 2009 at 1:06 PM, Nicolas Cellier <[hidden email]> wrote: 2009/11/3 Andreas Raab <[hidden email]>: yuck. asSet is readable and in the Smalltalk tradition. << sMLells ;)
|
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote:
> OK, I see ' newFrom: ' can be considered as noise, so we can't have > our cake and eat it too ? > I find the fact that simple objects print as a simple code snippet > such a nice feature though... But why? How often have you taken the result of something and evaluated it again (not counting literals)? It seems an extremely rare case compared with what we mostly need to do: Quickly understand the kind of collection we're looking at and its contents. The ClassName(elem1, elem2) printing achieves this with minimal complications. If you really want the code to construct the object send storeString. Cheers, - Andreas |
In reply to this post by Eliot Miranda-2
2009/11/3 Eliot Miranda <[hidden email]>:
> > > On Tue, Nov 3, 2009 at 1:06 PM, Nicolas Cellier > <[hidden email]> wrote: >> >> 2009/11/3 Andreas Raab <[hidden email]>: >> > Nicolas Cellier wrote: >> >> >> >> While at isSelfEvaluating, I wonder why we do not abuse {..} notation >> >> a bit more. >> >> Instead of printing 'aSet( 0@0 1@2 )' >> >> we could just make it evaluate proof '{0@0. 1@2} asSet' >> >> >> >> Of course, with limited stream, we take the risk of loosing trailing ' >> >> asSet' information. >> >> So we can also print using a less nice but still evaluating 'Set >> >> newFrom: {0@0. 1@2}'. >> >> >> >> As a bonus, generalizing this behaviour might also eliminate a few >> >> bytecodes and methods from the Kernel. >> >> >> >> Same for storeOn: >> >> >> >> What do you think ? >> > >> > -1. The goal of printing isn't to make parsing easier. In fact I find >> > this >> > to be the least useful application of {} - the advantage of the syntax >> > form >> > is that it is immediately recognized and consequently requires less >> > effort >> > than having "an Array(". That you can also evaluate it in some >> > situations is >> > a useful side effect but no more. >> > >> > Cheers, >> > - Andreas >> > >> >> OK, I see ' newFrom: ' can be considered as noise, so we can't have >> our cake and eat it too ? >> I find the fact that simple objects print as a simple code snippet >> such a nice feature though... >> Set << {0@0. 1@2} would be short, but I guess introducing a new binary >> selector will be hard to sell :) > > yuck. asSet is readable and in the Smalltalk tradition. << sMLells ;) Like http://en.wikipedia.org/wiki/ML_%28programming_language%29 ? Oh, didn't know about this one http://en.wikipedia.org/wiki/Miranda_%28programming_language%29 Using asSet is taking the risk of loosing class information because of printStringLimitedTo: limit "Answer a String whose characters are a description of the receiver. If you want to print without a character limit, use fullPrintString." | limitedString | limitedString := String streamContents: [:s | self printOn: s] limitedTo: limit. limitedString size < limit ifTrue: [^ limitedString]. ^ limitedString , '...etc...' >> >> Nicolas >> > > > > > |
In reply to this post by Andreas.Raab
2009/11/3 Andreas Raab <[hidden email]>:
> Nicolas Cellier wrote: >> >> OK, I see ' newFrom: ' can be considered as noise, so we can't have >> our cake and eat it too ? >> I find the fact that simple objects print as a simple code snippet >> such a nice feature though... > > But why? How often have you taken the result of something and evaluated it > again (not counting literals)? It seems an extremely rare case compared with > what we mostly need to do: Quickly understand the kind of collection we're > looking at and its contents. The ClassName(elem1, elem2) printing achieves > this with minimal complications. > > If you really want the code to construct the object send storeString. > > Cheers, > - Andreas > > Yes, I understand that. The main use I see is to quickly modify in an inspector, especially in the debugger. I find it also convenient for toying in workspace and line-editing like scripts. Nicolas |
In reply to this post by Nicolas Cellier
On Tue, Nov 3, 2009 at 1:51 PM, Nicolas Cellier <[hidden email]> wrote: 2009/11/3 Eliot Miranda <[hidden email]>: ML. I remember seeing an ML program at Queen Mary that had about 25 user-defined operators in its precedence table. One has to be a sadist or a monk to define one's own operators with one's own precedence. A sadist if one expects anyone else to read the program, and a monk otherwise :)
I can sort of live with << and >> for shift because they're used in more than just C, but overloading it for collection creation is IMO a step too far :) Oh, didn't know about this one |
2009/11/3 Eliot Miranda <[hidden email]>:
> > > On Tue, Nov 3, 2009 at 1:51 PM, Nicolas Cellier > <[hidden email]> wrote: >> >> 2009/11/3 Eliot Miranda <[hidden email]>: >> > >> > >> > On Tue, Nov 3, 2009 at 1:06 PM, Nicolas Cellier >> > <[hidden email]> wrote: >> >> >> >> 2009/11/3 Andreas Raab <[hidden email]>: >> >> > Nicolas Cellier wrote: >> >> >> >> >> >> While at isSelfEvaluating, I wonder why we do not abuse {..} >> >> >> notation >> >> >> a bit more. >> >> >> Instead of printing 'aSet( 0@0 1@2 )' >> >> >> we could just make it evaluate proof '{0@0. 1@2} asSet' >> >> >> >> >> >> Of course, with limited stream, we take the risk of loosing trailing >> >> >> ' >> >> >> asSet' information. >> >> >> So we can also print using a less nice but still evaluating 'Set >> >> >> newFrom: {0@0. 1@2}'. >> >> >> >> >> >> As a bonus, generalizing this behaviour might also eliminate a few >> >> >> bytecodes and methods from the Kernel. >> >> >> >> >> >> Same for storeOn: >> >> >> >> >> >> What do you think ? >> >> > >> >> > -1. The goal of printing isn't to make parsing easier. In fact I find >> >> > this >> >> > to be the least useful application of {} - the advantage of the >> >> > syntax >> >> > form >> >> > is that it is immediately recognized and consequently requires less >> >> > effort >> >> > than having "an Array(". That you can also evaluate it in some >> >> > situations is >> >> > a useful side effect but no more. >> >> > >> >> > Cheers, >> >> > - Andreas >> >> > >> >> >> >> OK, I see ' newFrom: ' can be considered as noise, so we can't have >> >> our cake and eat it too ? >> >> I find the fact that simple objects print as a simple code snippet >> >> such a nice feature though... >> >> Set << {0@0. 1@2} would be short, but I guess introducing a new binary >> >> selector will be hard to sell :) >> > >> > yuck. asSet is readable and in the Smalltalk tradition. << sMLells ;) >> >> Like http://en.wikipedia.org/wiki/ML_%28programming_language%29 ? > > ML. I remember seeing an ML program at Queen Mary that had about 25 > user-defined operators in its precedence table. One has to be a sadist or a > monk to define one's own operators with one's own precedence. A sadist if > one expects anyone else to read the program, and a monk otherwise :) > I can sort of live with << and >> for shift because they're used in more > than just C, but overloading it for collection creation is IMO a step too > far :) Choice of << was in the same vein as C++ stream. t's a kind of left arrow indicating streaming direction (fill my Set with...). And <- is not a valid binary selector according to st80 syntax (unless http://bugs.squeak.org/view.php?id=3616) I agree on your first argument, binary selectors are hard to sell for this very reason: they are cryptic when keywords are expressive... and we have already two #newFrom: #withAll: for that purpose... ... and also {} asSet, or {} as: Set. Probably too many already ! Having a single selector with totally different meanings is also not the best idea. It makes following senders chain a bit difficult. Though (Set >> Set selectors anyOne) has nothing to do with a shift and the context greatly helps. That's why I dared proposing <<, but without much conviction, see the :) Nicolas |
In reply to this post by Nicolas Cellier
Nicolas Cellier wrote:
> The main use I see is to quickly modify in an inspector, especially in > the debugger. Fair enough. But in this case, wouldn't it be better if we had a "copy storeString" item in the inspector (we already have "copy name" for the name of the variable)? Or even "show storeString"? I really dislike the idea to clutter something that everyone needs to understand every single time they look at with stuff that only a few people may use in even fewer situations. Cheers, - Andreas |
2009/11/4 Andreas Raab <[hidden email]>:
> Nicolas Cellier wrote: >> >> The main use I see is to quickly modify in an inspector, especially in >> the debugger. > > Fair enough. But in this case, wouldn't it be better if we had a "copy > storeString" item in the inspector (we already have "copy name" for the name > of the variable)? Or even "show storeString"? I really dislike the idea to > clutter something that everyone needs to understand every single time they > look at with stuff that only a few people may use in even fewer situations. > > Cheers, > - Andreas > > I don't buy this one. The feature would be usefull for simple objects only, and I prefer to stay away from instVarAt: 1 put: (...) and infinite loop on cyclic object graphs as proposed by current implementation of storeString for any other Object. A traditional inspector window does a better job. Maybe we should better close this subject :) |
On Wed, Nov 4, 2009 at 12:51 AM, Nicolas Cellier <[hidden email]> wrote: 2009/11/4 Andreas Raab <[hidden email]>: No. Actually the abilities I want are to open inspectors on "distant" objects and compare them. For example right now I'm developing a "refactored" virtual machine in which the ObjectMemory is an instance variable of the CoInterpreterSE instead of a superclass of the CoInterpreter. Thing is, this is more than a refactoring and my CoInterpreterSE doesn't fully work yet. I'm running both the new VM and the old VM until they diverge and trying to account for that divergence. Things that are difficult:
- getting both VMs in the same inspector. Right now I have to e.g. in one debugger assign the interpreter to a global. in the other debugger open an inspector on an array of the VM assigned to the global and the local VM.
- comparing instance variables and their state in the two interpreters. Some generic object graph comparer that could display a partial walk over the two object graphs would be fantastic. - better still is the ability to run the two VMs in lock-step, halting when they diverge. Difficult in my case because lots of the computation happens in primitives that are executing generated machine code.
So I think the needs aren't for good print strings. The needs are actually for much higher-level tools that allow one to - compare object graphs with a richer result than merely equal or not, i.e. explore the comparison
- trace the evolution of object graphs during computation, ideally supporting evolution in lock-step of more than one graph, perhaps simply allowing one to record the sequence of evolutions such that one can compare one trace to another
How general is this kind of thing? Do others find themselves looking at this kind of thing often? I fear not. eliot |
On 4-Nov-09, at 9:26 AM, Eliot Miranda wrote: > So I think the needs aren't for good print strings. The needs are > actually for much higher-level tools that allow one to > - compare object graphs with a richer result than merely equal or > not, i.e. explore the comparison > - trace the evolution of object graphs during computation, ideally > supporting evolution in lock-step of more than one graph, perhaps > simply allowing one to record the sequence of evolutions such that > one can compare one trace to another > > How general is this kind of thing? Do others find themselves > looking at this kind of thing often? I fear not. It sounds like you want something akin to omniscient debugging. (See http://www.LambdaCS.com/debugger/debugger.html) . If the VM were instrumented to log all state changes, a debugger- like tool could visualize the changing state of the image over time. For your purposes, you'd just have to compare the logs to find out where they diverged. IIRC John McIntosh did something a bit like this for the Mac VM. It might serve as a starting point, anyway. Colin |
In reply to this post by Eliot Miranda-2
2009/11/4 Eliot Miranda <[hidden email]>:
> > > On Wed, Nov 4, 2009 at 12:51 AM, Nicolas Cellier > <[hidden email]> wrote: >> >> 2009/11/4 Andreas Raab <[hidden email]>: >> > Nicolas Cellier wrote: >> >> >> >> The main use I see is to quickly modify in an inspector, especially in >> >> the debugger. >> > >> > Fair enough. But in this case, wouldn't it be better if we had a "copy >> > storeString" item in the inspector (we already have "copy name" for the >> > name >> > of the variable)? Or even "show storeString"? I really dislike the idea >> > to >> > clutter something that everyone needs to understand every single time >> > they >> > look at with stuff that only a few people may use in even fewer >> > situations. >> > >> > Cheers, >> > - Andreas >> > >> > >> >> I don't buy this one. The feature would be usefull for simple objects >> only, and I prefer to stay away from instVarAt: 1 put: (...) and >> infinite loop on cyclic object graphs as proposed by current >> implementation of storeString for any other Object. >> A traditional inspector window does a better job. >> >> Maybe we should better close this subject :) > > No. Actually the abilities I want are to open inspectors on "distant" > objects and compare them. For example right now I'm developing a > "refactored" virtual machine in which the ObjectMemory is an instance > variable of the CoInterpreterSE instead of a superclass of the > CoInterpreter. Thing is, this is more than a refactoring and my > CoInterpreterSE doesn't fully work yet. I'm running both the new VM and the > old VM until they diverge and trying to account for that divergence. Things > that are difficult: > - getting both VMs in the same inspector. Right now I have to e.g. in one > debugger assign the interpreter to a global. in the other debugger open an > inspector on an array of the VM assigned to the global and the local VM. > - comparing instance variables and their state in the two interpreters. > Some generic object graph comparer that could display a partial walk over > the two object graphs would be fantastic. > - better still is the ability to run the two VMs in lock-step, halting when > they diverge. Difficult in my case because lots of the computation happens > in primitives that are executing generated machine code. > So I think the needs aren't for good print strings. The needs are actually > for much higher-level tools that allow one to > - compare object graphs with a richer result than merely equal or not, i.e. > explore the comparison > - trace the evolution of object graphs during computation, ideally > supporting evolution in lock-step of more than one graph, perhaps simply > allowing one to record the sequence of evolutions such that one can compare > one trace to another > How general is this kind of thing? Do others find themselves looking at > this kind of thing often? I fear not. > eliot > As long as there is no Collection (minor problem) and no changes in intermediate hierarchy levels (big problem), i see no difficulty in comparing two snapshots, but UI definition and efficiency... Cycles have to be detected, but that seems doable. Collections are a bit annoying because elements have no strong signature unlike instVars (but Dictionaries which have strong signature thanks to keys). How to compare {1@0. 2@1. 2@-1} with {1@0. 2@-1} ? How to evaluate longest match in complex trees ? Collections also can be unordered, and partial longest match of unordered Collection smells like combinatorial... If you want to handle changes in hierarchy levels, like for example comparing (ValueHolder with: 1@2) versus (1@2), you are in trouble. I had such a problem 10 years ago for comparing block diagrams with changes in hierarchy... I never found the courage to handle it (though my problem had a "simple" solution consisting in eliminating the hierarchy - that is aggregating all leafs in a flat hierarchy). Comparing two movies (I mean dynamic evolutions of the graph as a serie of snapshots) is way more demanding, maybe one process will arrive to the same result in four steps versus five... So how to control advance of the two ? Plus how to store evolutions in the graphs efficiently ? we wouldn't make a copy of each snapshot, would we ? You have the ability to turn trivial threads into tough subjects indeed... |
Free forum by Nabble | Edit this page |