[PEAK] Use cases for the priority feature

P.J. Eby pje at telecommunity.com
Tue Aug 17 19:14:44 EDT 2010


At 12:37 AM 8/18/2010 +0200, Christoph Zwerschke wrote:
>Am 17.08.2010 23:16 schrieb P.J. Eby:
> > You haven't seen the new combine_using decorator, have you? ;-)
>
>No, I hadn't, I'm learning something new every day here :)
>
> > from peak.rules import combine_using, when
> >
> > @combine_using(max)
> > def getDiscount(...):
> > return 0
> >
> > @when(getDiscount, "customer=='Elvis'")(value(.1))
> > @when(getDiscount, "product is shoes")(value(.05))
>
>The @'s need to be removed, and value imported from core, right?

The new API is to import things from the main peak.rules module if 
it's to "use" peak.rules.  If it's to "extend" peak.rules, you import 
from the defining module.  Right now, the public API consists of:

AmbiguousMethods
DispatchError
NoApplicableMethods

abstract
after
around
before
combine_using
expand_as
istype
let
value
when

@expand_as lets you turn functions into conditions, e.g.:

@expand_as("filter is None or value==filter")
def check_condition(filter, value):
     pass

You can then use "check_condition(x, y)" in a rule somewhere, and 
it'll be treated as if you'd said "x is None or x==y" in the rule directly.

And 'let()' is a pseudo-function you can use in a rule to create 
temporary "variables" to simplify complex conditions.  You can then 
also have those variables passed in to extra arguments on your rule's 
method...  a bit like pattern matching in other languages.


>  You should document the "value" function somewhere, it's simple 
> but handy, but at first I didn't see where it was coming from.

Um, it's in README.txt, line 278.  (The section just before 
"combine_using".  It's got examples and everything.  ;-)

let() and expand_as aren't in there yet, but they at least have 
extensive docstrings.


>But isn't the problem here that every function gets evaluated, and 
>only then the maximum is calculated?

Only the *applicable* ones.


>While with priorities, only the getElvisDiscount method would be 
>evaluated. In this example, it may not be a big problem, but in the 
>other use cases?
>...
>Granted, that should work. But it looks a bit overly complicated to 
>me, because you have to work with functions getters here, whereas 
>with the priority parameter you could use the actual functions and 
>spare some of the overhead.

Hm.  I just thought of a totally different way to do priorities in that case:

    when("requestedQuality>20 and ...")

Then always request the maximum quality -- higher levels will imply 
lower ones, and thus be more specific.  ;- )  (i.e. if quality>20, 
then it also is >10.)

You do have to have unique quality levels in that case, but then, you 
also have to have unique priorities in that case.

I guess what I'm saying is, at some point to have a total ordering, 
you have to manage the whole of the rule system.  HOW you do that is 
less important than *that* you do it.

I am worried, though, that numeric priorities built into the system 
encourages people to impatiently wave their problems away without 
learning anything...  until their rules are so encumbered by magical 
priority numbers that they end up spending so much time tweaking the 
priorities that they decide to do without rules altogether.  ;-)




More information about the PEAK mailing list