[MUSIC] In this optional segment, I want to tell you about the concept of multimethods in object oriented programming. This lets me be a little more fair. Because a language that had multimethods does not need the manual and awkward double dispatch idiom. That we just saw on Ruby on the previous segment. So here is what you could do in a language, not Ruby, but a different language that had something different. What we could do is we could take our Int, our MyString, and MyRational classes. Which were our three kinds of values that we can add in any combination. And we can have them each define three methods all called the same thing, all called add_values. And in these three methods, one of them would take an Int, one would take a MyString, and one would take a MyRational. So we would actually have nine total methods called add_values. Three of them define an Int, three in MyString, three in MyRational. And all nine combinations correspond to one of the methods called the same thing. And then in our language when we said e1.eval.add_values e2.eval. What we would end up doing is saying, well, e1.eval is either an Int, a MyString, or a My Rational. e2.eval is an Int, a MyString, or a MyRational. And the semantics of our language will pick the correct method out of the nine possibilities and call that one. So we have multiple methods with the same name and we're going to pick the right one based on the run-time class of our operands. Both the operand on the left of add_values and the operand that is the other argument. And if your language does that, it's a language with multimethods which is also know as as multiple dispatch. So the general idea is that we allow multiple methods with the same name. We have to indicate which ones take instances of which classes. And then, at run time we use dynamic dispatch not just on the receiver, which is what every OOP language does. But on the receiver and the arguments. We use all of the arguments including the receiver to pick the best method, even when multiple methods have the same name. So on the one hand, if dynamic dispatch is the thing that makes OOP different, we just added more dynamic dispatch. Which makes this kind of a more OOP construct. Right? Now we're doing dynamic dispatch not just on the thing to the left of the dot. But we're also using the arguments to pick the best method based on the runtime classes of more things. The downside is, there are situations where this idea interacts with subclassing such that it's not clear what the best method is to call. There are multiple methods with the same name. And you could call more than one. They would all make sense and you're not sure which one to call. And you need to define that in your language. Or programmers are going to get very confused when they expect one method to be called and you actually call another one. Okay. So, I actually think multimethods are pretty neat, but I would not suggest adding them to Ruby. There's a couple reasons. One is, Ruby does not have method definers indicate the class of the thing they accept. That's not Ruby at all. Ruby is a very dynamic language. You can pass any object to any method. But multimethods relied on that. When we were picking which one to call. We needed to know that this method called add_values expects a MyRational as its argument. And that one called add_values expects a MyString as its argument. This is pretty fundamentally incompatible with Ruby. The second reason why I wouldn't add it to Ruby is Ruby has a very simple rule. Which is that classes never have more than one method with the same name. All right? When you're defining a class if you repeat a method definition, it replaces the earlier one. And similar in subclassing, having a method of the same name as something in the super class means overwriting. It's a simple rule. It works just fine. But multimethods requires multiple methods with the same name. Finally, probably some of you are thinking, I know Java, or C#, or C++. And they definitely allow multiple methods in the same class with the same name. And you are right. But these languages do not have multimethods. They have something different. Something that has different advantages and disadvantages, and which is called static overloading. When you have multiple methods with the same name in Java and C# and C++. You use the static types of the arguments to choose which method you actually meant. So on the receiver, the thing to the left of the dot, of course we use the run-time class, that's dynamic dispatch. But then, for the other arguments, we use the static types. Which of course doesn't work in Ruby, where we don't have a type system that gives us that information. And while static overloading is convenient to a lot of people I've always found it a bit of a strange hybrid. That you use the run-time class of the receiver and the compile time types of the other arguments. I'm not going into the details of static overloading here. But I would point out that it does not help in our example. That our binary operation where we add two values where each value can be an Int, a MyRational, or a MyString. Static overloading is not very helpful. We need to code up double dispatch manually. The only thing static overloading lets us do is instead of calling the methods addString, addRational and addInt. We can give them all the same name, add. Which I personally find more confusing than helpful. But it is conventional in languages with static overloading to just give them all the same name. Should also be fair to C#. C# 4.0 when they added the dynamic type, turns out you can use dynamic to get the effect of multimethods. So this is a sufficient solution. That you would basically make it seem like you were using the static overloading approach. But then by essentially casting your arguments to Type Dynamic, the C# language will give you multimethods. And that's kind of cool and is helpful in examples like this. But there are many other languages where multimethods aren't something added in version four. Or aren't sort of coded up by combining them with another feature. But it's actually just built in to their idea of how method calls work. A modern example is Clojure, but there have been many languages with multimethods that go back decades. They're not a new idea. They're just something that hasn't gone as mainstream in object-oriented programming. As some of the other concepts that we've studied.