Selectors as variables?

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

Re: AW: Selectors as variables?

stefano-franchi
Thanks to everyone for the illuminating discussion. It looks like it
may keep going on for a while...
I know know the answers to all my questions, and a little more besides.

My original problem was partially UI-related: I have a (mathematical)
function which is just the composition of three simpler functions each
chosen from a (math.) set. My idea was to have a method with three
parameters for the composed function, something like:

MyDataObject>>computeResultWith: aFunctionSelectorFromSet1 and:
aFunctionSelectorFromSet2 and: aFunctionSelectorFromSet3

With this setup I could manipulate the call to the composed function
both programmatically and from the GUI (i.e. by having menus populated
automatically from the respective sets).

It seems the perform: aString asSymbol solution is much simpler, but I
understand well (and much better after the discussion) the potential
maintenance problems, especially in debugging and refactoring.


Cheers,

Stefano


__________________________________________________
Stefano Franchi
Department of Philosophy                  Ph:  (64)  9 373-7599 x83940
University Of Auckland Fax: (64) 9 373-8768
Private Bag 92019 [hidden email]
Auckland
New Zealand

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
In reply to this post by Georg Heeg
On 19/03/07, Georg Heeg <[hidden email]> wrote:
> Bruce,
>
> The most predominant examples are in the UI. Most actions in menu
> specifications are symbols as well as aspects. They all are sent by perform:

Well, yes.  But are these illustrations of Best Practice that you
would hold up to someone as an example to follow?  FWIW, I would not.

Never say never, though.  I'm sure there must be an example of the use
of perform which is obviously the best way of solving a particular
problem.  I've just never seen one.

All the best,
    Bruce

--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
In reply to this post by stefano-franchi
Re: Selectors as variables?

I hate to sound like a broken record, but for me, appropriate is being able to search/refactor code, and symbols being literals helps neither..

Cheers!

-Boris
(Sent from a BlackBerry)

----- Original Message -----
From: Charles A. Monteiro <[hidden email]>
To: Bruce Badger <[hidden email]>; Travis Griggs <[hidden email]>
Cc: vwnc <[hidden email]>
Sent: Mon Mar 19 10:06:49 2007
Subject: Re: Selectors as variables?

Bruce:

I may be catching this mid-stream but not sure about "more" appropriate 
but obviously in situations where the invocation is deferred and simple 
e.g. no arguments there are a few examples such as AspectAdaptors , 
DependencyTransformers etc,

there are some recent extensions that make certain usages of symbols and 
blocks effectively interchangeable, e.g.

collection collect: #money

which amounts to :

collection collect:[:ea | ea money].

Basically symbols have been made "evaluable"

so when you bring up "appropriate" what do you mean ?

On Mon, 19 Mar 2007 10:33:37 -0500, Bruce Badger <[hidden email]
wrote:

> On 19/03/07, Travis Griggs <[hidden email]> wrote:
>> Both techniques have their place. With much cross over. They are both 
>> used
>> _extensively_ throughout the system itself, so I think that neither can 
>> be
>> all that bad.
>
> Really?  Can you point to an example in the base VisualWorks system
> where, in your view, it was more appropriate to use a perform than use
> a block?
>
> All the best,
>     Bruce



--
Charles A. Monteiro
http://wiki.nycsmalltalk.org
http://www.monteirosfusion.com
http://monteirofusion.blogspot.com

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Charles A. Monteiro-2
In reply to this post by Bruce Badger
Bruce:

I may be catching this mid-stream but not sure about "more" appropriate  
but obviously in situations where the invocation is deferred and simple  
e.g. no arguments there are a few examples such as AspectAdaptors ,  
DependencyTransformers etc,

there are some recent extensions that make certain usages of symbols and  
blocks effectively interchangeable, e.g.

collection collect: #money

which amounts to :

collection collect:[:ea | ea money].

Basically symbols have been made "evaluable"

so when you bring up "appropriate" what do you mean ?

On Mon, 19 Mar 2007 10:33:37 -0500, Bruce Badger <[hidden email]>  
wrote:

> On 19/03/07, Travis Griggs <[hidden email]> wrote:
>> Both techniques have their place. With much cross over. They are both  
>> used
>> _extensively_ throughout the system itself, so I think that neither can  
>> be
>> all that bad.
>
> Really?  Can you point to an example in the base VisualWorks system
> where, in your view, it was more appropriate to use a perform than use
> a block?
>
> All the best,
>     Bruce



--
Charles A. Monteiro
http://wiki.nycsmalltalk.org
http://www.monteirosfusion.com
http://monteirofusion.blogspot.com

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
On 19/03/07, Charles A. Monteiro <[hidden email]> wrote:

> Bruce:
>
> I may be catching this mid-stream but not sure about "more" appropriate
> but obviously in situations where the invocation is deferred and simple
> e.g. no arguments there are a few examples such as AspectAdaptors ,
> DependencyTransformers etc,
>
> there are some recent extensions that make certain usages of symbols and
> blocks effectively interchangeable, e.g.
>
> collection collect: #money
>
> which amounts to :
>
> collection collect:[:ea | ea money].
>
> Basically symbols have been made "evaluable"
>
> so when you bring up "appropriate" what do you mean ?

I mean the kind of thing where you would say: Look, see how perform is
used here?  This is a good example of where perform should be used.

I would not say that "collection collect: #money" was such an example.
 In this case what would happen if I refactored things and wanted to
rename >>money to >>instrument (which might be more generic in some
cases)?  What if I just want to know the impact of possibly changing
>>money?  Of course one can still do these things even with a perform
being used, it's just harder.

Sorry chaps.  I'll sut up now :-/

--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Charles A. Monteiro-2
In reply to this post by Boris Popov, DeepCove Labs (SNN)
So Boris, do you mean that you want for one, to be able to do "senders of  
selector" for selector #foo

and if you have code such as:

MyClass>>>myMethod
        "for illustration purposes only"

        self blah.
        self moreBlahBlah.
        self doThis: #foo.

you ought to be able to find the method "myMethod" ?

Well I can and I believe is because our friend Terry a zillion years ago  
game me some code for it. Or does the stock image already do this? Don't  
know, I have had this thing in my image for ever. BTW, didn't you write  
that regex addon to RB? can that beast help with the above? Or would it be  
necessary that the rewrite editor can handle this? I actually don't know  
if it can.

BTW , is a broken record worse or better than a CD with a glitch? I don't  
know.

-Charles

On Mon, 19 Mar 2007 11:05:10 -0500, Boris Popov <[hidden email]>  
wrote:

> I hate to sound like a broken record, but for me, appropriate is being  
> able to search/refactor code, and symbols being literals helps neither..
>
> Cheers!
>
> -Boris
> (Sent from a BlackBerry)
>
> ----- Original Message -----
> From: Charles A. Monteiro <[hidden email]>
> To: Bruce Badger <[hidden email]>; Travis Griggs <[hidden email]>
> Cc: vwnc <[hidden email]>
> Sent: Mon Mar 19 10:06:49 2007
> Subject: Re: Selectors as variables?
>
> Bruce:
>
> I may be catching this mid-stream but not sure about "more" appropriate
> but obviously in situations where the invocation is deferred and simple
> e.g. no arguments there are a few examples such as AspectAdaptors ,
> DependencyTransformers etc,
>
> there are some recent extensions that make certain usages of symbols and
> blocks effectively interchangeable, e.g.
>
> collection collect: #money
>
> which amounts to :
>
> collection collect:[:ea | ea money].
>
> Basically symbols have been made "evaluable"
>
> so when you bring up "appropriate" what do you mean ?
>
> On Mon, 19 Mar 2007 10:33:37 -0500, Bruce Badger <[hidden email]>
> wrote:
>
>> On 19/03/07, Travis Griggs <[hidden email]> wrote:
>>> Both techniques have their place. With much cross over. They are both
>>> used
>>> _extensively_ throughout the system itself, so I think that neither can
>>> be
>>> all that bad.
>>
>> Really?  Can you point to an example in the base VisualWorks system
>> where, in your view, it was more appropriate to use a perform than use
>> a block?
>>
>> All the best,
>>     Bruce
>
>
>



--
Charles A. Monteiro
http://wiki.nycsmalltalk.org
http://www.monteirosfusion.com
http://monteirofusion.blogspot.com

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
In reply to this post by Bruce Badger
On Mar 19, 2007, at 9:10, Bruce Badger wrote:

On 19/03/07, Charles A. Monteiro <[hidden email]> wrote:
Bruce:

I may be catching this mid-stream but not sure about "more" appropriate
but obviously in situations where the invocation is deferred and simple
e.g. no arguments there are a few examples such as AspectAdaptors ,
DependencyTransformers etc,

there are some recent extensions that make certain usages of symbols and
blocks effectively interchangeable, e.g.

collection collect: #money

which amounts to :

collection collect:[:ea | ea money].

Basically symbols have been made "evaluable"

so when you bring up "appropriate" what do you mean ?

I mean the kind of thing where you would say: Look, see how perform is
used here?  This is a good example of where perform should be used.

I would not say that "collection collect: #money" was such an example.
In this case what would happen if I refactored things and wanted to
rename >>money to >>instrument (which might be more generic in some
cases)?  What if I just want to know the impact of possibly changing
money?  Of course one can still do these things even with a perform
being used, it's just harder.

Not sure I understand correctly. So forgive if I'm off base here.

Define a class called Foo. Define a method 'money ^42'. Define another method 'performMoney ^self perform: #money'. Now rename 'money' to be 'currency'. You'll find that the performMoney has been rewritten. As it should be. Frankly, the RB rewrite engine would be FAR less useful than it is if it couldn't do that. Ponder just how many "specifications of selector to send" there are literal array specs. If the rewrite scope did not include those, you could never rename any method that was specified in a spec, because it might be broken later.

--
Travis Griggs
Objologist
"HTTP. It's like a bike pretending to be a bus, a bulldozer, and a cup of coffee at the same time." - Martin Kobetic


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
In reply to this post by Charles A. Monteiro-2
On Mar 19, 2007, at 10:45, Charles A. Monteiro wrote:

So Boris, do you mean that you want for one, to be able to do "senders of selector" for selector #foo

and if you have code such as:

MyClass>>>myMethod
"for illustration purposes only"

self blah.
self moreBlahBlah.
self doThis: #foo.

you ought to be able to find the method "myMethod" ?

Well I can and I believe is because our friend Terry a zillion years ago game me some code for it. Or does the stock image already do this? Don't know, I have had this thing in my image for ever. BTW, didn't you write that regex addon to RB? can that beast help with the above? Or would it be necessary that the rewrite editor can handle this? I actually don't know if it can.

The stock image already does this. Since I don't know when. A zillion and one years ago I think. :)

"senders of selector" is a great example of "it's ok to cheat if you don't get caught." Because cheat it does. It simply searches for methods with #foo in their frame. As well as scanning the bytecodes for "embedded" selectors. IOW, it's really just "references to symbol." Has been for a long time.

--
Travis Griggs
Objologist
"You A students, you'll be back soon teaching here with me. You B students, you'll actually go on to be real engineers. You C students, you'll go into management and tell the A and B students what to do." - My Fluid Dynamics Professor whom I have yet to disprove


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
In reply to this post by Travis Griggs-3
Ah, but symbol refactorings are half-baked simply because that's all they are, literal-based searches.
 
Foo>>one
 self bar
 
Foo>>two
self perform: #bar
 
Foo>>three
#(#bar) do: [:ea | self perform: ea]
 
Foo>>four
#bar << #bar >> 'Bar'
 
Foo>>five
(Array with: [:v | v bar]) do: [:ea | ea value: self]
 
Foo>>six
 #('bar') do: [:ea | self perform: ea asSymbol]
 
Now lets try renaming #bar to #foo,
 
one (okay)
 self foo
 
two (okay)
 self perform: #foo
 
three (okay)
#(#foo) do: [:ea | self perform: ea]
 
four (not okay)
#foo << #foo >> 'Bar'
 
five (okay)
(Array with: [:v | v foo]) do: [:ea | ea value: self]
 
six (nowhere to be found)
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Travis Griggs [mailto:[hidden email]]
Sent: Mon 19/03/2007 9:50 AM
To: vwnc
Subject: Re: Selectors as variables?

On Mar 19, 2007, at 9:10, Bruce Badger wrote:

On 19/03/07, Charles A. Monteiro <[hidden email]> wrote:
Bruce:

I may be catching this mid-stream but not sure about "more" appropriate
but obviously in situations where the invocation is deferred and simple
e.g. no arguments there are a few examples such as AspectAdaptors ,
DependencyTransformers etc,

there are some recent extensions that make certain usages of symbols and
blocks effectively interchangeable, e.g.

collection collect: #money

which amounts to :

collection collect:[:ea | ea money].

Basically symbols have been made "evaluable"

so when you bring up "appropriate" what do you mean ?

I mean the kind of thing where you would say: Look, see how perform is
used here?  This is a good example of where perform should be used.

I would not say that "collection collect: #money" was such an example.
In this case what would happen if I refactored things and wanted to
rename >>money to >>instrument (which might be more generic in some
cases)?  What if I just want to know the impact of possibly changing
money?  Of course one can still do these things even with a perform
being used, it's just harder.

Not sure I understand correctly. So forgive if I'm off base here.

Define a class called Foo. Define a method 'money ^42'. Define another method 'performMoney ^self perform: #money'. Now rename 'money' to be 'currency'. You'll find that the performMoney has been rewritten. As it should be. Frankly, the RB rewrite engine would be FAR less useful than it is if it couldn't do that. Ponder just how many "specifications of selector to send" there are literal array specs. If the rewrite scope did not include those, you could never rename any method that was specified in a spec, because it might be broken later.

--
Travis Griggs
Objologist
"HTTP. It's like a bike pretending to be a bus, a bulldozer, and a cup of coffee at the same time." - Martin Kobetic


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
In reply to this post by Travis Griggs-3
"references to symbol" ~~ "message sends" :)
 
/me hides under the bed
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Travis Griggs [mailto:[hidden email]]
Sent: Mon 19/03/2007 9:55 AM
To: VW NC
Subject: Re: Selectors as variables?

On Mar 19, 2007, at 10:45, Charles A. Monteiro wrote:

So Boris, do you mean that you want for one, to be able to do "senders of selector" for selector #foo

and if you have code such as:

MyClass>>>myMethod
"for illustration purposes only"

self blah.
self moreBlahBlah.
self doThis: #foo.

you ought to be able to find the method "myMethod" ?

Well I can and I believe is because our friend Terry a zillion years ago game me some code for it. Or does the stock image already do this? Don't know, I have had this thing in my image for ever. BTW, didn't you write that regex addon to RB? can that beast help with the above? Or would it be necessary that the rewrite editor can handle this? I actually don't know if it can.

The stock image already does this. Since I don't know when. A zillion and one years ago I think. :)

"senders of selector" is a great example of "it's ok to cheat if you don't get caught." Because cheat it does. It simply searches for methods with #foo in their frame. As well as scanning the bytecodes for "embedded" selectors. IOW, it's really just "references to symbol." Has been for a long time.

--
Travis Griggs
Objologist
"You A students, you'll be back soon teaching here with me. You B students, you'll actually go on to be real engineers. You C students, you'll go into management and tell the A and B students what to do." - My Fluid Dynamics Professor whom I have yet to disprove


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Dennis smith-4
OK, I didn't know it was there either -- I only ever looked in "Visualworks | Browse" -- should be there too!

Boris Popov wrote:
"references to symbol" ~~ "message sends" :)
 
/me hides under the bed
 
-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.


From: Travis Griggs [[hidden email]]
Sent: Mon 19/03/2007 9:55 AM
To: VW NC
Subject: Re: Selectors as variables?

On Mar 19, 2007, at 10:45, Charles A. Monteiro wrote:

So Boris, do you mean that you want for one, to be able to do "senders of selector" for selector #foo

and if you have code such as:

MyClass>>>myMethod
"for illustration purposes only"

self blah.
self moreBlahBlah.
self doThis: #foo.

you ought to be able to find the method "myMethod" ?

Well I can and I believe is because our friend Terry a zillion years ago game me some code for it. Or does the stock image already do this? Don't know, I have had this thing in my image for ever. BTW, didn't you write that regex addon to RB? can that beast help with the above? Or would it be necessary that the rewrite editor can handle this? I actually don't know if it can.

The stock image already does this. Since I don't know when. A zillion and one years ago I think. :)

"senders of selector" is a great example of "it's ok to cheat if you don't get caught." Because cheat it does. It simply searches for methods with #foo in their frame. As well as scanning the bytecodes for "embedded" selectors. IOW, it's really just "references to symbol." Has been for a long time.

--
Travis Griggs
Objologist
"You A students, you'll be back soon teaching here with me. You B students, you'll actually go on to be real engineers. You C students, you'll go into management and tell the A and B students what to do." - My Fluid Dynamics Professor whom I have yet to disprove



-- 
Dennis Smith                 		         +1 416.798.7948
Cherniak Software Development Corporation   Fax: +1 416.798.0948
509-2001 Sheppard Avenue East        [hidden email]
Toronto, ON M2J 4Z8              <a class="moz-txt-link-freetext" href="sip:dennis@CherniakSoftware.com">sip:dennis@...
Canada			         http://www.CherniakSoftware.com
Entrance off Yorkland Blvd south of Sheppard Ave east of the DVP
Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
In reply to this post by Bruce Badger
On Mar 19, 2007, at 9:04, Bruce Badger wrote:

On 19/03/07, Georg Heeg <[hidden email]> wrote:
Bruce,

The most predominant examples are in the UI. Most actions in menu
specifications are symbols as well as aspects. They all are sent by perform:

Well, yes.  But are these illustrations of Best Practice that you
would hold up to someone as an example to follow?  FWIW, I would not.

Never say never, though.  I'm sure there must be an example of the use
of perform which is obviously the best way of solving a particular
problem.  I've just never seen one.

There is no "best practice" to follow here IMO.

Obvioulsy, UIs use it heavily. Browse senders of perform: yourself to see lots more.

perform: #someSymbol is used by the change engine. In Trippy. Lots in the RB. To dispatch the correct action in ParagraphEditor. TestCases use it. CharacterScanners. All those icons that show up all over the image. The list goes on and on and on and on.

Don't get me wrong, if my reputation for going nuts with blocks doesn't precede me in this discussion, then we're definitely in different universes.

But I simply can find no validation of a semi-religious belief that "perform: #aSymbol" is to be viewed as taboo.

I would also argue that indeed for a beginner, perform: #aSymbol, is much easier to grok than blocks. The reason is that it has direct analogs with other programming environments. It's _just_ a function pointer as it were. You can pass them around. And invoke them. Many/most languages have the ability to invoke functions from the indirect specification of a variable. The whole "callback" metaphor in just about every language but Smalltalk is based on this whole notion.

--
Travis Griggs
Objologist
"There are a thousand hacking at the branches of evil to one who is striking at the root" - Henry David Thoreau


Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
In reply to this post by Travis Griggs-3
On 19/03/07, Travis Griggs <[hidden email]> wrote:
> Define a class called Foo. Define a method 'money ^42'. Define another
> method 'performMoney ^self perform: #money'. Now rename 'money' to be
> 'currency'. You'll find that the performMoney has been rewritten.

Thanks, Travis (and Charles).  I didn't realise the RB would do that!

... I'm not sure I feel very good that it does.  It strikes me that
there could be unwanted side effects, for example if a symbol is
coincidentally the same as the selector of a method that gets renamed.
 I would prefer it if the RB recognised the distinction that Boris
made, viz symbol != message selector.

I would go along with you and avoid religiously applying a rule that
banned >>perform even if I could (never say never, and all that), but
I think it's OK to talk about best practice.  There are benefits from
having a view of what is best practice and constantly trying to trend
towards that. Of course, one should always be open to  Even Better
practice too!

I certainly don't buy the argument that perform must be OK because it
is used in the base VW image, though.  Having said that, if you know
of a place in the base image that is an illustration of where
>>perform is the Right Thing To Do, then I'd love to see it.  Really.

I'm also not so convinced that encouraging people to pick up bad
habits (because it's a bit easier for now) is a good thing.  Blocks
are not that hard to grok once you have played with them for a bit.

Lastly Travis, my apologies if I have portrayed you as anything other
than a big fan of blocks :-)

All the best,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Dave Stevenson-2
In reply to this post by Alexander Ivanov-2
Finally catching up on my email, so excuse me coming in late.

 > How do you implement this:
 >
 > Foo>>doSeveralActions: actions
 >     actions do: [ :selector | anObject perform: selector]
 >
 > Foo new doSeveralActions: #(read write save print)

How about:

Foo>>actionObject
        ^anObject

Bar>>actionsWith: aFoo

        (aFoo actionObject)
                doThis;
                doThat;
                doTheOther;
                etc.

Admittedly, this is a contrived example. But then, so was yours.  :)

Dave

Alexander Ivanov wrote:

> It is hard to say what would be more confusing for newbies, blocks or
> 'perform'. From my point of view both are not quite easy for
> non-smalltalkers:
>  
>  [:v | v inspect] value: anObject
> or
> anObject perform: #inspect
> Yes, perform is bad in debugging but blocks are less convenient if we go
> a little bit further.
>  
> How do you implement this:
>  
> Foo>>doSeveralActions: actions
>     actions do: [ :selector | anObject perform: selector]
>  
> Foo new doSeveralActions: #(read write save print)
>  
> Definition is OK:
>  
> Foo>>doSeveralActions: actions
>     actions do: [ :block | block value: anObject ].
>  
> But what about call?
>  
> blocks := OrderedCollection new
>     add: [ :v | v read ];
>     add: [ :v | v write ];
>     add: [ :v | v save ];
>     add: [ :v | v print];
>     yourself.
> Foo new doSeveralActions: blocks.
>  
> If somebody find something less ugly, I will switch to blocks too.
>  
> Regards,
>  
> Alex
>
> Alex Ivanov
> [hidden email]
> 778 898-2527
>
>
>  
>  
>  
>  
>  -----Original Message-----
> *From:* Steve Aldred [mailto:[hidden email]]
> *Sent:* Sunday, March 18, 2007 8:22 PM
> *To:* vwnc
> *Subject:* Re: Selectors as variables?
>
>     Alexander Ivanov wrote:
>>      
>>     OtherFoo>>beforeDoSomething
>>     | block otherObject |
>>     otherObject := 5.
>>     block := [ :v | otherObject  inspect ].
>>     Foo new doSomething: block
>>      
>>     Then
>>      
>>     Foo>>doSomething: aBlock
>>      aBlock value: myInstVar
>>      
>>      inspects 5 instead of myInstVar because aBlock was compiled in
>>     other context.
>>     That is what I meant. Sorry, I gave a hypothetical example, did
>>     not have time to invent a useful one.
>     If you want the block to do things with the argument, which is the
>     whole point of the exercise, then you write block code that does
>     just that. For the above the block should then be:
>
>         [:v | v inspect]
>
>     then there is no confusion over what is being acted on. Of course
>     any self references in the block refer to where the block was
>     compiled not where it is executed - which does confuse newbies.
>
>     cheers
>     Steve A
>>      
>>     Regards,
>>      
>>     Alex
>>      
>>      
>>
>>         -----Original Message-----
>>         *From:* Boris Popov [mailto:[hidden email]]
>>         *Sent:* Sunday, March 18, 2007 11:30 AM
>>         *To:* Alexander Ivanov; [hidden email];
>>         [hidden email]
>>         *Cc:* [hidden email]
>>         *Subject:* RE: Selectors as variables?
>>
>>         Not sure what you mean by context here, could you elaborate?
>>          
>>         Foo>>doSomething: aBlock
>>          aBlock value: myInstVar
>>          
>>         aFoo doSomething: [:v | v inspect]
>>          
>>         versus,
>>          
>>         Foo>>doSomething: aSelector
>>          myInstVar perform: aSelector
>>          
>>         aFoo doSomething: #inspect
>>          
>>         Using perform's leads to brittle code as they are not subject
>>         to refactorings (method renames, rewrites and such), runtime
>>         packager has no way to trace them, code highligter doesn't
>>         know what they are etc.
>>          
>>         Cheers!
>>          
>>         -Boris
>>
>>         --
>>         +1.604.689.0322
>>         DeepCove Labs Ltd.
>>         4th floor 595 Howe Street
>>         Vancouver, Canada V6C 2T5
>>
>>         [hidden email]
>>
>>         CONFIDENTIALITY NOTICE
>>
>>         This email is intended only for the persons named in the message
>>         header. Unless otherwise indicated, it contains information
>>         that is
>>         private and confidential. If you have received it in error, please
>>         notify the sender and delete the entire message including any
>>         attachments.
>>
>>         Thank you.
>>
>>         ------------------------------------------------------------------------
>>         *From:* Alexander Ivanov [mailto:[hidden email]]
>>         *Sent:* Sun 18/03/2007 11:19 AM
>>         *To:* Boris Popov; [hidden email]; [hidden email]
>>         *Cc:* [hidden email]
>>         *Subject:* RE: Selectors as variables?
>>
>>         Passing a block is more powerful but might be more complicated
>>         because 'fooClass' would never know in which context a block
>>         is going to be performed. In 'perform' case it is always clear
>>         that selector will be performed in 'anObject' context.
>>          
>>         For beginners I would recommend to start exploring 'perform'
>>         case and if it is not enough, try to use blocks.
>>          
>>         Regards,
>>          
>>         Alex
>>          
>>          
>>
>>             -----Original Message-----
>>             *From:* Boris Popov [mailto:[hidden email]]
>>             *Sent:* Sunday, March 18, 2007 10:34 AM
>>             *To:* [hidden email]; [hidden email]
>>             *Cc:* [hidden email]
>>             *Subject:* Re: Selectors as variables?
>>
>>             Technically, yes, but practically one is much better off
>>             passing a block instead.
>>
>>             Cheers!
>>
>>             -Boris
>>             (Sent from a BlackBerry)
>>
>>             ----- Original Message -----
>>             From: [hidden email] <[hidden email]>
>>             To: Stefano Franchi <[hidden email]>
>>             Cc: vwnc <[hidden email]>; Stefano Franchi
>>             <[hidden email]>
>>             Sent: Sun Mar 18 10:27:51 2007
>>             Subject: Re: Selectors as variables?
>>
>>             Stefano
>>
>>             >fooClass>>doSomething: withThisMethod
>>             >anObject withThisMethod
>>
>>             If you pass in the selector, then:
>>
>>             doSomething: aSymbol
>>                     anObject perform: aSymbol
>>
>>                                             And So It Goes
>>                                                  Sames
>>             ______________________________________________________________________
>>
>>             Samuel S. Shuster [|]
>>             VisualWorks Engineering, GUI Project
>>             Smalltalk Enables Success -- What Are YOU Using?
>>
>

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Dave Stevenson-2
In reply to this post by Bruce Badger
 > I mean the kind of thing where you would say: Look, see how perform
is used here?  This is a good example of where perform should be used.

Umm, maybe MessageSend>>value ?

        value
                "Evaluate the message send."
       
                ^receiver perform: selector withArguments: args

Dave

Bruce Badger wrote:

> On 19/03/07, Charles A. Monteiro <[hidden email]> wrote:
>> Bruce:
>>
>> I may be catching this mid-stream but not sure about "more" appropriate
>> but obviously in situations where the invocation is deferred and simple
>> e.g. no arguments there are a few examples such as AspectAdaptors ,
>> DependencyTransformers etc,
>>
>> there are some recent extensions that make certain usages of symbols and
>> blocks effectively interchangeable, e.g.
>>
>> collection collect: #money
>>
>> which amounts to :
>>
>> collection collect:[:ea | ea money].
>>
>> Basically symbols have been made "evaluable"
>>
>> so when you bring up "appropriate" what do you mean ?
>
> I mean the kind of thing where you would say: Look, see how perform is
> used here?  This is a good example of where perform should be used.
>
> I would not say that "collection collect: #money" was such an example.
> In this case what would happen if I refactored things and wanted to
> rename >>money to >>instrument (which might be more generic in some
> cases)?  What if I just want to know the impact of possibly changing
>>> money?  Of course one can still do these things even with a perform
> being used, it's just harder.
>
> Sorry chaps.  I'll sut up now :-/
>

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
On 20/03/07, Dave Stevenson <[hidden email]> wrote:
>  > I mean the kind of thing where you would say: Look, see how perform
> is used here?  This is a good example of where perform should be used.
>
> Umm, maybe MessageSend>>value ?
>
>         value
>                 "Evaluate the message send."
>
>                 ^receiver perform: selector withArguments: args

Heh, well, this seems to be the mechanism used in loads of places so
people can say "me? nah, I don't use >>perform" :-)  Looking at the
references to MessageSend it seemed to me that blocks could do the job
just as well if not better in the situations where MessageSend is used
(not that I am suggesting a wholesale change!).

Indeed MessageSend seems to me to be a class created to try and
mitigate the problems with passing symbols around to be later used as
selectors.  So rather that being an example of a good use of
>>perform, it seems to be an example of why one should consider using
blocks instead IMO.

The one situation where I can see that >>perform *may* be handy is
when bringing in strings from outside the image which you want to use
as selectors, though one might then be open to dodgy code being
injected (much like the SQL injection vulnerabilities in some
systems).  So even in this case I'd be more inclined to define an
acceptable vocabulary and  look up an action in a dictionary whose
keys are the "selectors" and whose values are blocks and then I'd say
value to the block.

All the best,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Travis Griggs-3
Bruce,

How would you do SUnit without perform:?

--
Travis Griggs
Objologist
"You A students, you'll be back soon teaching here with me. You B students, you'll actually go on to be real engineers. You C students, you'll go into management and tell the A and B students what to do." - My Fluid Dynamics Professor whom I have yet to disprove


Reply | Threaded
Open this post in threaded view
|

RE: Selectors as variables?

Boris Popov, DeepCove Labs (SNN)
Travis,

There's a big difference between perform'ing selectors that are
effectively extracted from the runtime and perform'ing selectors that
are coded as literals in the source.

Okay:

(self selectorsMatching: 'test*') do: [:ea | self perform: ea]

Not so much:

#(testOne testTwo testThree) do: [:ea | self perform: ea]

That's the pattern I was campaigning against, not all uses of perform,

Cheers!

-Boris

--
+1.604.689.0322
DeepCove Labs Ltd.
4th floor 595 Howe Street
Vancouver, Canada V6C 2T5
http://tinyurl.com/r7uw4

[hidden email]

CONFIDENTIALITY NOTICE

This email is intended only for the persons named in the message
header. Unless otherwise indicated, it contains information that is
private and confidential. If you have received it in error, please
notify the sender and delete the entire message including any
attachments.

Thank you.

> -----Original Message-----
> From: Travis Griggs [mailto:[hidden email]]
> Sent: Tuesday, March 20, 2007 12:51 PM
> To: vwnc
> Subject: Re: Selectors as variables?
>
> Bruce,
>
> How would you do SUnit without perform:?
>
> --
> Travis Griggs
> Objologist
> "You A students, you'll be back soon teaching here with me. You B
> students, you'll actually go on to be real engineers. You C students,
> you'll go into management and tell the A and B students what to do." -
My
> Fluid Dynamics Professor whom I have yet to disprove
>

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Bruce Badger
In reply to this post by Travis Griggs-3
On 20/03/07, Travis Griggs <[hidden email]> wrote:

> How would you do SUnit without perform:?

Good point!  Thank goodness I never say never! :-)

Travis, I do I like Boris's latest response to you and agree with the
distinction he makes.  I think his thoughts on this are more refined
than mine. I shall steal them forthwith.

Perhaps we can give this topic a more extensive flogging at StS07?

All the best,
    Bruce
--
Make the most of your skills - with OpenSkills
http://www.openskills.org/

Reply | Threaded
Open this post in threaded view
|

Re: Selectors as variables?

Dennis smith-4
In reply to this post by Bruce Badger
We make extensive use of perform in our business application framework.
Simple example -- for large lists of things (e.g. employees) we maintain
some different sort orders.  They have to be maintained when udpates are
made
for performance reasons.  We define a sort order using a "Key" object which
lists the attributes (which have read accessors) which are used to
define the order.
For example, "surname, firstName, sin".  We then, in the framework,
use "perform" to get the values to sort on.

In a different case, we can have named groups of attributes so the developer
can say "give me an Array of the employee name"  which might be defined as

    title, firstName, surname, initial

The attribute "set" would be called name, and would contain the 4
selector names
and asking for "name" would have to use perform to get the array of values.
Could we create a method "name" and have it build the set, yes but we
want to build
it at runtime, not by hard-coding.

There are numerous other examples where perform is used in the framework
because the
names of attributes are in the data.


--
Dennis Smith                         +1 416.798.7948
Cherniak Software Development Corporation   Fax: +1 416.798.0948
509-2001 Sheppard Avenue East        [hidden email]
Toronto, ON M2J 4Z8              sip:[hidden email]
Canada         http://www.CherniakSoftware.com
Entrance off Yorkland Blvd south of Sheppard Ave east of the DVP

123