Reading myself into Lisp, currently on this page (http://landoflisp.com), I found the following statement on the second last paragraph on the page that shows when clicking the link CLOS GUILD:
The important thing to note about the example is that in order to figure out which mix method to call in a given situation, the CLOS needs to take into account both of the objects passed into the method. It is dispatching to a specific implementation of the method based on the types of multiple objects. This is a feature that is not available in traditional object-oriented languages, such as Java or C++.
Here is the example Lisp-code:
(defclass color () ())
(defclass red (color) ())
(defclass blue (color) ())
(defclass yellow (color) ())
(defmethod mix ((c1 color) (c2 color))
"I don't know what color that makes")
(defmethod mix ((c1 blue) (c2 yellow))
"you made green!")
(defmethod mix ((c1 yellow) (c2 red))
"you made orange!")
No I think that the last sentence is wrong. I can actually do exactly that with the following Java code:
public class Main {
public static void main(String[] args) {
mix(new Red(), new Blue());
mix(new Yellow(), new Red());
}
public static void mix(Color c1, Color c2) {
System.out.println("I don't know what color that makes");
}
public static void mix(Blue c1, Yellow c2) {
System.out.println("you made green!");
}
public static void mix(Yellow c1, Red c2) {
System.out.println("you made orange!");
}
}
class Color {}
class Red extends Color {}
class Blue extends Color {}
class Yellow extends Color {}
which gives me the same output, when I run it:
I don't know what color that makes
you made orange!
So my question is: Is this sentence on that page actually wrong and it is possible in Java / C++? If so, maybe it was not possible in an older version of Java? (Although I highly doubt that, since the book is only 5 years old) If not so, what did I forget to consider in my example?
In Java, there's no direct support for multiple dispatch. However you can emulate multiple dispatch by using several layers of single dispatch combined with overloading.
A Dispatcher is used to build an application by aggregating several services. The dispatcher maintains a registry of Service objects. A Service is categorized by the type of processing it performs: A pre-processing service pre-processes input data for the command being processed.
If you change your example to:
public static void main(String[] args) {
Color red = new Red();
Color blue = new Blue();
Color yellow = new Yellow();
mix(red, blue);
mix(yellow, red);
}
then you will get
I don't know what color that makes
I don't know what color that makes
Java is using the compile time types to figure out which overload of the method to call, where Lisp is dispatching on the runtime types. Java has to use the Visitor pattern in order to do double dispatch (calling a different implementation based on both the type of the object the method is called on and the type of the argument passed in).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With