fbpx
dirtSimple.orgwhat stands in the way, becomes the way
CLOS-style Method Combination for Generic Functions

CLOS-style Method Combination for Generic Functions

…is now available in PyProtocols CVS. So far this is just the CLOS “standard” method combination, with before/after/around/primary/call-next-method. But the infrastructure is now there to build any sort of qualifier-based method combination ala CLOS’ ones. If you’re not familiar with method combination,this chapter from Peter Seibel’s book has a nice introduction to the basics that doesn’t really require you to know any Lisp. Before you read his book, however, first check out the doc page I wrote, as I’m trying to make the PyProtocols docs explain method combination without resorting to just saying, “they’re just like in CLOS.” 🙂 So, if you have any trouble following what I wrote, check out the Lisp link and tell me what I can improve on!

There’s still additional method-combination work to do, as I’d like to get equivalents to most of the useful CLOS built-in combination strategies, and document with examples how to build a custom combination strategy of your own. But the basic framework is now there to permit doing all of that.

Join the discussion
6 comments
  • I noticed that the conditions of the after() methods are evaluated when the function is first call. Is there any way to have them evaluated after the actual function runs?

    Maybe, for the bank example, you want an after() method that tells you if you have low funds. That means you need to look at the value of self.balance after the primary withdraw() methods have completed. (ie. You start with $1000. You withdraw $950, and you want an after() method that prints out a warning if you self.balance < 100) Does this require writing one’s own method combiner? Or is the system setup so that all the conditions will always be evaluated beforehand?

  • Wow, I should proof-read those comments of mine a bit better before I post…

    Anyway, I just thought of one trivial way to do it, and that would be an after() method with strategy.default, which checks the self.balance within the function itself.

  • “””Does this require writing one’s own method combiner? Or is the system setup so that all the conditions will always be evaluated beforehand?”””

    The answer to both questions is “yes”. 🙂

    More specifically, you *can* write your own method combiner to do it, but that combiner would have to work by tacking on a call to a second generic function.

    Even more specifically, you’d have to do this by subclassing GenericFunction and replacing the ‘after’ method such that it actually registered the condition and function with a different generic function.

    A second generic function is needed because a given generic function only tests the conditions once, all at once, and then figures out *all* the methods that apply, and combines them. And then it caches the combined form so it never has to combine the same N methods more than once. So, within a single generic function invocation, you can’t test the conditions more than once.

  • I am excited that you are taking the time and effort to try all this out. After reading your experience about how generic functions reduce a lot of code I am not sure that Python should follow everything Java does. Then again CLOS is probably not the last word spoken on this issue either. Please take the time to look at these links:

    1. http://www.cs.washington.edu/research/projects/cecil/www/Release/doc-cecil-lang/cecil-spec.ps
    Read pages 6-9.

    Home page http://www.cs.washington.edu/research/projects/cecil/

    2. http://tunes.org/~eihrul/talk.pdf
    Prototypes with multiple dispatch (short presentation 20 slides)

    The full thesis is on http://slate.tunes.org/ website

    Hope you get enlightened (maybe you already are).
    And maybe you can tell me what you think about it.

    Nestor

  • “””Read pages 6-9.”””

    That covers a lot – could you be more specific? Note, by the way, that PyProtocols’ generic function implementation actually implements the full “unsugared” model of Cecil-style predicate dispatch, albeit modified for use of classes rather than prototypes. I stole the algorithms from some Cecil-related papers. 🙂

    “””2. http://tunes.org/~eihrul/talk.pdf“””

    That one’s a lot more interesting, although the prototype-based example doesn’t do anything you can’t do with PyProtocols’ generic functions. Once I implement Cecil-style “predicate abstraction” sugar, you’ll even be able to make your generic function method guards look more like this, e.g. by using predicates like ‘is_healthy(shark)’.

    Anyway, it’s interesting mainly because it gives really nice examples of why predicate dispatch is handy, not because it introduces anything that’s not in Cecil or PyProtocols. Unless I’m misunderstanding something, of course.

  • All clear then.

    When referring to the Cecil manual I was thinking in general terms about some of the design decisions that are interesting e.g.:

    “…multiple dispatching and multiple inheritance are
    both unbiased with respect to argument order and parent order…”
    (on page 7)
    OR
    “…the subtype graph can differ from the inheritance graph…”
    (on page 8)

    But since you already know about Cecil, feel free to ignore it.

    Since you kept mentioning CLOS, and even the wikipedia http://en.wikipedia.org/wiki/Multimethods does not mention Cecil and Slate in the multimethod entry, I just wanted to make sure that you knew about these other projects, where objects, types and generic functions are fundamental part of the design discussion.

    It is, at least for me, insightful when different people try to explain and implement the same thing slightly differently. It allows one to understand the concept better.

    Have a good day,

    Nestor

dirtSimple.org

Menu

Stay In Touch

Follow our feeds or subscribe to get new articles by email on these topics:

  • RSS
  • RSS
  • RSS

 

Get Unstuck, FAST

Cover photo of "A Minute To Unlimit You" by PJ Eby
Skip to toolbar