adamsol / Pyxell

Multi-paradigm programming language compiled to C++, written in Python.
MIT License
54 stars 6 forks source link

Support for multiple dispatch #6

Open sirex opened 3 years ago

sirex commented 3 years ago

Do you have plans to add support for multiple dispatch, like in Julia language?

adamsol commented 3 years ago

That's an interesting idea that could be a nice generalization of virtual class methods. Although it doesn't seem to have many use-cases, a physics collision detection mechanism is a good one. I'll see how difficult it would be to implement.

sirex commented 3 years ago

Actually it is very useful, especially when combined with UCFS, where you can separate data types from functions.

For example:

class Pet def
    speaks: String = ""

class Cat(Pet) def
    speaks: String = "Mew"

class Dog(Pet) def
    speaks: String = "Huf"

func speak(pet: Animal): Void def
    print pet.speaks

Cat().speak()
Dog().speak()

This was only single dispatch, bet for example, if you want to add custom responses, depending on situation:

class Mood def

class Happy(Mood) def

func speak(pet: Cat, mood: Mood): Void def
    print "Mrrrr"

Multiple dispatch is similar thing, to function overloading, but which function to call is decided at runtime. I find it very useful.

I don't know how C++ is capable of dynamic type inference, but in general it is very difficult, unless it is already solved in C++.

sirex commented 3 years ago

For Python I use multipledispatch. It does not support full type inference, for example List[str] is not supported. It only supports what is possible with isinstance.

sirex commented 3 years ago

Another good use case is binary operator overloading, for example:

func add(a: Vector, b: Vector): Vector def
    ...
adamsol commented 3 years ago

Yeah, operator overloading is something I've been wondering about. It doesn't exactly fit as a class method, but more as a function outside of class definition, so it would probably work well with UFCS and multiple dispatch. This would be a big change to the language, but maybe worth implementing. Though I'm a bit sceptical about putting all methods into the global namespace.

C++ does only have single dispatch. There are ways of simulating multiple dispatch, like here: https://eli.thegreenplace.net/2016/a-polyglots-guide-to-multiple-dispatch/, but it's not very readable and not scalable enough. Probably some map (dictionary) of functions, with tuples of argument types as keys, would be necessary for a general implementation. I think that's how Python's multidispatch works.

sirex commented 3 years ago

All methods definitely should not be put into the global namespace. In order for a method to be considered, that method should be explicitly imported into module or be defined in that module.

For example if you want to add two Vector instances, you must import the method:

use vectors

a = Vector([1, 2])
b = Vector([3, 4])
print a + b