Since the java version used in GroIMP does not yet support the java lambda functions, GroIMP comes with a set of own lambda functions. A Lambda function or anonymous function is a function that is not connected to an identifier and can be handled like a variable.
The XL implementation is mostly designed for mathematical or logical operations and follows a clear but strict syntax:
For instance the mathematical expression f(x)=x*0.7
could be defined by this expresison: IntToFloat f = int x ⇒ float x*0.7;
,
This can then be use to evaluate the function for a given integer to return a float: f.evaluateFloat(3)
.
This implementation is provided for any combination of the common data types (e.g. float, int, char, boolean, object) as well as for Void (in this case no input parameter is needed or no result is provided) A full list can be found int the javadoc.
In the following a very simple example shows one possible use case of these functions, providing different mathematical calculations for instance of the same module in one rule:
module A(float len, FloatToFloat calc) extends Sphere(0.1) { {setShader(GREEN);} } FloatToFloat l = float x => float x*1.2; FloatToFloat m = float x => float x*0.7; protected void init () [ Axiom ==> F(1) [RU(30) RH(90)A(0.5,l)] [RU(-30) RH(90)A(0.5,m)]; ] public void run () [ A(x,calc) ==> F(x) [RU(30) RH(90) A(calc.evaluateFloat(x),calc)] [RU(-30) RH(90) A(calc.evaluateFloat(x),calc)]; ]
custom rules
By using a Object function (eg. ObjectToFloat, BooleanToObject, ObjectToObject) the object can be more specifically defined in the function. For example the follwing lambda function will only work with node of the module A but can therefore also use attributes of this moduel:
ObjectToFloat getLen = A a => float a.len;
This works with module types and interfaces, for example the following code would let all Node implementing the Organ interface add one to the age.
public interface organ{ public int age; public void setAge(int a); public int getAge(); } public void ageing(){ ObjectToVoid grow = organ o => void o.setAge(o.getAge()+1); grow.evaluateVoid((*organ*)); }
Generators
Moreover it is possible to create lambda functions that return series of values.
These functions add the therm generator at the and for instance DoubleToDoubleGenerator
.
They can be used with XL queries:
public void test (){ DoubleToDoubleGenerator f = double x => double* ((*A*)).len*x; println(f.evaluateDouble(3)); }