Is there a **simple** lambda example?

what’s the point in a lambda with no parameter ?

The point of lambda is not parameter, but possibility to reuse the code. That’s why almost every programming language has procedures and/or functions. I have a part of the code that’s being repeated 6 times, and I would like to put it in lambda. I don’t need any parameter for that code, because every call is exactly the same. I just want to be able to change it in one place, and not all over my rules file.

Best regards,
Davor

I don’t know the proper answer to your question, but you could always pass in something and then throw it away. if (true) blahblahblah…

Hello!

I know I could use some kind of “dummy” parameter, just thought someone might know a proper way to do it. Thank you for your reply.

Best regards,
Davor

If you don’t have a parameter, you should use a Script. The advantage is you can call a script from multiple .rules files whereas a lambda can only be called from the same file it is defined. But scripts won’t take arguments like lambdas.

That would be the “proper way”.

Hello!

Thank you for the answer. That’s exactly what I was looking for.

Best regards,
Davor

Hi!

Thank you for this nice explanation on lambdas. I followed this but cam across some problems. I use OpenHabian with OpenHAB 2.2.0.

In my items there is:

String Relay_StairPWR_LED  "LEDs for stairs"  <switch2>  {mqtt=">[mosquitto:Relay:command:ON:23/ON], >[mosquitto:Relay:command:OFF:23/OFF]"}

My rule file is as follows:

import org.eclipse.xtext.xbase.lib.*

var int PowerOnDelay = 700
var boolean ComponentCanPowerOn = true


//Lambda function:
val Functions$Function3 PwrCheck = [
    org.openhab.core.library.items.StringItem RelayLED,
    boolean CanPowerOn,
    int PwrDelay |
        if((RelayLED.state != "ON") && CanPowerOn)
        {
            sendCommand(RelayLED, "ON")
            Thread::sleep(PwrDelay) 
        }
        true
]

//I'm using in my rules than this call:
PwrCheck.apply(Relay_StairPWR_LED, ComponentCanPowerOn, PowerOnDelay)

The Relay_StairPWR is a string because it takes also other states than ON and OFF.

After saving this rule I get an info:

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'test.rules', using it anyway:
The use of wildcard imports is deprecated.
Function3 is a raw type. References to generic type Function3<P1, P2, P3, Result> should be parameterized

After firing a rule containing the lambda call i get:

[ERROR] [ntime.internal.engine.RuleEngineImpl] - Rule 'Test rule lambda call': 'state' is not a member of 'org.eclipse.smarthome.core.library.items.StringItem'; line 19, column 13, length 14

Of course the lambda is not executing. Where am I wrong here?

[SOLVED]
Found that this was written for OpenHAB 1.x, in OpenHAB 2.x the org.openhab.core.library.items. is not needed, just leave TypeItem name

but the INFO still appears in the log:

[INFO ] [el.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'test.rules', using it anyway:
Function3 is a raw type. References to generic type Function3<P1, P2, P3, Result> should be parameterized

This two posts helped me out:
https://community.openhab.org/t/reusable-rules-via-function-in-openhab-2/14571/4?u=erzyk
https://community.openhab.org/t/reusable-rules-via-function-in-openhab-2/14571/6?u=erzyk

I followed also this example later on. Thank you for this tip, but there is another thing that bothers me.
Am I right that lambdas are executed in a separate thread and the calling rule just triggers the lambda and goes on with is own code? I have in my lambda a Thread wait statement but the rule that call this lambda never waits this delay time. Is there a way to make the calling rule wait for lambda to finish it’s work?

This is incorrect. The calling rule will block until the lambda returns.

Do you mean Thread::sleep? Thread::wait will not work on this context.

Yes I meant Thread::sleep(ms).
OK, I checked i carefully again and it is indeed working fine.

I also changed Functions to Procedures since I do not need a return value. But everytime I get the INFO:

Procedure6 is a raw type. References to generic type Procedure6<P1, P2, P3, P4, P5, P6> should be parameterized

Look at the 2.0 syntax in the link I provided above. Procedure and Function work the same way.

After using Procedures for several months I can’t get rid of this issue on rules file loading:

[INFO ] [del.core.internal.ModelRepositoryImpl] - Validation issues found in configuration model 'X.rules', using it anyway:
Procedure2 is a raw type. References to generic type Procedure2<P1, P2> should be parameterized
 [INFO ] [del.core.internal.ModelRepositoryImpl] - Refreshing model 'X.rules'

It’s about this section of the lambda. It’s asking it to be presented in a more formal way, defining the paameter types in <> and the alias separately.
For Functions it also wants a return type defined in that <> list, void if there isn’t one, but I suppose that’s not needed for Procedures

//Lambda function:
val Functions$Function3 < StringItem, boolean, int, void > PwrCheck = [
    RelayLED,
    CanPowerOn,
    PwrDelay |

Thank you rossko57! That solved the annoying problem.

But sometimes I notice that a rules file does not load or stops working, maybe this will solve that issue.

That’s almost certainly something else, or two something elses, and it’d probably be best to start a new thread with details when you think it happens.

There is a cleaner syntax you can use.

val PwrCheck = [ StringItem RelayLED, Boolean CanPowerOn, Integer PwrDelay |

It will figure out whether it is a Functions or Procedures based on the value of the last line.

2 Likes

Oh , I had no idea.
That cleaned up a stranger warning during startup for me.

The easiest (and most usefull) example I could imagine is the following:
protected static Comparator STRING_COMPARATOR = [String s1, String s2 |
if(s1==s2){return 0;}
else if (s1 === null ){return -1;}
else if (s2 === null ){return 1;}
else return s1.compareTo(s2);
];
I decided to keep the type Comparator<String> to make it more clear.