View Source

Just to quickly summarize an idea for further implementation on Fantom just for fun.
The idea is to enable [multiple dispatch|http://en.wikipedia.org/wiki/Multiple_dispatch]. Probably the same ideas can be further expanded to full-featured pattern matching.
# Everything will be implemented in a single *dispatch.pod*.
# There will be one class Dispatch with api like this:
{code}
const class Dispatch
{
** Do we really need name and ret?
new make(Str name, Type ret)

** Registers new function, args are picked from this func
** If default, then it will be called when nothing better is found
Dispatch add(Func f, Bool default := true)

** Calls fitting func, if nothing matches, calls default. If no default, throws Err
Obj? call(Obj?[] args)
}
{code}
Thus, anyone can construct a dispatcher like this:
{code}
d := Dispatch("collide", Void#)
.add |Ship s, Asteroid a| { s.destroy }
.add |Ship s1, Ship s2| { s1.destroy; s2.destroy }
.add |Asteroid a, Ship s| { s.destroy }
.add |Asteroid a, Asteroid b| { }

Obj ship := Ship()
Obj asteroid := Asteroid()
//wow!
d.call([ship, asteroid])
{code}
# There also will be DSL plugin to enable Dispatch construction at compile-time (with proper error generation if possible) and facet @DispatchFunc, so the following code will be allowed (need to check whether current DSL API allows it):
{code}
class OpTransform
{
** inclusive transform of insert operation against remove
@DispatchFunc{ name = "transform" }
Op transformIR(Insert op1, Remove op2)

** inclusive transform of remove operation against insert
@DispatchFunc{ name = "transform" }
Op transformRI(Remove op1, Insert op2)

//... 30 more operations ...

** That's the trick!
Op transform(Op a, Op b) { Dispatch<|transform|>.call([a,b]) }
}
{code}
# In _method mode_, by involving default param values, one more interesting feature can be enabled (synthetic example):
{code}
class Sorter
{
@DispatchFunc { name = "sort" }
Obj[] sortEmpty(Obj[] list := Obj[,])

@DispatchFunc { name = "sort" }
Obj[] sortNonEmpty(Obj[] list)

Obj[] sort(Obj[] list) { Dispatch<|sort|>.call([list]) }
}
{code}