There are 623 senders of isKindOf: in the 4.5 image I'm using right now - which may be more than the general because I have some extra stuff loaded - and I'd bet that there are no more than a dozen places where it is actually a sensible way of doing what is needed.
It's slow - it scans up a class tree. It's ugly. It isn't actually testing what a lot of people seem to think - if you want to find out is some object can handle a certain capability try actually asking with something like #isAGraphicThing rather than (isKindOf: Morph) or:[ foo isKindOf: DisplayObject] blahblahblah. We can do better. tim -- tim Rowledge; [hidden email]; http://www.rowledge.org/tim Useful random insult:- Paralyzed from the neck up. |
Totally. Also, one might argue that switching on type isn't terribly object-oriented. Or rather, it sort of re-implements dispatch. Sometimes it's hard to avoid, but some hard things are worth doing. Of course I'm a big fat hypocrite once in a long while (DNU hacks, #isKindOf:, etc.) #respondsTo: is nicer in some spots. Protocol isn't class. Etc. +1 On Sat, Aug 31, 2013 at 7:39 PM, tim Rowledge <[hidden email]> wrote: There are 623 senders of isKindOf: in the 4.5 image I'm using right now - which may be more than the general because I have some extra stuff loaded - and I'd bet that there are no more than a dozen places where it is actually a sensible way of doing what is needed. Casey Ransberger |
Only tangentially related but I can't resist. Here's my least-favorite hack... pure evil. What was that thing uncle Ben said about power? someObject perform: ('foo' , 'Bar') asSymbol. "There are no senders of #fooBar! Oh wait..."
On Sat, Aug 31, 2013 at 8:30 PM, Casey Ransberger <[hidden email]> wrote:
Casey Ransberger |
In reply to this post by timrowledge
> It's slow - it scans up a class tree.
... my favorite part of the slowness is that isKindOf: causes an unending sequence of megamorphic message sends which routinely need expensive lookups or large, much more complicated caches than "simple" PICs so the process is not overly slow. And of course, since the isKindOf: code tends to be well refactored, there is effectively one send site for every one of those megamorphic messages in the whole image, which _ensures_ those send sites will be slow... ;). Andres. |
Hey, let's use isKindOf: for exception handling!
... oh, wait... On 8/31/13 23:35 , Andres Valloud wrote: >> It's slow - it scans up a class tree. > > ... my favorite part of the slowness is that isKindOf: causes an > unending sequence of megamorphic message sends which routinely need > expensive lookups or large, much more complicated caches than "simple" > PICs so the process is not overly slow. And of course, since the > isKindOf: code tends to be well refactored, there is effectively one > send site for every one of those megamorphic messages in the whole > image, which _ensures_ those send sites will be slow... ;). > > Andres. > > |
In reply to this post by Casey Ransberger-2
> someObject perform: ('foo' , 'Bar') asSymbol. "There are no senders of
> #fooBar! Oh wait..." (SimpleButtonMorph new label: 'Test'; target: (MessageSend receiver: World selector: #fooBar); actionSelector: #value) openInHand ... no senders of #fooBar are found either. Of course the above example is silly, but my point is that the look-up for senders is not comprehensive anyway. Stef |
In reply to this post by Casey Ransberger-2
It's not terribly OO, I agree. It's useful in a kind've pattern
matching-y way (albeit pattern matching lite). I used it deliberately when playing around with derivative parsing. Take a look at #isNullableBlock here: https://github.com/frankshearar/Parsing-Derivatives/blob/master/Derivatives/DerivingParser.st isNullableBlock | n | n := nil. n := [:p | p class caseOf: { [Empty] -> [false]. [EmptyString] -> [true]. [EpsStar] -> [true]. [Literal] -> [false]. [LiteralSet] -> [false]. [Union] -> [(n value: p left) or: [n value: p right]]. [Cat] -> [(n value: p first) and: [n value: p second]]. [Red] -> [n value: p parser]. [StarParser] -> [(n value: p parser) or: [p parser isEmpty]]. [DelayedParser] -> [n value: p force]. [DelegateParser] -> [n value: p parser]} otherwise: [Error signal: 'isNullable not defined for ', p className]] lfpWithBottom: false. ^ n. (We're _effectively_ using #isMemberOf: (I think? I can never remember which is "is this class" and which is "is this class or subclass") by switching on `p class`.) I switch on type here because I'm much more interested here in the algorithm, and I can concentrate the whole thing into one place, rather than use implementors-of to view and a Browser to extend. But if you could mark methods as belonging to the same "conceptually same method split into multiple parts like a type-switching pattern match" you could have a special Browser assemble all the parts to display them together, as well as make it easily to extend the "partial method". When you use Traits the Browser + SystemChangeNotification stuff lets you do all sorts of nifty things that feel like you're working with (lisp) macros while also letting it look like everything's flattened. We need more of that. frank On 1 September 2013 04:30, Casey Ransberger <[hidden email]> wrote: > Totally. Also, one might argue that switching on type isn't terribly > object-oriented. Or rather, it sort of re-implements dispatch. Sometimes > it's hard to avoid, but some hard things are worth doing. Of course I'm a > big fat hypocrite once in a long while (DNU hacks, #isKindOf:, etc.) > > #respondsTo: is nicer in some spots. Protocol isn't class. Etc. > > +1 > > > On Sat, Aug 31, 2013 at 7:39 PM, tim Rowledge <[hidden email]> wrote: >> >> There are 623 senders of isKindOf: in the 4.5 image I'm using right now - >> which may be more than the general because I have some extra stuff loaded - >> and I'd bet that there are no more than a dozen places where it is actually >> a sensible way of doing what is needed. >> >> It's slow - it scans up a class tree. >> It's ugly. >> It isn't actually testing what a lot of people seem to think - if you want >> to find out is some object can handle a certain capability try actually >> asking with something like #isAGraphicThing rather than (isKindOf: Morph) >> or:[ foo isKindOf: DisplayObject] blahblahblah. >> >> We can do better. >> >> tim >> -- >> tim Rowledge; [hidden email]; http://www.rowledge.org/tim >> Useful random insult:- Paralyzed from the neck up. >> >> >> > > > > -- > Casey Ransberger > > > |
On Sun, 1 Sep 2013, Frank Shearar wrote:
> It's not terribly OO, I agree. It's useful in a kind've pattern > matching-y way (albeit pattern matching lite). I used it deliberately > when playing around with derivative parsing. Take a look at > #isNullableBlock here: > https://github.com/frankshearar/Parsing-Derivatives/blob/master/Derivatives/DerivingParser.st > > isNullableBlock > | n | > n := nil. > n := [:p | > p class caseOf: { > [Empty] -> [false]. > [EmptyString] -> [true]. > [EpsStar] -> [true]. > [Literal] -> [false]. > [LiteralSet] -> [false]. > [Union] -> [(n value: p left) or: [n value: p right]]. > [Cat] -> [(n value: p first) and: [n value: p second]]. > [Red] -> [n value: p parser]. > [StarParser] -> [(n value: p parser) or: [p parser isEmpty]]. > [DelayedParser] -> [n value: p force]. > [DelegateParser] -> [n value: p parser]} > otherwise: [Error signal: 'isNullable not defined for ', p > className]] lfpWithBottom: false. > ^ n. > > (We're _effectively_ using #isMemberOf: (I think? I can never remember > which is "is this class" and which is "is this class or subclass") by > switching on `p class`.) Yes, it's something like #isMemberOf:, but not exactly, due to the hidden #= sends of #caseOf:otherwise:. #isMemberOf: doesn't do any message sends in Squeak. > > I switch on type here because I'm much more interested here in the > algorithm, and I can concentrate the whole thing into one place, > rather than use implementors-of to view and a Browser to extend. > > But if you could mark methods as belonging to the same "conceptually > same method split into multiple parts like a type-switching pattern > match" you could have a special Browser assemble all the parts to > display them together, as well as make it easily to extend the > "partial method". When you use Traits the Browser + > SystemChangeNotification stuff lets you do all sorts of nifty things > that feel like you're working with (lisp) macros while also letting it > look like everything's flattened. We need more of that. If you come up with a unique selector, then you can let the VM do the dispatching, which is a lot more efficient. The unique selector will ensure that you can use the Implementors Browser to see just these methods at the same place. Levente > > frank > > On 1 September 2013 04:30, Casey Ransberger <[hidden email]> wrote: >> Totally. Also, one might argue that switching on type isn't terribly >> object-oriented. Or rather, it sort of re-implements dispatch. Sometimes >> it's hard to avoid, but some hard things are worth doing. Of course I'm a >> big fat hypocrite once in a long while (DNU hacks, #isKindOf:, etc.) >> >> #respondsTo: is nicer in some spots. Protocol isn't class. Etc. >> >> +1 >> >> >> On Sat, Aug 31, 2013 at 7:39 PM, tim Rowledge <[hidden email]> wrote: >>> >>> There are 623 senders of isKindOf: in the 4.5 image I'm using right now - >>> which may be more than the general because I have some extra stuff loaded - >>> and I'd bet that there are no more than a dozen places where it is actually >>> a sensible way of doing what is needed. >>> >>> It's slow - it scans up a class tree. >>> It's ugly. >>> It isn't actually testing what a lot of people seem to think - if you want >>> to find out is some object can handle a certain capability try actually >>> asking with something like #isAGraphicThing rather than (isKindOf: Morph) >>> or:[ foo isKindOf: DisplayObject] blahblahblah. >>> >>> We can do better. >>> >>> tim >>> -- >>> tim Rowledge; [hidden email]; http://www.rowledge.org/tim >>> Useful random insult:- Paralyzed from the neck up. >>> >>> >>> >> >> >> >> -- >> Casey Ransberger >> >> >> > > |
In reply to this post by Stéphane Rollandin
On 2013-09-01, at 11:32, Stéphane Rollandin <[hidden email]> wrote:
>> someObject perform: ('foo' , 'Bar') asSymbol. "There are no senders of >> #fooBar! Oh wait..." > > (SimpleButtonMorph new > label: 'Test'; > target: (MessageSend receiver: World selector: #fooBar); > actionSelector: #value) openInHand > > ... no senders of #fooBar are found either. > > Of course the above example is silly, but my point is that the look-up for senders is not comprehensive anyway. > > Stef I have occasionally put a literal array of all the constructed selectors at the sending site, just to facilitate senders browsing: #(fooBar fooBaz fooFum). "for senders browsing" someObject perform: ('foo' , thing) asSymbol. It even helps to do that if the selector is not constructed but simply performed after being passed into the method. - Bert - |
I've done stuff like this too. What I was pointing out was mostly composing selectors from strings. One great way to tell e.g. ME that a message actually is sent somewhere when doing these kinds of shenanigans is to write an SUnit test which includes the composed selector. Then it will still show up as being sent, and I'll know not to remove the method from my image as useless. Make sense, gents? :) On Mon, Sep 2, 2013 at 4:04 AM, Bert Freudenberg <[hidden email]> wrote:
Casey Ransberger |
Free forum by Nabble | Edit this page |