[rules-dev] exploring functional programming

Mark Proctor mproctor at codehaus.org
Mon Oct 25 19:36:51 EDT 2010


We are thinking of moving "accumulate" to a simple "for" keyword. We 
might allow 'in' and 'from' to be used interchangably and allow ';' semi 
colons to separate the sections. I'm also wondering ho we could allow 
function pipelines for the function part of the element. We also need 
type inference and "default" return values.

So here are some code snippets to show what I'm thinking, as 
improvements over what we do with accumulate now.

// Simple 'or' very simlar to accumulate before. ; for section 
separating. With a new boolean section at the end to decide whether to 
propagate or not. Will probably use '=' for function assignments.
$c : Customer()
for( $bi : BasketItem( customer == $c );
         $s = sum( $bi.price);
         $s > 100 )

// Multiple functions are ofcourse allowed
$c : Customer()
for( $bi : BasketItem( customer == $c );
         $mn =min( $bi.price),
         $mx = max( $bi.price); )

// As are multiple patterns, and as before patterns can come 'from' an 
expression and with type inference we can get some nice compact text:
for ( x in [0..4]
       y in [0..4]
       $c : Cell( row == y, col == x );
       $avg = avg( $cell.value );
       $avg > 100 )

The above is possible now with the following:
Integer( this > 100) from
     accumulate( x : Integer() from [0, 1, 2, 3, 4]
                 y : Integer() from [0, 1, 2, 3, 4],
                 $c : Cell( row == y, col == x ),
                 avg( $c.value) )

I think the proposed additions reall help with declarative readability.

The normal chaining of elements is supported:
$c : Customer()
for( $b1 : BasketItem() in
           for( $b2 : BasketItem( customer == $c );
                  filter( $b2, $b2.price > 100); );
         $a = avg( $b1.price ); )

'for' will have a default return type for each bound function. In this 
case it returns a single value $a, if there are multiple bound results 
an array/map must be used for access.

I also think we should allow pipelineing of functions, much as you would 
do in a normal functional programming, possibly using haskell like 
"stream fusion" capable functions.

// '$' refers to the magic contents of the function which is "piped" in. 
So $bi is piped to map, $ refers to each value evaluated in the 
function, with type inference. 'map' results are piped to 'filter'. The 
final results are assigned to $r.
$c : Customer()
for( $bi : BasketItem( customer == $c );
         $r = $bi | map( $, $.price * 2) |
                        filter( $, $.price < 100);
         $r.size > 100 )

More ideas welcome :) But I think this opens up some very interesting 
areas for DRL, with something that will hopefully feel more natural for 
developers.

Mark



More information about the rules-dev mailing list