[Python-3000] Adaptation vs. Generic Functions
Guido van Rossum
guido at python.org
Sat Apr 8 17:29:30 CEST 2006
On 4/8/06, Phillip J. Eby <pje at telecommunity.com> wrote:
> Naturally, if your goals are more modest, dealing only with actual
> arguments, no expressions, no operators other than 'isinstance()', no
> ability to apply boolean logic to the conditions (e.g. "isinstance(arg1,A)
> and isinstance(arg1,B)", or perhaps "not isinstance(arg1,C)!"), then the
> logic for an interpreter is indeed much simpler. In that case, you can
> just use a series of dictionaries that each argument is checked against,
> one at a time, and you can build those dictionaries in a straightforward
> way at registration time.
Yes, I'd like to explore this approach first: (a) Java and C++ seem to
get quite a bit of mileage out of it; (b) I'm not sure that *all*
if/else tests at the top of a function should be frowned upon; the
ones that do type tests are usually the most suspect.
Of course, there are applications for more general predicates (like a
dungeons&dragons game dispatcher) but to me they all seem a bit
specialized to me.
> In that approach, the lookup loop could look something like:
>
> reg = self.root_registry
> for arg in args:
> for cls in type(arg).__mro__: # not exactly, but sort of
> if cls in reg:
> reg = reg[cls]
> break
> else:
> raise NoMatch # (or fall back to default)
>
> # reg is now a function or a placeholder indicating ambiguity
I was thinking of something like this (nested dicts) as a strategy to
deal with hundreds of registered methods. But I'm not sure if it
matters in practice give that this code is only executed once to fill
up the cache. I see more timing tests in my future... :-)
> You wouldn't actually use __mro__, in order to avoid the unstable dominance
> hierarchy problem, but you get the gist. If you use RuleDispatch and
> restrict what operations you use, you'll actually get almost exactly the
> above; it's just that RuleDispatch may not evaluate the args in strictly
> left-to-right order, depending on how "good" an argument is for
> dispatching. (RuleDispatch evaluates the "goodness" of expressions (such
> as arguments) by how well they fan out and flatten the dispatch tree, so it
> may decide that the last argument is in fact a better thing to check first.
>
> This approach of course has more hash table lookups than your approach, so
> these are all tradeoffs to be considered, and more importantly,
> measured. But in general I tend to see this space through the lens of
> "arbitrary boolean expressions" and thus may occasionally intuit wrong
> answers for the more limited scope you're contemplating here. Actually, I
> keep feeling like you're "cheating" because you can get away with so little
> code -- and I keep having to remind myself that it's because there are so
> many things that the cached type tuple approach cannot. (The approach
> which you are using, and which other folks wrote papers about, prior to the
> Chambers & Chen paper on using dispatch trees to handle arbitrary predicates.)
I'm not sure if it's worth the complexity. Also, responding to stuff I
snipped that you wrote about access to ASTs is incredibly far in the
future; it's too close to macros or extensible syntax, which I am
explicitly ruling out from Python 3000 (I'm saying this so we don't
have to engage in an endless discussion).
> Anyway, I just got home from a 6+ hour flight, and I'm probably not being
> very coherent right now, so I'm going to go get some sleep. :)
And I have a 4-year-old next to me playing Elmo so I'm going to give
my family some time! :-)
--
--Guido van Rossum (home page: http://www.python.org/~guido/)
More information about the Python-3000
mailing list