<br><br>On Tuesday, 3 September 2013, PJ Eby  wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Sun, Sep 1, 2013 at 4:07 PM, Sébastien de Menten &lt;<a href="javascript:;" onclick="_e(event, &#39;cvml&#39;, &#39;sdementen@gmail.com&#39;)">sdementen@gmail.com</a>&gt; wrote:<br>

&gt; @abstract<br>
&gt; def foo(a,b):<br>
&gt;   pass<br>
&gt; foo.when = lambda condition: when(foo, condition)   #&lt;== this could be<br>
&gt; better implemented in the abstract decorator<br>
<br>
Better still might be to implement @when() and other such APIs as<br>
macros that transform just the second argument; that way your code<br>
would not need the extra &quot;s&quot; function.  Still, it&#39;s definitely a way<br>
around the IDE issues, and doesn&#39;t suffer from the usual issues of<br>
access to source code (I assume, anyway).<br>
<br></blockquote><div>Indeed, good idea ! </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
&gt; For my second question, explaining the real domain space would need pages so<br>
&gt; I must find a &#39;to-the-point&quot; analogy that captures the gist of the problem.<br>
&gt; So here is one that does not use domain-specific terms but maps 100% with<br>
&gt; the problem.<br>
&gt; I have different kind of cars (pickup, sedans, convertible, etc) which have<br>
&gt; different transmissions (4x4, traction, propulsion) and different tires (all<br>
&gt; season, snow, high performance, etc) and all combinations of Car x<br>
&gt; Transmission x Tires are possible.<br>
&gt; Now the generic functions I want to write are like :<br>
&gt;  - &quot;optimal_acceleration(car, weather)&quot;<br>
&gt;  - &quot;maintenance_planning(car)&quot;<br>
&gt;  - &quot;customer_match(car, customer_profile)&quot;<br>
&gt; These functions may depend on the Car(Transmission, Tire) combination and<br>
&gt; while all may not be supported, I want to be able to add support for any of<br>
&gt; them. Moreover, if a user adds a new kind of transmission, or car, or tire,<br>
&gt; I want to be able to add the functions for these new combinations (if they<br>
&gt; make sense ... otherwise, an exception NoApplicableMethods is perfect !<br>
<br>
Sounds just like what PEAK-Rules is intended for.<br>
<br>
One thing you might want to watch out for in de-structuring rules like<br>
this (ones that depend on attributes of a parameter), is to remember<br>
that PEAK-Rules generally applies tests to parameters before testing<br>
attributes.  This doesn&#39;t affect rule *precedence* (as far as what&#39;s<br>
most specific), but it does affect *evaluation order*.<br>
<br>
For example, if all your rules for a given function read in this order:<br>
<br>
    isinstance(car.tires, Foo) and isinstance(car.transmission, Bar)<br>
<br>
That is, if they all check the tires before checking the transmission,<br>
then PEAK-Rules will conservatively assume that it&#39;s not safe to<br>
access the transmission attribute until after the tires are checked.<br>
This limits the shapes that the dispatch tree will be built in, even<br>
though it doesn&#39;t affect the answers given.  Under some circumstances,<br>
this might create larger or slower dispatch trees.<br>
<br>
In contrast, tests based directly on parameters are assumed to be<br>
independent of each other (e.g. &quot;param1&gt;1 and param2&gt;2&quot; is assumed to<br>
allow checking either condition first) and so can be used at any level<br>
of the dispatch tree, and so the builder is free to use whatever shape<br>
works best for that subtree (at a cost of a little more setup time to<br>
decide which shape is best.)<br>
<br>
I guess what I&#39;m trying to say is that if you have a relatively flat<br>
rule structure, based mainly on car, car.tires, and car.transmission,<br>
you may find it useful to make the tires and transmissions direct<br>
parameters, or else to deliberately vary the order they appear in your<br>
rules, so that the rule system will have maximum freedom to construct<br>
dispatch trees.<br>
<br>
I wouldn&#39;t even bother to mention this, except that from your<br>
description I don&#39;t have any way to know just how complex your<br>
dispatch trees will be.  In general, I find that generic functions<br>
tend to follow one of two patterns:<br>
<br>
1. &quot;Registry&quot; functions -- not heavily dependent on predicates, more<br>
dependent on types of a few key parameters, relatively simple rules<br>
with occasional extra criteria<br>
2. &quot;Pattern matching&quot; or &quot;compiler&quot; functions -- while one or two<br>
parameter types may be involved, the bulk of the rules are predicates,<br>
often deeply nested predicates on component objects; often found in<br>
compilers or compiler-like systems (such as PEAK-Rules itself) to<br>
pattern-match subtrees with complex conditions.<br>
<br>
In pattern #2, evaluation order may be rather important, but the tree<br>
size is fairly limited by the fact that most of the actual predicates<br>
exist for only a few rules.  In pattern #1, the bulk of the indexing<br>
is for that handful of parameters, so as long as they&#39;re<br>
freely-orderable (i.e., can be tested independently), you can&#39;t get a<br>
blowup of tree size.  (And in pattern #1, the tests are usually done<br>
directly on the parameters, not on attributes or methods or formulas<br>
using the parameters.)<br>
<br>
>From your vague description, I can&#39;t tell if your use case is more<br>
like #1 or #2, or some sort of hybrid.  If it&#39;s basically #1 but using<br>
lots of independent attribute-level checks, and you have very large<br>
rulesets, then you may want to promote the attributes to parameters<br>
(or access those attributes in different order some of the time), in<br>
order to allow PEAK-Rules full tree reordering freedom.  It will not<br>
affect the answers you get, only memory usage (and possibly speed).<br>
Even then, it&#39;s unlikely to do it in the kinds of uses I&#39;m familiar<br>
with, but since I&#39;m not familiar with your case, I am being<br>
extra-thorough and cautious.  ;-)<br>
</blockquote><div>It is definitely more the #2 (pattern matching). Is there some introspection ability on the decision tree PEAK-rules build ? Otherwise, i&#39;ll check first the overhead to see if it is penalising or not before optimising. </div>
<div>Thank you for you detailed description of these mechanisms !<span></span></div>