March 15, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | Daniel Yokomiso wrote: > Such feature (top_cast) needs specialized support to work correctly or it can introduce weird bugs in your application. In cases like this (double-dispatch) the standard OO solution is a visitor or something similar. There's a nice link at wiki, with lots of discussion on the related pages. I don't understand how it can cause bugs, more than manual casting would. Can you give details? If I am missing something, I honestly and earnestly would like to see it! > In D we can have a multidispatch solution using delegates, as in Burton's post. These two solutions are safe and easy to predict. I've looked at delegates, but they don't work to replace top_cast because they are fpointer-with-obj, not fpointer-into-class. That is, you'd need a different delegate for every right-hand object, instead of for every right-hand object class. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
March 15, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | "Russ Lewis" <spamhole-2001-07-16@deming-os.org> escreveu na mensagem news:3E737084.28AADA97@deming-os.org... > Daniel Yokomiso wrote: > > > Such feature (top_cast) needs specialized support to work correctly or it > > can introduce weird bugs in your application. In cases like this (double-dispatch) the standard OO solution is a visitor or something similar. There's a nice link at wiki, with lots of discussion on the related > > pages. > > I don't understand how it can cause bugs, more than manual casting would. Can > you give details? If I am missing something, I honestly and earnestly would > like to see it! Some unambiguous method call involving "top_cast" and a set of classes S could work correctly, because all possibilities used are tested and correctly defined. But some days/months/years later a programmer introduces a new class into your framework that breaks the fragile existing stability. Or he can define a new overloaded function that will cause problems with some weird combination of classes. It's like manual casting plus function pointers to simulate OO in C. Let me dig some strange cases (Eiffel syntax here, sorry guys :-) ): class A end class B inherit A end class C inherit A end class D inherit B end class E inherit C, D end class G a_method(a:A):A is do end a_method(b:B):B is do end a_method(c:C):C is do end a_method(d:D):D is do end a_method(e:E):E is do end end The previous classes respects all my overloading rules. But if you, or anyone else, add later the following class: class F inherit B and C end It should be always valid. And then someone could make: local a:A b:B c:C f:F g:G create f create g a := f b := f c := f a := g.a_method(a) -- doesn´t matter the method call here, any result conforms to A b := g.a_method(b) -- if you select in runtime a_method(C):C you can get a problem c := g.a_method(c) -- if you select in runtime a_method(B):B you can get a problem Note that doesn't matter if they're classes or interfaces. In Eiffel everything is a class, but in D with interfaces the same kind of problems can happen. Some cases may not happen in your tests, it's almost impossible to write comprehensive tests. > > In D we can have a multidispatch solution using delegates, as in Burton's > > post. These two solutions are safe and easy to predict. > > I've looked at delegates, but they don't work to replace top_cast because they > are fpointer-with-obj, not fpointer-into-class. That is, you'd need a different > delegate for every right-hand object, instead of for every right-hand object > class. It works by forcing each subclass to register itself in a registry controlling method versions. Something like this (it's different from Burton's post): module shapes; // some kind of storage is necessary, like hashes of hashes. Method getMethodFor(ClassInfo shapeA, ClassInfo shapeB); void registerMethodFor(ClassInfo shapeA, ClassInfo shapeB, Method method); module shape; import shapes; static this() { registerMethodFor(Shape.class, Shape.class, method1); registerMethodFor(Square.class, Triangle.class, method2); registerMethodFor(Circle.class, Triangle.class, method3); registerMethodFor(Square.class, Circle.class, method4); } void method1(Shape a, Shape b) { printf("method1(Shape a, Shape b)\r\n"); } void method2(Square a, Triangle b) { printf("method2(Square a, Triangle b)\r\n"); } void method3(Circle a, Triangle b) { printf("method3(Circle a, Triangle b)\r\n"); } void method4(Square a, Circle b) { printf("method4(Square a, Circle b)\r\n"); } class Shape { void method(Shape other) { getMethodFor(this.classInfo(), other.classInfo()).invoke(this, other); } } Search for efficient multi-dispatch in CiteSeer and you'll get some good hints of ways to do this in a performance-wise way. > -- > The Villagers are Online! http://villagersonline.com > > .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] > .[ (a version.of(English).(precise.more)) is(possible) ] > ?[ you want.to(help(develop(it))) ] > > --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.462 / Virus Database: 261 - Release Date: 13/3/2003 |
March 16, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Daniel Yokomiso | Daniel Yokomiso wrote: > Some unambiguous method call involving "top_cast" and a set of classes S could work correctly, because all possibilities used are tested and correctly defined. But some days/months/years later a programmer introduces a new class into your framework that breaks the fragile existing stability. Or he can define a new overloaded function that will cause problems with some weird combination of classes. It's like manual casting plus function pointers to simulate OO in C. Let me dig some strange cases (Eiffel syntax here, sorry guys :-) ): A similar argument could be made for virtual functions, couldn't it? A programmer that extends your class library could overload a function in the wrong way, and totally screw things up. top_cast doesn't affect your legacy code when the legacy code is using legacy objects. So adding a new class to the heirarchy can't break old paths. However, top_cast allows your legacy code to interact with new objects. If you so desire, you can use top_cast to allow extensions to your library to add new code paths into the heart of the old library. In places where that is not the design goal, don't use top_cast and you won't get the problem. > (snip code example) The example, as I understood it, was a good explanation of how implicit casts to overloaded functions can be fraught with danger, particularly when you have multiple inheritance. How does top_cast make this worse? > > > In D we can have a multidispatch solution using delegates, as in > Burton's > > > post. These two solutions are safe and easy to predict. > > > > I've looked at delegates, but they don't work to replace top_cast because > they > > are fpointer-with-obj, not fpointer-into-class. That is, you'd need a > different > > delegate for every right-hand object, instead of for every right-hand > object > > class. > > It works by forcing each subclass to register itself in a registry > controlling method versions. Something like this (it's different from > Burton's post): > > module shapes; > // some kind of storage is necessary, like hashes of hashes. > Method getMethodFor(ClassInfo shapeA, ClassInfo shapeB); > void registerMethodFor(ClassInfo shapeA, ClassInfo shapeB, Method > method); Right, this is exactly what I'm implementing currently. I think it's ugly, though. Walter, you've expressed before that you like general purpose features that add to the expressivity of the language in a widely-applicable way, yet don't duplicate other, existing features (not too much, at least). It seems to me that top_cast gives a valuable capability that no existing language feature gives. It is useful for implemeting multimethods, but also (I expect) for other purposes we haven't seen yet. Any thoughts about whether it should make it into the language? In v2, perhaps? -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
March 16, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | That seems like a really bad design philosophy, because the nature of the language becomes entirely dependent on the order in which you added the features. If you don't think of the cool features til last, the whole language will look like a frankenstein monster. Any time you add a feature you need to refactor the existing features. If there is going to be one way of doing things it should be the best way, not the first way added. Sean "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3E741FDF.9F12D35C@deming-os.org... > Walter, you've expressed before that you like general purpose features that add > to the expressivity of the language in a widely-applicable way, yet don't duplicate other, existing features (not too much, at least). It seems to me > that top_cast gives a valuable capability that no existing language feature > gives. It is useful for implemeting multimethods, but also (I expect) for other > purposes we haven't seen yet. Any thoughts about whether it should make it into > the language? In v2, perhaps? |
March 16, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean L. Palmer | "Sean L. Palmer" wrote: > That seems like a really bad design philosophy, because the nature of the language becomes entirely dependent on the order in which you added the features. If you don't think of the cool features til last, the whole language will look like a frankenstein monster. > > Any time you add a feature you need to refactor the existing features. If there is going to be one way of doing things it should be the best way, not the first way added. I agree, and I don't think that that was Walter's strategy. I was attempting to recognize that one of Walter's key concerns is with orthogonality - he wants new features to add new expressive dimensions to the language, not just be syntax sugar for old ones. IMHO, top_cast is one of those features. -- The Villagers are Online! http://villagersonline.com .[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ] .[ (a version.of(English).(precise.more)) is(possible) ] ?[ you want.to(help(develop(it))) ] |
March 17, 2003 Re: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | I agree with that. So far Walter's additions have been very clearly adding new features. Sorry I have such a negative attitude lately. I don't know what's come over me. ;( Sean "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3E74ED0E.6D846B8B@deming-os.org... > "Sean L. Palmer" wrote: > > > That seems like a really bad design philosophy, because the nature of the > > language becomes entirely dependent on the order in which you added the features. If you don't think of the cool features til last, the whole language will look like a frankenstein monster. > > > > Any time you add a feature you need to refactor the existing features. If > > there is going to be one way of doing things it should be the best way, not > > the first way added. > > I agree, and I don't think that that was Walter's strategy. I was attempting to > recognize that one of Walter's key concerns is with orthogonality - he wants new > features to add new expressive dimensions to the language, not just be syntax > sugar for old ones. > > IMHO, top_cast is one of those features. |
April 27, 2003 Re: Idea: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Cox | "Bill Cox" <bill@viasic.com> wrote in message news:3E70F283.1070301@viasic.com... > However, there's another nasty condition that I run into. The smarter a guy is, the more he hates reading other peoples code. They practically look for excuses to rewrite it (BTW, I do let them rewrite tons of code... old code can be a liability). This results in good code being deleted and re-written badly pretty often. Code can benefit enormously from being rewritten, *provided* it is being rewritten by the same guy who wrote it in the first place. Otherwise, the new guy doesn't understand what all the undocumented cruft in the old code does, ignores it in the rewrite, and so repeats every bug the cruft was added to fix. |
April 27, 2003 Re: Idea: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Bill Cox | "Bill Cox" <bill@viasic.com> wrote in message news:3E71DDC7.1090904@viasic.com... > I agree. I may have given the impression that I manage my teams. That's not exactly right. I fill a lead technical roll, and try to get a good manager involved to run the group. It's a tag-team aproach that I've found extremely effective. There are huge benifits in having the group's technical lead/mentor not be everyone's boss. > > I haven't studied management techniques at all, but I've found it odd that this tag-team aproach isn't more wide spread. Usually, companies promote the best tech guy, often losing a great asset while creating a monster. You're right. Management and technical expertise rarely reside in the same person. In more successful projects I've been involved with teams on, I've done the technical lead while someone *else* does the managing. |
April 28, 2003 Re: Idea: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
Walter wrote:
> "Bill Cox" <bill@viasic.com> wrote in message
> news:3E70F283.1070301@viasic.com...
>
>>However, there's another nasty condition that I run into. The smarter a
>>guy is, the more he hates reading other peoples code. They practically
>>look for excuses to rewrite it (BTW, I do let them rewrite tons of
>>code... old code can be a liability). This results in good code being
>>deleted and re-written badly pretty often.
>
>
> Code can benefit enormously from being rewritten, *provided* it is being
> rewritten by the same guy who wrote it in the first place. Otherwise, the
> new guy doesn't understand what all the undocumented cruft in the old code
> does, ignores it in the rewrite, and so repeats every bug the cruft was
> added to fix.
Yep. As I'm sure you remember, it's nice to be in EDA in these cases. With a thousand or so test cases from customers, you can check for every obscure bug that you've had to fix in the past, and verify performance. I imagine that writing compilers is possibly like that.
I try not to let new code replace the old code until the new code does a better job, and passes all the tests. I find most programmers ignore the old code until this stage, and then poor over it carefully looking for nuggets of wisdom. It can be pretty hard beating a 4 year old tool without reading it to see what it does.
Of course, if a programmer's not a team player, there's not much you can do. We just lost the programmer I described as the super-smart guy that I was having some trouble working with. Replacing fast code with slow code was something he did all the time. It was his method of debugging. If he traced a problem into your code, rather than fixing it, he'd rewrite it in the simplest way possible, which usually was very slow. A number of times, the tool just slowed down to a crawl, and I spent a day tracing the problem to one of his fixes. Also, the tool got somewhat slower every day. I've had to abondon the entire code base he was involved with even though I wrote half of it, and I'm working lots of overtime rewriting it now.
Bill
|
April 28, 2003 Re: Idea: top_cast | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter |
Walter wrote:
> "Bill Cox" <bill@viasic.com> wrote in message
> news:3E71DDC7.1090904@viasic.com...
>
>>I agree. I may have given the impression that I manage my teams.
>>That's not exactly right. I fill a lead technical roll, and try to get
>>a good manager involved to run the group. It's a tag-team aproach that
>>I've found extremely effective. There are huge benifits in having the
>>group's technical lead/mentor not be everyone's boss.
>>
>>I haven't studied management techniques at all, but I've found it odd
>>that this tag-team aproach isn't more wide spread. Usually, companies
>>promote the best tech guy, often losing a great asset while creating a
>>monster.
>
>
> You're right. Management and technical expertise rarely reside in the same
> person. In more successful projects I've been involved with teams on, I've
> done the technical lead while someone *else* does the managing.
One trick is to find a good manager who will let the tech-guys lead. Even if the manager is a superior programmer, I find that the guys doing the actual work usually come up with better solutions. You have to be able to turn off your technical insights, and let the creativity come from your workers.
The best team I ever worked with was QuickLogic in the early 90's, where we didn't really have a manager. One of the founders was in charge of our group, and he's a great guy. However, he had no interest in real management, so far as I can tell. He just worked on his own stuff and let us do our stuff.
In a vacuum of direction for the group, we had to define our own goals, and then we work together to meet them. The results were amazing. I wish I could reproduce it.
After seeing our early success, QuickLogic naturally promoted our best tech guy and mentor to run the group, and that turned out to be a disaster. He had some bad physical problems, but I bet failing at management contributed to his suicide within about a year. Since then, I've worked hard to stay out of management, and it's been a good thing so far.
Bill
P.S. If old stories aren't apropriate for this group, let me know, and I'll stop posting them. I hope they're enjoyable rather than annoying.
|
Copyright © 1999-2021 by the D Language Foundation