About a year ago I worked on a project with 4 string types:
Aphelion (an image processing library) used AphString in their C++ code.
Aphelion, the same damn library, used char* in many parts of their library that was based on KBVision, an old product of theirs. Notice it was a char* - not a const - so the other string classes were not automatically converted.
C++ standard string class.
mfc's CString.
Anybody got that beat? So much for the Pragmatic Programmer's "Don't Repeat Yourself" principle.
I'd love to see puzzles on slashdot. Here are two you might enjoy - one C++ and one regular.
How do you implement function overloading by return type in C++? solution (From an article in comp.lang.c++)
One day two mathematicians, Igor and Pavel, meet in the street. "How are you? How are your sons?" asks Igor. "You have three sons as I remember, don't you? But I have forgotten their ages." "Yes, I do have three sons," replies Pavel. "The product of their ages is equal to 36." Looking around and then pointing to a nearby house, Pavel says, "The sum of their ages is equal to the number of windows in the building over there." Igor thinks for a minute and then responds, "Listen, Pavel, I cannot find the ages of your sons." "Oh, I am very sorry", says Pavel; "I forgot to tell you that my oldest son has red hair." Now Igor is able to find the ages of the brothers. Can you do it?
Solution (From The Chicken from Minsk by Yuri Chernyak & Robert Rose)
If you like puzzles, you may like my page <shameless plug>Playful Thoughts</shameless plug>.
I hate the name "Metaobject Protocall" (MOP). It sounds academic - not something that a working programmer would ever make use of. I would like to (briefly) describe what a MOP is and why it is useful.
A MOP opens up a compiler in controlled ways. You define call-back functions that will be called when the compiler recognizes certain constructs - like defining a member function, assigning to a class, or using a class in an expression (like vector a+b). There will also be ways of finding and changing a class's members and base classes. The way you define these callbacks, is through metaclasses. It's easy, but not really that important for this brief introduction (see OpenC++). A not-so-bad way to think of a MOP is as the builder pattern.
That's the mile high view. Now, what can we do with it.
Before/after methods. Originally, Stroustrup had before/after methods in C++ (he took them out after he found he was the only one making use of them). Before/after methods could be defined for functions so when the function was called its before method would be called first, and when the method returned, its after method would be called. This was useful for locking and unlocking semaphores (for example). Now, with a MOP, this is easy to implement. Everytime a method is called, we can use our hook into the compiler to insert a call to our before method and after method.
Delegation. The decorator pattern uses delegation as its implementation. Consider a graphics class hierarchy: class Graphic; class GraphicDecorator : public Graphic. GraphicDecorator has a data member of type Graphic*. It needs to forward all of its function call to its contained graphic. This is straight-forward, but error prone. If we add a new function to Graphic, we need to remember to add it to GraphicDecorator as well. With a MOP, we can automatically build an class that delegates its function calls.
Mulidispatch. I built code that does double-dispatch for C++ (for the visitor pattern). The implementation to make the function call was pretty straight forward: some tables of pointers to members that are indexed by the parameters (a virtual function call on the parameters to get the correct index). While the code to make the call was easy, building the tables was not. To build the tables, I needed to know and the inheritance tree. While the compiler knew this, I couldn't get at it. So I had to build code to automatically create this information at "static initialization" time (I don't know the correct term). This was especially challenging because of static initialization ordering problems. With a MOP I can directly access the inheritance tree. I don't have to build it myself. As a side note, Stroustrup did consider putting multidispatch into C++, but decided against it because it required too complex a linker.
Optimizing vector/matrix classes. If you know about metatemplate programming (see blitz), you know you have to write some very complex code to optimize linear algebra code. With a MOP, you can use the hook to translate expressions to do these optimizations much more sanely.
Object persistence. If you want to use pointer swizzling to implement object persistence, you need to know where the pointers are on a given page. With a MOP, you can find the layout of an object and keep track of where the pointers are on a memory page.
Writing browsers.
Writing "bridge" code to interface C++ with other languages, like Python.
I hope this gives you a taste of why I'm excited about MOPs. I haven't written much code using MOPs (I certainly don't claim to be an expert), and I'm not sure its ready for prime time yet, but I'd love to hear Stroustrup's view on this.
I've been playing around with OpenC++, C++ with a metaobject protocol and I find opening up the compiler in controlled ways like this to be very powerful - and more than just an academic toy. It would allow me to extend C++ in interesting ways to include Delegation (useful for the "Decorator" pattern) and multi-dispatch (useful for the "Visitor" pattern) - along with other interesting extensions (before/after methods, persistance, etc.). I know you considered and rejected both of these features in C++ (if I remember from "Design and Evolution of C++" you rejected Delegation because users found it confusing and you rejected multi-dispatch because it required too complex a linker[1]). I am not questioning your rejection of these features, but I would be interested in your option of a metaobject protocol for C++, which would allow me to add features like these to C++ so it is a closer to my designs. Did you consider a metaobject protocol for C++, and if you did why did you rejected it (too immature? too hard to maintain code? not useful enough to justify the complexity to the language?)
-Scott nonya_cpp_question@yahoo.com
[1] I should mention my version of Multi-Dispatch doesn't solve the linker problem, it requires you call a function at the start of a program to initialize some tables of pointers to member functions.
I'm about 3/4 the way through this book. And I'm enjoying it. But I don't think this book is a 9 out of 10. It is valuable because it clearly explains things we may already know, but may have difficulty explaining. For example, the helicopter analogy explaining orthogonality was outstanding.
On the other hand, this book isn't going to change the way I program. While "Pragmatic Programmer" is well written, and will be enjoyed by serious programmers, it is not in the same category as "Design Patterns" of Graham's "On Lisp". This book has good, common sense advice. You you're a serious programmer you might enjoy picking up the book and nodding along with it - but if your stack of books to read is as large as mine, skip this one. Your time is better spent learning something new rather than reinforcing what you already know. If you're just becoming serious about programming, then I'd recommend this book. I'd give it a 6/10 for this audience.
I believe the congressional record is wrong. The quote starts with "Communists..."
Als die Nazis die Kommunisten holten, habe ich geschwiegen; ich war ja kein Kommunist. Als sie die Sozialdemokraten einsperrten, habe ich geschwiegen; ich war ja kein Sozialdemokrat. Als sie die Gewerkschafter holten, habe ich geschwiegen; ich war ja kein Gewerkschafter. Als sie die Juden holten, habe ich geschwiegen; ich war ja kein Jude. Als sie mich holten, gab es keinen mehr, der protestieren konnte.
(Translation by Bob Berkovitz)
When the Nazis arrested the Communists, I said nothing; after all, I was not a Communist. When they locked up the Social Democrats, I said nothing; after all, I was not a Social Democrat. When they arrested the trade unionists, I said nothing; after all, I was not a trade unionist. When they arrested the Jews, I said nothing; after all, I was not a Jew. When they arrested me, there was no longer anyone who could protest.
The article is from the April 29, 1999 WSJ. Here is a quick summery:
Among other things, Jeffrey Papows claims (according to the article):
PhD Pepperdine University
Marine Pilot
Marine Captain
He discovered a live grenade in a trench he and another marine were in. He threw the grenade out of a trench and saved their lives.
Helps the widow of a flier who died ejecting from a jet he and Papows were flying
Black Belt Tae Kwon Do
Mass State Tae Kwon Do Champ (2 out of three years)
Truth (according to the article):
PhD Unaccredited correspondence school
Marine air-traffic controller (1976 - 1979, no longer in the reserves, as he claims)
Left the marines with the rank of First Lieutenant
Papows says people must have misunderstood about the grenade story. He says it never happened and they are probably confusing it with another incident that happened at military school (which is also exaggerated).
As he was never a pilot, the story about helping the widow of man who died ejecting from his plane could not have happened. The story is most likely taken from the movie "Top Gun".
He is a red-belt in Tae Kwon Do.
He never entered the Tae Kwon Do state championship in 1995 or 1996 (two of the years in question).
Currently we imprison a larger percentage of our population that any other country in the world (a little over one percent of our population, if I remember.)
According to this article in Scientific American, the U.S. prison population is 668 per 100,000 (~.7%). Only Russia has more, with 690 per 100,000. Check out the article, worth a read.
- Aphelion (an image processing library) used AphString in their C++ code.
- Aphelion, the same damn library, used char* in many parts of their library that was based on KBVision, an old product of theirs. Notice it was a char* - not a const - so the other string classes were not automatically converted.
- C++ standard string class.
- mfc's CString.
Anybody got that beat? So much for the Pragmatic Programmer's "Don't Repeat Yourself" principle."How are you? How are your sons?" asks Igor. "You have three sons as I remember, don't you? But I have forgotten their ages."
"Yes, I do have three sons," replies Pavel. "The product of their ages is equal to 36." Looking around and then pointing to a nearby house, Pavel says, "The sum of their ages is equal to the number of windows in the building over there."
Igor thinks for a minute and then responds, "Listen, Pavel, I cannot find the ages of your sons."
"Oh, I am very sorry", says Pavel; "I forgot to tell you that my oldest son has red hair."
Now Igor is able to find the ages of the brothers. Can you do it?
Solution (From The Chicken from Minsk by Yuri Chernyak & Robert Rose)
If you like puzzles, you may like my page <shameless plug>Playful Thoughts</shameless plug>.
I hate the name "Metaobject Protocall" (MOP). It sounds academic - not something that a working programmer would ever make use of. I would like to (briefly) describe what a MOP is and why it is useful.
A MOP opens up a compiler in controlled ways. You define call-back functions that will be called when the compiler recognizes certain constructs - like defining a member function, assigning to a class, or using a class in an expression (like vector a+b). There will also be ways of finding and changing a class's members and base classes. The way you define these callbacks, is through metaclasses. It's easy, but not really that important for this brief introduction (see OpenC++). A not-so-bad way to think of a MOP is as the builder pattern.
That's the mile high view. Now, what can we do with it.
I hope this gives you a taste of why I'm excited about MOPs. I haven't written much code using MOPs (I certainly don't claim to be an expert), and I'm not sure its ready for prime time yet, but I'd love to hear Stroustrup's view on this.
-Scott
Metaobject protocalls, like the one in OpenC++ is a nice way to handle the optimizations that template metaprogramming gives.
I've been playing around with OpenC++, C++ with a metaobject protocol and I find opening up the compiler in controlled ways like this to be very powerful - and more than just an academic toy. It would allow me to extend C++ in interesting ways to include Delegation (useful for the "Decorator" pattern) and multi-dispatch (useful for the "Visitor" pattern) - along with other interesting extensions (before/after methods, persistance, etc.). I know you considered and rejected both of these features in C++ (if I remember from "Design and Evolution of C++" you rejected Delegation because users found it confusing and you rejected multi-dispatch because it required too complex a linker[1]). I am not questioning your rejection of these features, but I would be interested in your option of a metaobject protocol for C++, which would allow me to add features like these to C++ so it is a closer to my designs. Did you consider a metaobject protocol for C++, and if you did why did you rejected it (too immature? too hard to maintain code? not useful enough to justify the complexity to the language?)
-Scott
nonya_cpp_question@yahoo.com
[1] I should mention my version of Multi-Dispatch doesn't solve the linker problem, it requires you call a function at the start of a program to initialize some tables of pointers to member functions.
I'm about 3/4 the way through this book. And I'm enjoying it. But I don't think this book is a 9 out of 10. It is valuable because it clearly explains things we may already know, but may have difficulty explaining. For example, the helicopter analogy explaining orthogonality was outstanding.
On the other hand, this book isn't going to change the way I program. While "Pragmatic Programmer" is well written, and will be enjoyed by serious programmers, it is not in the same category as "Design Patterns" of Graham's "On Lisp". This book has good, common sense advice. You you're a serious programmer you might enjoy picking up the book and nodding along with it - but if your stack of books to read is as large as mine, skip this one. Your time is better spent learning something new rather than reinforcing what you already know. If you're just becoming serious about programming, then I'd recommend this book. I'd give it a 6/10 for this audience.
I believe the congressional record is wrong. The quote starts with "Communists..."
Als die Nazis die Kommunisten holten,
habe ich geschwiegen; ich war ja kein Kommunist.
Als sie die Sozialdemokraten einsperrten,
habe ich geschwiegen; ich war ja kein Sozialdemokrat.
Als sie die Gewerkschafter holten,
habe ich geschwiegen; ich war ja kein Gewerkschafter.
Als sie die Juden holten,
habe ich geschwiegen; ich war ja kein Jude.
Als sie mich holten, gab es keinen mehr,
der protestieren konnte.
(Translation by Bob Berkovitz)
When the Nazis arrested the Communists,
I said nothing; after all, I was not a Communist.
When they locked up the Social Democrats,
I said nothing; after all, I was not a Social Democrat.
When they arrested the trade unionists,
I said nothing; after all, I was not a trade unionist.
When they arrested the Jews,
I said nothing; after all, I was not a Jew.
When they arrested me, there was no longer anyone who could protest.
I just joined the EFF too. $100 well spent.
Among other things, Jeffrey Papows claims (according to the article):
- PhD Pepperdine University
- Marine Pilot
- Marine Captain
- He discovered a live grenade in a trench he and another marine were in. He threw the grenade out of a trench and saved their lives.
- Helps the widow of a flier who died ejecting from a jet he and Papows were flying
- Black Belt Tae Kwon Do
- Mass State Tae Kwon Do Champ (2 out of three years)
Truth (according to the article):Currently we imprison a larger percentage of our population that any other country in the world (a little over one percent of our population, if I remember.)
According to this article in Scientific American, the U.S. prison population is 668 per 100,000 (~.7%). Only Russia has more, with 690 per 100,000. Check out the article, worth a read.