Hi all,
I'm looking to see if there's any consensus in the community on the issue of adding #value: to Symbol. The commonly proposed reason for adding it is as a hack to allow coding, say, aCollection collect: [:each | each name] as: aCollection collect: #name My personal opinion is that the above is bad style, although it is undoubtedly useful as an shortcut in workspaces. However there is set of cases where I think it provides real value. For instance, I have a class called SortBlock that takes a selector and answers a <diadicValuable> object that can be used to create a SortedCollection: aCollection asSortedCollection: (SortDecreasing by: #name) (it could be abbreviated further, but I've never bothered). I find this valuable enough that I use it almost everywhere (and was very pleased that I did when D5.0.3 changed the optimum case for a sort expression from #< to #<=; I only had to change the definition of SortDecreasing>>value:value: instead of hunting down Blocks all over my code and embedded in View resources). The problem that Symbol>>value: would solve is that, as it stands, I had to make a choice between designing SortBlock to take a selector, or making it take a Block. Taking a block would be more powerful and general, e.g: aCollection asSortedCollection: (SortDecreasing by: [:each | each name subStrings last]) But, in practise the extra power is hardly ever needed, so being able to say *either* of: aCollection asSortedCollection: (SortDecreasing by: #name) aCollection asSortedCollection: (SortDecreasing by: [:each | each name]) would be a Good Thing. The best -- most general -- way to achieve that kind of flexibility would be for Symbol to implement #value:. Now, finally, getting to the questions that I wanted to ask, my problem is that, although I can easily add Symbol>>value: to my *own* image, what happens if I want to publish code that depends on it? The actual case that promoted these musing is, in fact, SortBlock. My initial version depended on Symbol>>value:, but when I added code that depended on SortBlock to my goodies website, I decided that forcing people to accept the Symbol>>value: hack was not acceptable. So I re-wrote SortBlock to remove the ability to take Blocks, restricting it to Symbols only. (And then forgot to remove Symbol>>value: from the package before publishing it, but that's a different story). However SortBlock isn't the only case where I have this sort of dilemma. So, what should I -- or anyone else with the same decision to make -- do: 1) Petition OA to add Symbol>>value: to the base image ? Obviously that makes sense only if there's some agreement that it really would enhance the base, rather than -- say -- encouraging a rather sleazy sort of hackery. 2) Add it to my own published packages ? But that risks irritating people who don't want that kind of addition. (And there is quite a lot of software that I've come across that *I* won't use, just because of similar unwanted additions to the image). What do you think, would it in fact be an irritant ? 3) Just bite the bullet and accept that I can't publish code that depends on interchangeable Symbols and Blocks? Grateful for any feedback... -- chris |
Chris,
How about aCollection asSortedCollection: (SortDecreasing byPerforming: #name) with #byPerforming: doing what it has to do to make it work? Otherwise, the base might offer a solution in the way it handles commands, because symbols and Messages are interchangeable in the #command aspect of buttons etc. Have a good one, Bill -- Wilhelm K. Schwab, Ph.D. [hidden email] |
In reply to this post by Chris Uppal-3
Hi,
My personal thinking after some well-digestion of your the packages and getting some understanding of the great ideas, is below ( maybe superficial, its just guess on my limited experience) : In wanting for the implementation of both working: aCollection asSortedCollection: (SortDescending by: #name). and: aCollection asSortedCollection: (SortDescending by: [:each | each name]) If not adding the method of "Symbol>>value: " to either the base image by OA, or via 3-party packages etc, I might try to write some test in the method: "SortBlock>>value: anObject1 value: anObject2" to test the selector: -- if selector is a Symbol then use "anObject1 perform: selector" etc. -- if selector is a monadicBlock, then use " selector value: anObject1" etc. It's just my personal opinion for the workaround. Best regards. kuo. "Chris Uppal" <[hidden email]> ¼¶¼g©ó¶l¥ó·s»D :3eaa697f$0$45175$[hidden email]... > Hi all, > > I'm looking to see if there's any consensus in the community on the issue of > adding #value: to Symbol. > > The commonly proposed reason for adding it is as a hack to allow coding, say, > > aCollection collect: [:each | each name] > > as: > > aCollection collect: #name > > My personal opinion is that the above is bad style, although it is undoubtedly > useful as an shortcut in workspaces. > > However there is set of cases where I think it provides real value. For > instance, I have a class called SortBlock that takes a selector and answers a > <diadicValuable> object that can be used to create a SortedCollection: > > aCollection asSortedCollection: (SortDecreasing by: #name) > > (it could be abbreviated further, but I've never bothered). I find this > valuable enough that I use it almost everywhere (and was very pleased that I > did when D5.0.3 changed the optimum case for a sort expression from #< to #<=; > I only had to change the definition of SortDecreasing>>value:value: instead of > hunting down Blocks all over my code and embedded in View resources). The > problem that Symbol>>value: would solve is that, as it stands, I had to make a > choice between designing SortBlock to take a selector, or making it take a > Block. Taking a block would be more powerful and general, e.g: > > aCollection asSortedCollection: (SortDecreasing by: > [:each | each name subStrings last]) > > But, in practise the extra power is hardly ever needed, so being able to say > *either* of: > > aCollection asSortedCollection: (SortDecreasing by: #name) > aCollection asSortedCollection: (SortDecreasing by: [:each | each name]) > > would be a Good Thing. The best -- most general -- way to achieve that kind of > flexibility would be for Symbol to implement #value:. > > Now, finally, getting to the questions that I wanted to ask, my problem is > that, although I can easily add Symbol>>value: to my *own* image, what happens > if I want to publish code that depends on it? > > The actual case that promoted these musing is, in fact, SortBlock. My initial > version depended on Symbol>>value:, but when I added code that depended on > SortBlock to my goodies website, I decided that forcing people to accept the > Symbol>>value: hack was not acceptable. So I re-wrote SortBlock to remove the > ability to take Blocks, restricting it to Symbols only. (And then forgot to > remove Symbol>>value: from the package before publishing it, but that's a > different story). However SortBlock isn't the only case where I have this sort > of dilemma. > > So, what should I -- or anyone else with the same decision to make -- do: > > 1) Petition OA to add Symbol>>value: to the base image ? Obviously that makes > sense only if there's some agreement that it really would enhance the base, > rather than -- say -- encouraging a rather sleazy sort of hackery. > > 2) Add it to my own published packages ? But that risks irritating people who > don't want that kind of addition. (And there is quite a lot of software that > I've come across that *I* won't use, just because of similar unwanted additions > to the image). What do you think, would it in fact be an irritant ? > > 3) Just bite the bullet and accept that I can't publish code that depends on > interchangeable Symbols and Blocks? > > Grateful for any feedback... > > -- chris > > |
In reply to this post by Chris Uppal-3
"Chris Uppal" <[hidden email]> wrote in message
news:3eaa697f$0$45175$[hidden email]... > > I'm looking to see if there's any consensus in the community on the issue of > adding #value: to Symbol. I added it to my image. I posted about this here http://groups.google.com/groups?dq=&hl=en&lr=&ie=UTF-8&oe=UTF-8&selm=ae5j1j%2448aku%241%40ID-50880.news.dfncis.de . I was not sure if it was a good idea, but I did it, and I don't regret it yet. I mostly use it for the getContentsBlock in list columns. It is easier to type, and makes sense to me (I think most Smatalkers could guess what was happening if they saw a symbol where I block would normally be). I don't feel too bad being slightly creative with block replacements, as OA sometimes uses Classes in place of blocks. I also like not having so many block references floating around. I seem to recall (and there was recent discussion about this too) that blocks can hold on to references. ... > 1) Petition OA to add Symbol>>value: to the base image ? Obviously that makes > sense only if there's some agreement that it really would enhance the base, > rather than -- say -- encouraging a rather sleazy sort of hackery. Add my name to the petition. ;) If they can uses classes in place of blocks, I don't see why using symbols is any worse. > 2) Add it to my own published packages ? But that risks irritating people who > don't want that kind of addition. (And there is quite a lot of software that > I've come across that *I* won't use, just because of similar unwanted additions > to the image). What do you think, would it in fact be an irritant ? It could be an irritant to some, perhaps for different reasons. I wonder what this would do to prerequisites, maybe nothing, but worth checking. I have been hesitant to use Symbol<<value: in my goodie code for the same reasons. I don't like having to add methods like this in other people's images. > 3) Just bite the bullet and accept that I can't publish code that depends on > interchangeable Symbols and Blocks? That is what I do now. I write my code differently (not using some of my add-ons) if I know it will be released as a goodie. However this makes it a little bit of a pain to release something I did not initially intend to release. Chris |
In reply to this post by Chris Uppal-3
Thanks to everyone who replied (on and off-line). Since no one has expressed
horror at the way I want to use Symbol>>value: and since Chris Demers has exactly the same problem, I think I will petition OA to make this a part of the standard image. <coughs> <straightens tie> Andy, Blair, Could you add Symbol>>value: to the standard image please ? Thanks (hopefully) in advance. -- chris |
Chris,
> Could you add Symbol>>value: to the standard image please ? Thanks (hopefully) > in advance. Well, *I* wouldn't mind and I did petition Blair about doing this some time ago. I was interested in using it within the View Composer since, as has been mentioned, the use of blocks could often cause extra objects to be referenced unnecessarily and I found the use of Messages a bit too much typing. However, the great man thought the idea was generally abhorrent so the petition was shredded and my backside birched until red-raw. It never made it into the image. The fact that the prospective changes for Dolphin 6 will solve the block problems in the VC would seem to lend even less weight to the argument so I wouldn't hold out too much hope for this second petition being better received (perhaps you should consider a precationary book down the trousers!). And don't even think about ever requesting a method addition to Object. Nothing short of a papal bull will get that considered round here :-) Best Regards, Andy Bower Dolphin Support http://www.object-arts.com --- Are you trying too hard? http://www.object-arts.com/Relax.htm --- |
Andy,
> However, the great man thought the > idea was generally abhorrent so the petition was shredded and my > backside birched until red-raw. It never made it into the image. <grin> However, I think I've made an independent case for Symbol>>value: (and I live at least 10 miles beyond the reach of Blair's Instruments of Education and Remorse), so I'd like to hear whether he is still opposed to the idea. > And don't even think about ever requesting a method addition to > Object. Nothing short of a papal bull will get that considered round > here :-) Hmm... Then how did Object>>isString creep into D5.1 ? I hadn't meant to mention it (passing it off as a well-bred host will pretend not to notice when a guest vomits on the dog), but this is too much for me to ignore. Come to that, how do you live with the shame now that you *have* done it ? Is religion a comfort ? Or do you just haunt low bars unburdening yourself(s) to heedless strangers ? Despite the persiflage, I am genuinely curious about this one. Object>>isString strikes me as especially abhorent, and completely incompatable with the (admirable) line you and Blair have taken in the past. *And* it's only used twice... -- chris |
Chris
You wrote in message news:3eb22d02$0$45168$[hidden email]... > Andy, > > > However, the great man thought the > > idea was generally abhorrent so the petition was shredded and my > > backside birched until red-raw. It never made it into the image. > > <grin> > > However, I think I've made an independent case for Symbol>>value: (and I live > at least 10 miles beyond the reach of Blair's Instruments of Education and > Remorse), so I'd like to hear whether he is still opposed to the idea. I am uncomfortable about it because of a number of reasons. I don't think any one of these reasons is sufficient in itself to reject it, but for me they override the convenience: 1) It feels a bit too clever clever to me: The argument to #value: becomes the receiver of the message that was the original receiver in a rather magic way (at least to the uninitiated). 2) #value: doesn't apply to all Symbols, only unary selectors. In my image of 26000+ symbols, just over 10000 are actually unary selectors. About 3500 are unary, but not selectors at all. Disregarding that a lot of symbols are not selectors, we implement #value: and for completeness perhaps we should also implement #value:value: and #value:withArguments: for binary and keyword selectors. The translation of the first argument into the receiver, while the others remain the arguments, but shuffled down one, is even more magical. Having done something like this somewhere else (on Message) I've never been very happy with the result. 3) The true <valuable> protocols also includes the #argumentCount message. This is implemented on Symbol to answer the number of arguments that a message using the symbol as a selector would require, which seems sensible, but would be at odds with Symbol>>value: since a Symbol that answered 1 to #argumentCount would cause an error when sent #value:. 4) There is a specific object in Smalltalk-80 designed expressly for this purpose that provides a cleaner and more general solution. Of course I am referring to Message. This implements the full valuable protocol(s) correctly. 5) If one wants the convenience in terms of reduced typing (not something one should give much weight to really), then for programmatic cases there is always the option of adding another method that takes a symbol and wraps in into a Message to be passed to the method that expects a block. 6) One of the main motivations for using other forms of valuables than blocks in Dolphin has been, as Andy pointed out, the lack of true closures. I think we've put quite enough workarounds in for this (e.g. implementing #value:value: on classes), and these are not needed in D6. There remains the question of the increased space that a block requires in, e.g., a view resource, but this is either not worth worrying about, or one can use a Message. > > > And don't even think about ever requesting a method addition to > > Object. Nothing short of a papal bull will get that considered round > > here :-) > > Hmm... Then how did Object>>isString creep into D5.1 ? I hadn't meant to > mention it (passing it off as a well-bred host will pretend not to notice when > a guest vomits on the dog), but this is too much for me to ignore. Come to > that, how do you live with the shame now that you *have* done it ? Is religion > a comfort ? Or do you just haunt low bars unburdening yourself(s) to heedless > strangers ? > > Despite the persiflage, I am genuinely curious about this one. > Object>>isString strikes me as especially abhorent, and completely incompatable > with the (admirable) line you and Blair have taken in the past. > It's used extensively in the RB. Since the RB is now an integral part of Dolphin Pro, its extensions to Object (even type tests, yuck) are likely to be in the image anyway. As such they're likely to find there way into the base system over time (with much wailing and gnashing of teeth I can assure you). I'm surprised I didn't put a warning comment in it though... > *And* it's only used twice... If you unload the RB packages then yes. The remaining two references are from the RB Parser and scanner. Regards Blair |
Blair,
Thank you for replying. > 1) It feels a bit too clever clever to me: The argument to #value: > becomes the receiver of the message that was the original receiver in > a rather magic way (at least to the uninitiated). Agreed, but I don't think that's an argument one way or the other. The metaclass knot is also clever and confusing. The polymorphism between instances of True and False is well on the wrong side of the clever-clever boundary. I could probably think of other examples. > 2) #value: doesn't apply to all Symbols, only unary selectors. True. I'm not too bothered about this, though, because I think the underlying oddness is really in the BlockClosure (and, in some sense) Symbol classes. They have instances which are *not* polymorphically substitutable for each other. E.g. ([:acc :each | acc + each] value: 1) is a simple error (not even a DNU). [snipped other points with which I have no interesting disagreement, except, chosen as a representative example:] 5) If one wants the convenience > in terms of reduced typing (not something one should give much weight > to really), then for programmatic cases there is always the option of > adding another method that takes a symbol and wraps in into a Message > to be passed to the method that expects a block. I think you are missing my point. What I want to do is write code like aSet asSortedCollection: (SortIncreasing by: #name) because it reads better, because it allows me more flexibility, and because I can put in all sorts of exotic optimisations if I want to (e.g. memoising the result of the message send -- which is actually an option with the published version of my SortBlock package). There's no problem with that. However I also want to be able to use a BlockClosure (blocks specifically -- there no need for additional flexibility of allowing arbitrary <valuables>) for the rare case where a more complicated expression is required. That's to say that I want to be able to use Blocks for Symbols, not the other way around. The problem is that #perform: isn't sent to the Symbol, so I can't add methods to BlockClosure to make them substitutable for Symbols. Hence the desire to do it the other way around. However, putting it that baldly makes me realise that there's another way around the problem. I add #sendTo: to Symbol (implemented internally as #perform:), and use that instead of #perform: in my SortBlock code. I can then add (when I next find I need it) #sendTo: to BlockClosure, _et viola!_ So that's what I'll do. It's a little hacky (principly because good names for the method on Symbol -- #sendAsMessageTo:, say -- would look *really* stupid defined against BlockClosure), so I won't urge you to add it to the base image. But if you *could* think of a good selector, then I think it'd be worth adding to Symbol (though not necessarily duplicated against BlockClosure as standard). There's something I don't like about the way that selectors are so fundamental to Smalltalk, yet are reified as such pathetically passive objects. Hmm, #evaluatedAgainst:? #of: (as in: #name of: anObject)? Nah, nothing really appeals... [re: Object>>isString] > > *And* it's only used twice... > > If you unload the RB packages then yes. The remaining two references > are from the RB Parser and scanner. Ah, right. If you were to remove those two uses, then you could put #isString back into the RB packages where it belongs. One benefit would be of soothing your consciences (or is that two benefits?). Perhaps more importantly, it'd stop me mocking and pillorying you whenever I get the opportunity ;-) -- chris |
I wrote
> I add #sendTo: to Symbol (implemented > internally as #perform:), and use that instead of #perform: in my > SortBlock code. I can then add (when I next find I need it) #sendTo: > to BlockClosure Or indeed "borrow" Symbol>>forwardTo: (which was the gist of Bill's suggestion, that I unfortunately had misunderstood -- sorry Bill). Don't think I will, though. It has the right implementation, but it *means* something different... -- chris |
Free forum by Nabble | Edit this page |