D - Idea: top_cast
- Russ Lewis (50/50) Mar 13 2003 Thinking about my previous question, "Double Virtual...", and reading
- Bill Cox (26/91) Mar 13 2003 Hi, Russ.
- Russ Lewis (10/12) Mar 13 2003 A reasonable position. Hopefully, in time, its use would become widespr...
- Bill Cox (26/45) Mar 13 2003 If programmers were generally familiar with the construct, I'd support
- Sean L. Palmer (7/31) Mar 13 2003 Here's an idea: Don't hire programmers that suck, or don't give them
- Bill Cox (10/16) Mar 13 2003 What make a programmer a good programmer? I'd say a good GUI programmer...
- Sean L. Palmer (9/25) Mar 13 2003 If you're trying to make a run-of-the-mill program, hire a run-of-the-mi...
- Russ Lewis (8/12) Mar 13 2003 Ouch, Sean. That was uncalled for. I understand your sentiment, but th...
- Bill Cox (9/29) Mar 13 2003 Hey, it's no problem. I understand the sentiment.
- Bill Cox (61/67) Mar 13 2003 Hi, again. Just a few more random thoughts about hiring only good
- Daniel Yokomiso (20/87) Mar 14 2003 good
- Bill Cox (10/13) Mar 14 2003 I agree. I may have given the impression that I manage my teams.
- Walter (5/14) Apr 26 2003 You're right. Management and technical expertise rarely reside in the sa...
- Bill Cox (23/41) Apr 28 2003 One trick is to find a good manager who will let the tech-guys lead.
- Matthew Wilson (2/4) Apr 30 2003 Occasionally instructive. Always worth a read.
- Walter (4/6) Apr 30 2003 Oh, I think they're a great read. Please keep posting!
- Walter (7/12) Apr 26 2003 Code can benefit enormously from being rewritten, *provided* it is being
- Mike Wynn (21/25) Mar 13 2003 its not always the programmers, have a friend who did the oposite, strip...
- Bill Cox (21/36) Mar 14 2003 At QuickLogic, I read a paper called RICE, which was a fun mathematical
- Russ Lewis (87/87) Mar 13 2003 Some notes about how top_cast would affect function calls:
- Daniel Yokomiso (30/80) Mar 13 2003 This only works if there is always a most specialized method. But someti...
- Russ Lewis (20/44) Mar 14 2003 The runtime algorithm would be as follows:
- Daniel Yokomiso (127/175) Mar 14 2003 sometimes
- Russ Lewis (8/12) Mar 14 2003 Fair enough. But the problem is already confronted in D, as you point o...
- Daniel Yokomiso (16/28) Mar 15 2003 problem
- Russ Lewis (13/20) Mar 15 2003 I don't understand how it can cause bugs, more than manual casting would...
- Daniel Yokomiso (95/115) Mar 15 2003 it
- Russ Lewis (27/55) Mar 15 2003 A similar argument could be made for virtual functions, couldn't it? A
- Sean L. Palmer (15/22) Mar 16 2003 That seems like a really bad design philosophy, because the nature of th...
- Russ Lewis (11/18) Mar 16 2003 I agree, and I don't think that that was Walter's strategy. I was attem...
- Sean L. Palmer (13/27) Mar 16 2003 I agree with that.
Thinking about my previous question, "Double Virtual...", and reading the links about multimethods, I ran across this idea: top_cast <expr> This would be a cast operator that, at runtime, discovers the actual (i.e. the top) type of the value, and casts it to that type. Yes, that means that we are breaking the old C "know all types at compile time" paradigm. However, there will only be a finite number of possible types that the <expr> could be cast to. The compiler must attempt to compile code for each one. However, some may be syntax errors (perhaps you pass the top_cast as a function parameter, but there is not a function implementation that takes all child classes). The interesting (and difficult) thing about this is that the compiler would have to compile different code paths, one for each possible top type, with an internal switch or lookup table. So, multimethods would be trivial to implement (from the programmer's perspective): class X; class C1 : X; class C2 : X; void foo(C1,C1); void foo(C1,C2); void foo(C2,C1); void foo(C2,C2); void foo(X a,X b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } The function call here tells the compiler to, at runtime (or at compile time, if it can figure out enough stuff), determine what the top class of the variables "X a" and "X b" are. It then calls the right method based on the type. I figure that the compiler could throw a Error_top_cast_runtime_syntax_error if it found at runtime a type (or, in this case, set of types) it could not handle. I expect that there are many other interesting possible uses for top_cast that I haven't considered yet, either... Thoughts? Is the programming benefit worth the compiler complexity? Russ -- 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))) ]
Mar 13 2003
Hi, Russ. This is a nice idea, but IMO, it falls into the category of trying to be too elegant. The problem with being too elegant, is the next programmer who inherits your code will get lost looking at it. So, consider: What's the probability that that new programmer already knows about top_cast? Not likely. What's more likely: will he rip it out and rewrite it as the worst possible if-then-else chain, or will he go learn about top_cast, and become a fan? I wish it were the latter, but most of the time, I see the former. To protect the code base, I generally discourage use of advanced features whenever the alternative is not more than an ugly page or two of very easy to understand code. There are those who will argue that reducing the lines of code make it more maintainable, and that forcing use of advanced features will improve my group's overall productivity. After years of working with groups of programmers in teams, I can tell you that I've found this not to be the case. Overall productivity is enhanced when you can get everyone to agree on using the same features in the same way. Doing this is extremely difficult, especially since on avererage programmers leaves after three years on the job. Keeping the common feature set limited is your best chance of success. Anyway, it is a cool coding construct. I wouldn't be upset about it getting into D, but I wouldn't let you use it where I work. Bill Russ Lewis wrote:Thinking about my previous question, "Double Virtual...", and reading the links about multimethods, I ran across this idea: top_cast <expr> This would be a cast operator that, at runtime, discovers the actual (i.e. the top) type of the value, and casts it to that type. Yes, that means that we are breaking the old C "know all types at compile time" paradigm. However, there will only be a finite number of possible types that the <expr> could be cast to. The compiler must attempt to compile code for each one. However, some may be syntax errors (perhaps you pass the top_cast as a function parameter, but there is not a function implementation that takes all child classes). The interesting (and difficult) thing about this is that the compiler would have to compile different code paths, one for each possible top type, with an internal switch or lookup table. So, multimethods would be trivial to implement (from the programmer's perspective): class X; class C1 : X; class C2 : X; void foo(C1,C1); void foo(C1,C2); void foo(C2,C1); void foo(C2,C2); void foo(X a,X b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } The function call here tells the compiler to, at runtime (or at compile time, if it can figure out enough stuff), determine what the top class of the variables "X a" and "X b" are. It then calls the right method based on the type. I figure that the compiler could throw a Error_top_cast_runtime_syntax_error if it found at runtime a type (or, in this case, set of types) it could not handle. I expect that there are many other interesting possible uses for top_cast that I haven't considered yet, either... Thoughts? Is the programming benefit worth the compiler complexity? Russ -- 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))) ]
Mar 13 2003
Bill Cox wrote:Anyway, it is a cool coding construct. I wouldn't be upset about it getting into D, but I wouldn't let you use it where I work.A reasonable position. Hopefully, in time, its use would become widespread enough that you'd allow it into your shop! People probably said the exact same thing about virtual functions when they first came out, and they were probably correct then too. -- 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))) ]
Mar 13 2003
Hi, Russ. Russ Lewis wrote:Bill Cox wrote:If programmers were generally familiar with the construct, I'd support it's use. Virtual functions are an interesting example. I'd guess that almost half of the C++ GUI programmers I've worked with don't really know what it does. Since they generally just inherit from a base GUI class, and overide functions, they never have to decide when to make a function virtual or not. When put into that position, I've seen GUI programmers opt for simply making everything virtual, rather than learning what virtual really means. I love that virtual is gone in Java, and that the compiler is responsible for figuring it out. I've got some funny stories about what programmers did when they inherited really good code that they couldn't understand, but most are only funny if you know EDA really well. However, I've heard a good one that came up in one of the oldest visual editors: vi. The original author's of vi discovered that searching for strings can be done in time proportional to the size of the file, rather than the worst case (and not typical) case of having to compare most of the characters in a string to most of the characters in a file. It's a complex algorithm involving "failure functions" that tell you what state to go to when a mismatched character is encountered. These guys wrote all this great code, and demonstraited the world's fastest text search in history. The next programmer who inherited vi had no clue what all that code was about. He replaced it with strcmp vs every character in the file! BillAnyway, it is a cool coding construct. I wouldn't be upset about it getting into D, but I wouldn't let you use it where I work.A reasonable position. Hopefully, in time, its use would become widespread enough that you'd allow it into your shop! People probably said the exact same thing about virtual functions when they first came out, and they were probably correct then too. -- 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))) ]
Mar 13 2003
Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there. Sean "Bill Cox" <bill viasic.com> wrote in message news:3E70AFCD.9040308 viasic.com...If programmers were generally familiar with the construct, I'd support it's use. Virtual functions are an interesting example. I'd guess that almost half of the C++ GUI programmers I've worked with don't really know what it does. Since they generally just inherit from a base GUI class, and overide functions, they never have to decide when to make a function virtual or not. When put into that position, I've seen GUI programmers opt for simply making everything virtual, rather than learning what virtual really means. I love that virtual is gone in Java, and that the compiler is responsible for figuring it out. I've got some funny stories about what programmers did when they inherited really good code that they couldn't understand, but most are only funny if you know EDA really well. However, I've heard a good one that came up in one of the oldest visual editors: vi. The original author's of vi discovered that searching for strings can be done in time proportional to the size of the file, rather than the worst case (and not typical) case of having to compare most of the characters in a string to most of the characters in a file. It's a complex algorithm involving "failure functions" that tell you what state to go to when a mismatched character is encountered. These guys wrote all this great code, and demonstraited the world's fastest text search in history. The next programmer who inherited vi had no clue what all that code was about. He replaced it with strcmp vs every character in the file! Bill
Mar 13 2003
Hi, Sean. Sean L. Palmer wrote:Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there. SeanWhat make a programmer a good programmer? I'd say a good GUI programmer cranks out good GUIs fast. A good Perl hacker generates HTML pages 10 times faster than most of the rest of us. Good GUI programmers often don't understand how to write templates, never used unions, and really don't create very complex data structures. Most Perl programmers don't use any of the high-level capabilities of Perl. I'd hire both of them. Bill
Mar 13 2003
If you're trying to make a run-of-the-mill program, hire a run-of-the-mill programmer. If you need something exotic, adding more lines of code won't necessarily get the problem solved. I see your point. If you don't need a guru, stay away from them; they'll "upgrade" your codebase until mere mortals can't understand it. Sean "Bill Cox" <bill viasic.com> wrote in message news:3E70E906.1000408 viasic.com...Hi, Sean. Sean L. Palmer wrote:goodHere's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all theprogrammers down just because there are bad programmers out there. SeanWhat make a programmer a good programmer? I'd say a good GUI programmer cranks out good GUIs fast. A good Perl hacker generates HTML pages 10 times faster than most of the rest of us. Good GUI programmers often don't understand how to write templates, never used unions, and really don't create very complex data structures. Most Perl programmers don't use any of the high-level capabilities of Perl. I'd hire both of them. Bill
Mar 13 2003
Ouch, Sean. That was uncalled for. I understand your sentiment, but that was vicious. "Sean L. Palmer" wrote:Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there.-- The Villagers are Online! 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))) ]
Mar 13 2003
Hey, it's no problem. I understand the sentiment. I advocate putting in hand-rails in langauges for the less-than-average programmers, like removing pointers and making everything virtual and letting the compiler fix it. I also encourage programmers to write their programs as if the target audience is stupid people. That point of view gets a strong reaction from many. It's certainly not what super-smart people who enjoy very advanced language features want to hear. Bill Russ Lewis wrote:Ouch, Sean. That was uncalled for. I understand your sentiment, but that was vicious. "Sean L. Palmer" wrote:Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there.-- The Villagers are Online! 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))) ]
Mar 13 2003
Hi, again. Just a few more random thoughts about hiring only good programmers... Sean L. Palmer wrote:Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there. SeanI agree about keeping programmers who can mess up code away from the code. I don't let our GUI guys hack our algorithms, and vise-versa. The main problem, though, isn't stupid programmers, it's inexperienced programmers. I look back at code I wrote a long time ago, and frankly, it stinks. Experience really does count, at least the first few years. We hire mostly out of school, and always have a lot of training to do. I'd say we succeed in hiring very bright people, and that it pays off to do so, even if we have to train them. However, we have to help them get through that phase when their code still stinks. Naturally, every bright programmer we hire wants to jump right in and work on the most sensitive code. It's hard to hold them back to simpler, well contained pieces of the system while they're still learning. A lot of the problems arise when I relent, and put a guy into a situation he's not quite ready for. A lot of the problems are therefore really my fault. 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. Also, when a smart guy gets an idea, it's often really hard to change it, even when he's wrong. I'd say posts on this group support this assertion. I'm not goint to claim to be an exception. Here's a receient example at work. I hired a brilliant guy out of Duke, and have been training him for two years. He's scary smart. For example, there were several years where he never got a math problem wrong on any test, including SAT, SAT2, AP tests, and several high-school and college classes. I've found that these kinds of guys make great algorithms developers, and he's worked out well overall. He hates the fact that we have duplicated a very complex function in the routing database in two different places. It's morally offensive to him. The same code is literally repeated, but with minor changes. The first version computes the shape of a wire from the routing data structures. The second computes what shape would result if we built the routing data structures, but does it without building them. The direct computation from the data structures is the most inner-loop code in our system. The what-if code runs several times slower. I updated my source code a couple weeks ago, and all my stuff ran much slower. I wasted half the day to find that he'd deleted (not commented out) the fast direct computation, and emulated it's functionality by calling the what-if version. I had to check out an old version and undo his hack, but I also added a capability so that in debug mode, the what-if version is called, and the results are compared to the normal version. We still have two similar copies of code, but at least we know they are in sync. I updated again a couple of days ago, and the slow behavior came back. It turns out he'd commented out the if-statement around the check, so that it was always called. Of course, I had to put it back the way it was, so our tools would run at a competitive speed, and so I could get my work done in reasonable time. I bet that the slow behavior will be back next time I update. What do you do? The smartest programmers are often the ones causing the most problems. I can't fire them. They're too productive. In fact, they know it, and do all kinds of crap just to piss you off! It's just part of living in the real world. And besides, I deserve it. My old bosses tell horror stories about having to manage me. Bill
Mar 13 2003
"Bill Cox" <bill viasic.com> escreveu na mensagem news:3E70F283.1070301 viasic.com...Hi, again. Just a few more random thoughts about hiring only good programmers... Sean L. Palmer wrote:goodHere's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all theHere's my two cents. Since I started studying project management (and working as a consultant in these techniques) there's one thing about teams that I never ignore. You have to be able to trust in your team. If they lie to you, they work behind the scenes, they have their own agenda or if they have no concept of responsibility, things will just get worse over time. Good programmers can write efficient and well-designed software, not only one of these. It's a matter of time for a bad programmer to mess with an entire project. You can define some rules, like minimum performance, and write automated tests to check this. Run these tests every other hour, before every build, whenever you'll think it's important, and treat their failures as bugs. Make these programmers know that if performance goes down it's a bug and they should never put bugs in. At least you'll be able to verify when things get wrong. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.461 / Virus Database: 260 - Release Date: 10/3/2003programmers down just because there are bad programmers out there. SeanI agree about keeping programmers who can mess up code away from the code. I don't let our GUI guys hack our algorithms, and vise-versa. The main problem, though, isn't stupid programmers, it's inexperienced programmers. I look back at code I wrote a long time ago, and frankly, it stinks. Experience really does count, at least the first few years. We hire mostly out of school, and always have a lot of training to do. I'd say we succeed in hiring very bright people, and that it pays off to do so, even if we have to train them. However, we have to help them get through that phase when their code still stinks. Naturally, every bright programmer we hire wants to jump right in and work on the most sensitive code. It's hard to hold them back to simpler, well contained pieces of the system while they're still learning. A lot of the problems arise when I relent, and put a guy into a situation he's not quite ready for. A lot of the problems are therefore really my fault. 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. Also, when a smart guy gets an idea, it's often really hard to change it, even when he's wrong. I'd say posts on this group support this assertion. I'm not goint to claim to be an exception. Here's a receient example at work. I hired a brilliant guy out of Duke, and have been training him for two years. He's scary smart. For example, there were several years where he never got a math problem wrong on any test, including SAT, SAT2, AP tests, and several high-school and college classes. I've found that these kinds of guys make great algorithms developers, and he's worked out well overall. He hates the fact that we have duplicated a very complex function in the routing database in two different places. It's morally offensive to him. The same code is literally repeated, but with minor changes. The first version computes the shape of a wire from the routing data structures. The second computes what shape would result if we built the routing data structures, but does it without building them. The direct computation from the data structures is the most inner-loop code in our system. The what-if code runs several times slower. I updated my source code a couple weeks ago, and all my stuff ran much slower. I wasted half the day to find that he'd deleted (not commented out) the fast direct computation, and emulated it's functionality by calling the what-if version. I had to check out an old version and undo his hack, but I also added a capability so that in debug mode, the what-if version is called, and the results are compared to the normal version. We still have two similar copies of code, but at least we know they are in sync. I updated again a couple of days ago, and the slow behavior came back. It turns out he'd commented out the if-statement around the check, so that it was always called. Of course, I had to put it back the way it was, so our tools would run at a competitive speed, and so I could get my work done in reasonable time. I bet that the slow behavior will be back next time I update. What do you do? The smartest programmers are often the ones causing the most problems. I can't fire them. They're too productive. In fact, they know it, and do all kinds of crap just to piss you off! It's just part of living in the real world. And besides, I deserve it. My old bosses tell horror stories about having to manage me. Bill
Mar 14 2003
Here's my two cents. Since I started studying project management (and working as a consultant in these techniques) there's one thing about teams that I never ignore. You have to be able to trust in your team.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. Bill
Mar 14 2003
"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.
Apr 26 2003
Walter wrote:"Bill Cox" <bill viasic.com> wrote in message news:3E71DDC7.1090904 viasic.com...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.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.
Apr 28 2003
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.Occasionally instructive. Always worth a read. They're fine by me.
Apr 30 2003
"Bill Cox" <bill viasic.com> wrote in message news:3EAD05C1.3090300 viasic.com...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.Oh, I think they're a great read. Please keep posting! P.S. I've done my best to avoid the management track.
Apr 30 2003
"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.
Apr 26 2003
Walter wrote:"Bill Cox" <bill viasic.com> wrote in message news:3E70F283.1070301 viasic.com...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. BillHowever, 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.
Apr 28 2003
"Bill Cox" <bill viasic.com> wrote in message news:3EACFD6C.8000400 viasic.com...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.Very much so. My test suite is mainly a distillation of 20 years of bug reports <g>.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.Frequently, those nuggets consist of "if running under operating system XX.YY, work around this weird OS bug by doing this kludge". Developing under the latest OS means the new programmers will not see the problem until it's too late.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.He doesn't sound that smart to me <g>.
Apr 30 2003
"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message news:b4qkd6$12ms$1 digitaldaemon.com...Here's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there.its not always the programmers, have a friend who did the oposite, striped out the junk and wrote a smart lazy evaluating fast version of some code, the manager then removed it all because he did not understand how it could work! turned out the manager wrote version 1 and was upset that some contractor could write in 1 month a perfectly working version of something the manager has spent a year bodging and bugfixing. a good programmer is one who learns, and accepts there's always someone who can do (or has done) whatever better than they can (could). imho the best programmer is one how help the guy who can write a better version the code to do exactly that. but I'm baised, I know I'm a shite programmer, but I still think " 'cos it is " is the worst reason for never explaining why something was implemented in a particular way and I'm lazy, why write something someone else has written and tested for you. (if it turns out it don't work you can blaim someone else and head off to the pub for the rest of the day.) its bad project managment/leadership if someone who does not know what or why they are doing something is let loose on a section of code. didn't some bloke 2000 years ago write "before you unwind the for loop in your brothers code take the unbounded recursion out of your own."
Mar 13 2003
Mike Wynn wrote:"Sean L. Palmer" <seanpalmer directvinternet.com> wrote in message news:b4qkd6$12ms$1 digitaldaemon.com...At QuickLogic, I read a paper called RICE, which was a fun mathematical way to quickly predict net delays in circuits. I wrote a prototype over the weekend, and demonstrated it Monday. The code worked great. It dramatically improved our timing estimates, giving good estimates 99.99% of the time (the other .01% had to be done with the old techniques). My boss at the time was my EDA mentor, a truly brilliant guy and outstanding programmer, but with no background in math. He couldn't understand how my code worked, so he simply refused to believe it. He wouldn't let me put it in the tools until he had it validated. He hired Professor Pillage to come examine my work. Professor Pillage was the author of the RICE paper. It turns out that RICE failed to get a good answer 10% of the time, not 0.01% like my version. I showed him how to fix RICE. Then, he went around to all the EDA companies, and showed them how to do it! It remains the standard aproach today. BTW, back around 1994, I upgraded QuickLogic's timing estimation to a better method, which makes AWE obsolete for net delay estimation. I tried to publish it, but the academics wouldn't accept it without a professor behind it! If you're interested, I've got a weak patent on the topic that explains how to do it, and is easy to work around: 5,675,502. BillHere's an idea: Don't hire programmers that suck, or don't give them unlimited freedom to fuck up perfectly working code elsewhere in the codebase just because they "don't understand it". Don't pull all the good programmers down just because there are bad programmers out there.its not always the programmers, have a friend who did the oposite, striped out the junk and wrote a smart lazy evaluating fast version of some code, the manager then removed it all because he did not understand how it could work! turned out the manager wrote version 1 and was upset that some contractor could write in 1 month a perfectly working version of something the manager has spent a year bodging and bugfixing Just another story along these lines...
Mar 14 2003
Some notes about how top_cast would affect function calls: obj.foo(obj2); This is the standard D call. It is automatically a virtual call, if some child(ren) override it. (top_cast obj).foo(obj2); This is functionally identical to the one above, since we are determining the correct method to call by checking the left type at runtime. (I know, I know, that's not how vfunction calls are implemented...but that's the effect.) obj.foo(top_cast obj2); This is a multimethod, but the left side (what will be the "this" pointer) is of fixed type. So that means that the argument MUST be of a type for which obj has an implemented method. Thus, consider this type family: class Arg1; class Arg2 : Arg1; class Arg3 : Arg2; class Obj1 { void foo(Arg1); void foo(Arg2); } void DoStuff(Obj1 obj,Arg1 arg) { obj.foo(top_cast arg); } In this case, the 'arg' variable could be any of three types: Arg1: top_cast simply is a no-op. This is equivalent to: obj.foo(arg); Arg2: top_cast casts the object to Arg2. This is equivalent to: obj.foo(cast(Arg2)arg); Arg3: top_cast casts the object to Arg3. However, class Obj doesn't have an implementation for that, so it gets implicitly downcast back to Arg2 when the function is called: obj.foo(cast(Arg3)arg); // Obj::foo(Arg2) gets called here If you top_cast both sides, then things are even more complex: (top_cast obj).foo(top_cast arg); In this case, you might have another class: class Obj2 : Obj1 { void foo(Arg1); void foo(Arg3); }; Now the possibilities are like this: Obj1,Arg1: both top_casts are no-ops obj.foo(arg); Obj1,Arg2: left is no-op, cast right to Arg2: obj.foo(cast(Arg2)arg); // Obj1::foo(Arg2) gets called Obj1,Arg3: left is no-op, cast right to Arg3, then downcast to Arg2: obj.foo(cast(Arg3)arg); // Obj1::foo(Arg2) gets called Obj2,Arg1: cast left to Obj1, right is no-op (cast(Obj2)obj).foo(arg); // Obj2::foo(Arg1) gets called Obj2,Arg2: cast left to Obj1, right to Arg2. Base implementation (in Obj1) gets called (cast(Obj2)obj).foo(cast(Arg2)arg); // Obj1::foo(Arg2) gets called Obj2,Arg3: cast left to Obj1, right to Arg3. We DON'T have to downcast, because Obj2 has an implementation for Arg3 (cast(Obj2)obj).foo(cast(Arg3)arg); // Obj2::foo(Arg3) gets called So, you see that top_cast'ing the left side gives us access not only to virtual functions, but also to new functions only defined further down the type tree. You may also notice that, in this case, we can simplify things somewhat. If 'arg' is either Arg1 or Arg2, then we can just use D's existing virtual function call implementation. The compiler would produce code something like this: // implementing '(top_cast obj).foo(top_cast arg);' switch(arg.classinfo) { case Arg1: obj.foo(arg); // use the virtual function foo(Arg1) break; case Arg2: obj.foo(cast(Arg2)arg); // use the virtual function foo(Arg2) break; case Arg3: if(obj.classinfo == Obj1) obj.foo(cast(Arg2)arg); else (cast(Obj2)obj).foo(cast(Arg3)arg); break; } -- 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))) ]
Mar 13 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> escreveu na mensagem news:3E70A041.E91A9210 deming-os.org...Thinking about my previous question, "Double Virtual...", and reading the links about multimethods, I ran across this idea: top_cast <expr> This would be a cast operator that, at runtime, discovers the actual (i.e. the top) type of the value, and casts it to that type. Yes, that means that we are breaking the old C "know all types at compile time" paradigm. However, there will only be a finite number of possible types that the <expr> could be cast to. The compiler must attempt to compile code for each one. However, some may be syntax errors (perhaps you pass the top_cast as a function parameter, but there is not a function implementation that takes all child classes). The interesting (and difficult) thing about this is that the compiler would have to compile different code paths, one for each possible top type, with an internal switch or lookup table. So, multimethods would be trivial to implement (from the programmer's perspective): class X; class C1 : X; class C2 : X; void foo(C1,C1); void foo(C1,C2); void foo(C2,C1); void foo(C2,C2); void foo(X a,X b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } The function call here tells the compiler to, at runtime (or at compile time, if it can figure out enough stuff), determine what the top class of the variables "X a" and "X b" are. It then calls the right method based on the type. I figure that the compiler could throw a Error_top_cast_runtime_syntax_error if it found at runtime a type (or, in this case, set of types) it could not handle. I expect that there are many other interesting possible uses for top_cast that I haven't considered yet, either... Thoughts? Is the programming benefit worth the compiler complexity? Russ -- 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))) ]This only works if there is always a most specialized method. But sometimes it's not the case: class A; class B : A; class C : A; class D : B; void foo(A a, A b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } foo(B,A) foo(A,C) foo(B,C) foo(D,A) What should we do when we call "foo(someD, someC)"? This problem can get worse with interfaces. This solution would be good just for some cases. I'm a big fan of multimethods, but they need language support to get right and safe. With this syntax there's also problems with return types: a method return void, another return int and other return Foo. But such feature could be defined as a library function, it just needs reflection to get right. --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.461 / Virus Database: 260 - Release Date: 10/3/2003
Mar 13 2003
Daniel Yokomiso wrote:This only works if there is always a most specialized method. But sometimes it's not the case: class A; class B : A; class C : A; class D : B; void foo(A a, A b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } foo(B,A) foo(A,C) foo(B,C) foo(D,A) What should we do when we call "foo(someD, someC)"? This problem can get worse with interfaces. This solution would be good just for some cases. I'm a big fan of multimethods, but they need language support to get right and safe. With this syntax there's also problems with return types: a method return void, another return int and other return Foo. But such feature could be defined as a library function, it just needs reflection to get right.The runtime algorithm would be as follows: 1) Cast all top_cast expressions to their current (top) type. This is NOT ambiguous, since each reference points to a single object, and all objects have a single type, even though you have many possible pointers. 2) Evaluate the expression as though the programmer had manually cast these expressions to these types. Likewise, this is NOT ambiguous, because D has resolution rules. 3) If there is no legal way to evaluate the runtime type combination, then throw Error_top_cast_runtime_syntax_error Please, though, restate your example. I didn't understand it entirely. What overloaded versions of foo() are available? Also note that your example can potentially do infinite recursion if foo(A,A) calls itself because the objects are both literal A objects (or if that is the best implementation for the combination of objects that you pass it). -- 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))) ]
Mar 14 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> escreveu na mensagem news:3E71DB70.485FEC81 deming-os.org...Daniel Yokomiso wrote:sometimesThis only works if there is always a most specialized method. ButI'mit's not the case: class A; class B : A; class C : A; class D : B; void foo(A a, A b) { try { foo(top_cast a, top_cast b); } catch(Error_top_cast_runtime_syntax_error) { printf("Oops! I don't have a foo(...) function for these types!\n"); } } foo(B,A) foo(A,C) foo(B,C) foo(D,A) What should we do when we call "foo(someD, someC)"? This problem can get worse with interfaces. This solution would be good just for some cases.anda big fan of multimethods, but they need language support to get rightcouldsafe. With this syntax there's also problems with return types: a method return void, another return int and other return Foo. But such featurehavebe defined as a library function, it just needs reflection to get right.The runtime algorithm would be as follows: 1) Cast all top_cast expressions to their current (top) type. This is NOT ambiguous, since each reference points to a single object, and all objectsa single type, even though you have many possible pointers. 2) Evaluate the expression as though the programmer had manually casttheseexpressions to these types. Likewise, this is NOT ambiguous, because Dhasresolution rules. 3) If there is no legal way to evaluate the runtime type combination, thenthrowError_top_cast_runtime_syntax_error Please, though, restate your example. I didn't understand it entirely.Whatoverloaded versions of foo() are available? Also note that your example can potentially do infinite recursion iffoo(A,A)calls itself because the objects are both literal A objects (or if that isthebest implementation for the combination of objects that you pass it). -- 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))) ]This is a simple program tested with dmd 0.59. class A { } class B : A { } class C : A { } class D : B { } void foo(A a1, A a2) { printf("foo(A,A)\r\n"); } void foo(B b, A a) { printf("foo(B,A)\r\n"); } void foo(A a, C c) { printf("foo(A,C)\r\n"); } void foo(B b, C c) { printf("foo(B,C)\r\n"); } void foo(D d, A a) { printf("foo(D,A)\r\n"); } 1int main() { A a = new A(); B b = new B(); C c = new C(); D d = new D(); foo(a, a); // foo(A,A) foo(a, b); // foo(A,A) foo(a, c); // foo(A,C) foo(a, d); // foo(A,A) foo(b, a); // foo(B,A) // function foo overloads void(A a1,A a2) and void(B b,A a) both match argument list for foo // foo(b, b); foo(b, c); // foo(B,C) // function foo overloads void(A a1,A a2) and void(B b,A a) both match argument list for foo // foo(b, d); foo(c, a); // foo(A,A) foo(c, b); // foo(A,A) // function foo overloads void(A a1,A a2) and void(A a,C c) both match argument list for foo // foo(c, c); foo(c, d); // foo(A,A) foo(d, a); // foo(D,A) // function foo overloads void(A a1,A a2) and void(D d,A a) both match argument list for foo // foo(d, b); // function foo overloads void(A a1,A a2) and void(D d,A a) both match argument list for foo // foo(d, c); // function foo overloads void(A a1,A a2) and void(D d,A a) both match argument list for foo // foo(d, d); return 0; } It's difficult to define what is the most specialized version of the method. There's a long list of discussions about it in Usenet. I participated in some discussions in comp.lang.eiffel. There's also a problem if you define a function overloaded for interfaces: interface I { } interface J { } void foo(I i, J j) { printf("foo(I,J)\r\n"); } void foo(J j, I i) { printf("foo(J,I)\r\n"); } class A : I { } class B : J { } class C : I, J { } int main() { A a = new A(); B b = new B(); C c = new C(); I i = a; J j = b; I ic = c; J jc = c; foo(a, b); // foo(I,J) foo(b, a); // foo(J,I) foo(a, c); // foo(I,J) foo(b, c); // foo(J,I) // function foo overloads void(I i,J j) and void(J j,I i) both match argument list for foo // foo(c, c); foo(c, a); // foo(J,I) foo(c, b); // foo(I,J) foo(i, j); // foo(I,J) foo(j, i); // foo(J,I) foo(i, jc); // foo(I,J) foo(ic, j); // foo(I,J) return 0; } I can write more examples showing how different combinations of method definitions and calls can be resolved in a static context, but may fail in runtime, while some other combinations could work in a runtime context, but fail in static time. If you add OO polymorphism things get worse, because any possible descendent can write additional methods that'll cause ambiguity at runtime. To provide multi-dispatch we need compiler support to invalidate ambiguous cases and force the programmer to disambiguate them (by adding more function versions). --- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.461 / Virus Database: 260 - Release Date: 10/3/2003
Mar 14 2003
Daniel Yokomiso wrote:It's difficult to define what is the most specialized version of the method. There's a long list of discussions about it in Usenet. I participated in some discussions in comp.lang.eiffel. There's also a problem if you define a function overloaded for interfaces:Fair enough. But the problem is already confronted in D, as you point out. The issue is orthogonal to top_cast. -- 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))) ]
Mar 14 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> escreveu na mensagem news:3E72D829.67D10122 deming-os.org...Daniel Yokomiso wrote:problemIt's difficult to define what is the most specialized version of the method. There's a long list of discussions about it in Usenet. I participated in some discussions in comp.lang.eiffel. There's also aout. Theif you define a function overloaded for interfaces:Fair enough. But the problem is already confronted in D, as you pointissue is orthogonal to top_cast. -- 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))) ]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. http://c2.com/cgi/wiki?DoubleDispatchExample In D we can have a multidispatch solution using delegates, as in Burton's post. These two solutions are safe and easy to predict. --- 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
Mar 15 2003
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))) ]
Mar 15 2003
"Russ Lewis" <spamhole-2001-07-16 deming-os.org> escreveu na mensagem news:3E737084.28AADA97 deming-os.org...Daniel Yokomiso wrote:itSuch feature (top_cast) needs specialized support to work correctly orrelatedcan 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 theCanpages.I don't understand how it can cause bugs, more than manual casting would.you give details? If I am missing something, I honestly and earnestlywouldlike 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.Burton'sIn D we can have a multidispatch solution using delegates, as intheypost. These two solutions are safe and easy to predict.I've looked at delegates, but they don't work to replace top_cast becauseare fpointer-with-obj, not fpointer-into-class. That is, you'd need adifferentdelegate for every right-hand object, instead of for every right-handobjectclass.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
Mar 15 2003
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?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))) ]Burton'sIn D we can have a multidispatch solution using delegates, as intheypost. These two solutions are safe and easy to predict.I've looked at delegates, but they don't work to replace top_cast becauseare fpointer-with-obj, not fpointer-into-class. That is, you'd need adifferentdelegate for every right-hand object, instead of for every right-handobjectclass.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);
Mar 15 2003
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 featuresthat addto the expressivity of the language in a widely-applicable way, yet don't duplicate other, existing features (not too much, at least). It seems tomethat top_cast gives a valuable capability that no existing languagefeaturegives. It is useful for implemeting multimethods, but also (I expect) forotherpurposes we haven't seen yet. Any thoughts about whether it should makeit intothe language? In v2, perhaps?
Mar 16 2003
"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))) ]
Mar 16 2003
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:theThat seems like a really bad design philosophy, because the nature ofIflanguage 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.notthere is going to be one way of doing things it should be the best way,attempting tothe first way added.I agree, and I don't think that that was Walter's strategy. I wasrecognize that one of Walter's key concerns is with orthogonality - hewants newfeatures to add new expressive dimensions to the language, not just besyntaxsugar for old ones. IMHO, top_cast is one of those features.
Mar 16 2003