Musing on Symbol>>value:

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Musing on Symbol>>value:

Chris Uppal-3
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


Reply | Threaded
Open this post in threaded view
|

Re: Musing on Symbol>>value:

Bill Schwab
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]


Reply | Threaded
Open this post in threaded view
|

Re: Musing on Symbol>>value:

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


Reply | Threaded
Open this post in threaded view
|

Re: Musing on Symbol>>value:

Christopher J. Demers
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


Reply | Threaded
Open this post in threaded view
|

Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Chris Uppal-3
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


Reply | Threaded
Open this post in threaded view
|

Re: Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Andy Bower
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
---


Reply | Threaded
Open this post in threaded view
|

Re: Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Chris Uppal-3
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


Reply | Threaded
Open this post in threaded view
|

Re: Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Blair McGlashan
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


Reply | Threaded
Open this post in threaded view
|

Re: Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Chris Uppal-3
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


Reply | Threaded
Open this post in threaded view
|

Re: Calling for Symbol>>value: (was: Musing on Symbol>>value:)

Chris Uppal-3
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