Is Julia's way of OOP superior to C++/Python? Why Julia doesn't use class-based OOP?

This wikipedia page is a good illustration of how hard it is for a language to add multiple dispatch afterwards. I have to say I’ve seen some of those examples in real life.


What if Julia would officially support Multiple dispatch way and OOP way officially?
Both pros and cons would be solved… :slight_smile:

(Although I found power of multiple dispatch reading materials and easier to read write and collaborate but … )

OOP is just single dispatch. Just dispatch on the first argument. Done.


What benefits does the OOP offer that multiple dispatch doesn’t already solve?


OOP from my point of view means that you can add properties to classes and inherit them… But you can do this with Julia already…


I have nothing problem with it :slight_smile: .

I’ve one silly problem that i am looking for , like in classes we use like class. and hitting tab gives all methods interactively but in Multiple dispatch way.
I’ve to use a function which prints all methods at once and not interactive. As we have in julia,
methods(...) I am thinking a way to get interactively those methods like auto completer .
This is Is there Way to know methods/functions of classes(modules/functions) - #5 by vedasulo and I hope that alot of innovation have done, this would come in future :slight_smile: .


Exactly this I was talking :slight_smile: .
It seems these have been merged. I hope i will see this using some extensions in ide’s .

When could i see it in action? :slight_smile:

a = [1]

giving a all autocompletion interactively or tab . and it was added 12 days ago:) , I am waiting.


No, it’s not merged yet — that’s why the PR is listed as “open”. Even when it is merged, you won’t see it until Julia 1.7.

1 Like

:slight_smile: I hope will see soon.
Thank you @stevengj :slight_smile:

Two words: Type Piracy.

Those are indeed two words.


While it’s often useful to be as terse as possible when making a point, I think using just ‘two words’ didn’t convey what you wanted it to. Could you explain why you think those two words are relevant?


That example was not type piracy. It defined a new function which would be scoped to that module. For example SomeModule.somefunction() and OtherModule.somefunction() are two different functions which happen to share the same name, not type piracy.

Ah, just realised that the eBook is on sale for 5 Euro :see_no_evil: thanks for mentioning it!


Won’t it look basically the same in languages such as python? As I understand, the power of multiple dispatch comes not from just the ability to define new functions operating on existing types - this is possible in the majority of popular languages. In fact, your example doesn’t need dispatch at all, if it doesn’t do piracy:

def add(c1, c2):
    return RGB(c1.r + c2.r, c1.g + c2.g, c1.b + c2.b)

def norm(c):
    return np.norm([c.r, c.g, c.b])

Yes, I was wondering the same thing as @aplavin. It does seem like using duck typing in Python helps to address at least some of the manifestations of the expression problem.

Now write this in such a way that it’s extensible for other colour subtypes, e.g. HSV, CMYK, etc.

Furthermore, you want a system such that people who write their own colour subtype will also be able to interface with the add and norm functions.

Duck typing helps initially, but only so far.


I completely agree with you. It’s just that the short two-line example is not enough to illustrate multiple dispatch vs others.


Right. So that’s one of the other “solutions” to this problem in my talk — don’t use OOP at all, just use external functions. Which does work, but then you can no longer specialize or dispatch on the first argument, c1 and c (let alone c2). Moreover, the argument follows this trajectory:

  • Here’s a problem that is hard in OOP.
  • Solution: don’t use OOP at all, just use functions.

That is a solution, but it does not counter the fact that the problem is a problem for OOP, it instead shows that you can solve the problem by abandoning OOP entirely. In general, in functional programming it is easy to add new operations to existing types: functions don’t live inside of types like methods do in OOP, so you can just define a new external function to add an operation to an existing type. Problem solved. However, you have the opposite difficulty in the functional approach: it’s hard to make existing operations apply to new types. This is easy to do in OOP — you just subclass whatever the operation is defined on and add a specialized method.

Consider this add function that you just defined in Python. It works great if c1 and c2 are ducklike enough to quack in response to accessing the .r, .g and .b fields. But what if wanted to make the add function work on something less ducklike that needed a different implementation? You need to edit the original add function and add if/else type check for each new implementation that you want to support. Which works, but isn’t extensible: you need to modify the function for each new type you want to support. This is exactly the kind of problem that OOP was introduced to solve. Multiple dispatch doesn’t have any problem here: you can define add like that and then just write more specialized methods as needed. No fuss, no muss.

In summary, the expression problem presents as different problems for object-oriented and functional programming paradigms:

  • In OOP, it presents as difficulty adding new operations to existing types, which is easy when just using functions;
  • In functional programming, it presents as difficulty making existing operations apply to new types, which is easy in OOP.

The magic of multiple dispatch is that both aspects are unproblematic: you can add new operations to existing types and extend existing operations to new types with equal ease and simplicity.