Today I've created pod for support of multiple dispatch at runtime, see http://bitbucket.org/ivan_inozemtsev/mdispatch. The dispatcher itself is very simple constant class whichallows to create container of functions:
d := Dispatcher {
funcs = [
|Foo a, Bar b -> Str | { "foo vs bar" },
|Bar a, Foo b -> Str | { "bar vs foo" },
]
}
and invoke appropriate function by calling call(Obj?[] args):
verifyEq("foo vs bar", d.call([foo, bar]))
verifyEq("bar vs foo", d.call([bar, foo]))
The more interesting thing here is DSL plugin. Sample code (synthetic example):
class SampleProcessor
{
Obj?[] list := [,]
@Dispatch SampleProcessor processStr(Str s) { list.add(s); return this }
@Dispatch SampleProcessor processInt(Int i) { list.add(i); return this }
SampleProcessor process(Obj? obj) {
Dispatcher<|process|>.call([this, obj])
}
override Str toStr() { list.toStr }
}
Usage example:
s := SampleProcessor()
echo(s.process(10)) //types [10]
echo(s.process("aaa")) //types [10, aaa]
The DSL plugin searches for all methods with a given prefix marked with @Dispatch facet and the code become equivalent to this:
ivan Mon 15 Nov 2010
Hi,
Today I've created pod for support of multiple dispatch at runtime, see http://bitbucket.org/ivan_inozemtsev/mdispatch. The dispatcher itself is very simple constant class whichallows to create container of functions:
d := Dispatcher { funcs = [ |Foo a, Bar b -> Str | { "foo vs bar" }, |Bar a, Foo b -> Str | { "bar vs foo" }, ] }and invoke appropriate function by calling
call(Obj?[] args):verifyEq("foo vs bar", d.call([foo, bar])) verifyEq("bar vs foo", d.call([bar, foo]))The more interesting thing here is DSL plugin. Sample code (synthetic example):
class SampleProcessor { Obj?[] list := [,] @Dispatch SampleProcessor processStr(Str s) { list.add(s); return this } @Dispatch SampleProcessor processInt(Int i) { list.add(i); return this } SampleProcessor process(Obj? obj) { Dispatcher<|process|>.call([this, obj]) } override Str toStr() { list.toStr } }Usage example:
s := SampleProcessor() echo(s.process(10)) //types [10] echo(s.process("aaa")) //types [10, aaa]The DSL plugin searches for all methods with a given prefix marked with
@Dispatchfacet and the code become equivalent to this:SampleProcessor process(Obj? obj) { processDispatcher.call([this, obj]) } private const Dispatcher processDispatcher := Dispatcher( "process", SampleProcessor#, [#processStr.func, #processInt.func] )Combined with
@Operatorfacet, this can give an ability to use operator overloading with runtime method selection.Few notes:
@Dispatchfacet are defined in the same fileEDIT: added bitbucket link