In Scala, for algebraic data types like expressions and addition, you'd just use pattern matching. That would encompass the example fully.
Scala has an "external" dispatch mechanism as well, basically a way to create new typed methods, namely pimping:
implicit class FooWrapper(foo: Foo) extends AnyVal {
def newMethod: Int = ...
}
val x: Foo = new Foo()
x.newMethod
These are all checked at compile time.
Note that the example given above is actually not multiple dispatch, but merely adding methods to a type. It differs from function overloading (a Java/C++) feature only syntactically.
Multiple dispatch would be dispatch on multiple type arguments, not simply one (which Julia has, but Scala does not).
Unfortunately, operators can't be externally extended in C#, so there is still a lot of wrapper creation, but extension methods can be used for that; e.g.
Signal<int> a = ..., b = ...;
var c = a.Bl() + b.Bl();
Bl is an extension method for signal ints that returns a wrapper around the argument that allows for access to the + method. Bl is overloaded for a variety of types to provide access to those wrappers.
Scala has an "external" dispatch mechanism as well, basically a way to create new typed methods, namely pimping:
These are all checked at compile time.Note that the example given above is actually not multiple dispatch, but merely adding methods to a type. It differs from function overloading (a Java/C++) feature only syntactically.
Multiple dispatch would be dispatch on multiple type arguments, not simply one (which Julia has, but Scala does not).