[BangPypers] Clojure style multimethod functions in python
Dhananjay Nene
dhananjay.nene at gmail.com
Mon Aug 23 17:51:37 CEST 2010
On Mon, Aug 23, 2010 at 8:36 PM, Baishampayan Ghose <b.ghose at gmail.com>wrote:
> Dhananjay,
>
> > Could you help explain in light of the following (the argument lists are
> in
> > bold). The switcher function is provided exactly the same arguments as
> the
> > various multimethods. Probably something about clojure I am not aware of
> ?
> >
> > Dhananjay
> >
> > def multi(switcher_func):
> > """ Declares a multi map based method which will switch to the
> > appropriate function based on the results of the switcher func"""
> >
> > def dispatcher(*args, **kwargs):
> > key = *switcher_func(*args, **kwargs)*
> > func = dispatcher.dispatch_map[key]
> > if func :
> > return *func(*args,**kwargs)*
> > else :
> > raise Exception("No function defined for dispatch key: %s" %
> key
> > )
> > dispatcher.dispatch_map = {}
> > return dispatcher
>
> Multimethods are supposed to dispatch on the ``value'' returned by the
> dispatch function and not just when a specific condition is satisfied.
> What will you do when there are multiple possibilities? Ideally, I
> should be able to prefer a specific method to another one in case
> there is some ambiguity. Yours will always pick the first one that
> satisfies the condition, which is again dependent on the order in
> which the code is evaluated.
>
> For example, try implementing the following using your code -
> http://clojure.org/runtime_polymorphism
>
> Without making any change whatsoever to multi() and multi_method(),
the result of the following code :
# Declare the existence of a multi method switcher
encounter = multi(lambda x,y : (x["Species"], y["Species"]))
@multi_method(encounter, ("Bunny","Lion"))
def encounter(a1, a2):
return "run-away"
@multi_method(encounter, ("Lion","Bunny"))
def encounter(a1, a2):
return "eat"
@multi_method(encounter, ("Bunny","Bunny"))
def encounter(a1, a2):
return "mate"
@multi_method(encounter, ("Lion","Lion"))
def encounter(a1, a2):
return "fight"
b1 = {"Species" : "Bunny", "Other" : "Stuff"}
b2 = {"Species" : "Bunny", "Other" : "Stuff"}
l1 = {"Species" : "Lion", "Other" : "Stuff"}
l2 = {"Species" : "Lion", "Other" : "Stuff"}
print encounter(b1, b2)
print encounter(b1, l1)
print encounter(l1, b1)
print encounter(l1, l2)
*is
*
mate
run-away
eat
fight
Is that consistent with the expectations ?
Dhananjay
> Regards,
> BG
>
> --
> Baishampayan Ghose
> b.ghose at gmail.com
> _______________________________________________
> BangPypers mailing list
> BangPypers at python.org
> http://mail.python.org/mailman/listinfo/bangpypers
>
--
--------------------------------------------------------
blog: http://blog.dhananjaynene.com
twitter: http://twitter.com/dnene
More information about the BangPypers
mailing list