The parts Davide has updated are:
Pipes - Pass through Filters
Rising / Falling edges
Pipes - Pass through Filters
While accumulate performs map and fold operations it returns a derived result. Pipes allow us to filter a set of Tuple chains, that represent the actual join partial match results. In 5.0.x we had "over" as a temporal pass through filter, Person() over win:time(30s). We feel this concept should be more generalised to allow any pluggable filters, and for those filters to work on single Patterns of a group of patterns:
Person() | win:time(30s)These pipes can be combined, so we only allow the Persons for the last 10 minuts to propagate forward (retracting anyone who existed more than 10 mins ago) but we throttle the network updates to every 30s:
Person() | win:time(10m) | throttle(30s)This is important for combination with say accumulates, where we don't want every single change to be aggregated and the result propagated:
acc( Bus( $t: takings) | win:time(1h) | throttle(5m),So th above calculates the average takings for the last hour, continously, but it only updates the results every 5 minutes. Throttle is just currently a proposed filter name, we might come up with something different for that behaviour later.
$avgTakings : avg( $t ) )
Pipes don't just work on single Patterns, they can work on multiple patterns. So for instance we could provide a "unique" filter that remove ambiguous cross product joins; which Charles Forgy mentioned at ORF09. In the following example if we instead insert 3 As we would get 1 resulting match, not 9.
(A() A() A()) | uniqueUnit support
Groovy added unit support, based around leveraging JScience and JSR275. http://groovy.dzone.com/news/domain-specific-language-unit-. The dot notation is a bit too ambigous for Drools, but we already use # to cast patterns, so we can do the same for units.
3#km + 5#mWe can cast existing units to other units. So we can declare something as 3km, but have it returned as feet.
3#km#feetIf a unit is combined with a normal literal, then it's just a operator on that literal value, for instance the following is 6k, it is not executed in the same way as 3km * 2km would do.
3#km * 2# can be used with methods and functions. If the method returns a literal, then it's the same as saying 3km. If the method returns a unit, then it's like a caste:
returnInt()#kmThis works for strings too, and can be used to provide date/time formatting:
"2012 12 04"#myDateFormatRising / Falling edges
Grindworks supports the idea of executing actions on the rising or falling edges of a rule. While we could do this on the actions too, we think initially this would be better on the LHS, as a special conditinal element.
whenClealry rising is the default behaviour for a pattern. Whether we allow it's inclusion, for readability intent, or only support falling, is to be decided.
rising Person( age == 30 )
falling Person( age == 30 )
We could combine this with a branch
whenThis also has some ramifications for Logical Closures, as it solves some of the same problems.
branch( rising Person(....),
[b1] falling Person(....)