Declaring Lambdas as Parameters in a Lambda (newest syntax)

What is the proper type declaration if you are creating a recurring lambda? Say I have the following lambda to create a timer that will count down minutes for me in the UI:

val org.eclipse.xtext.xbase.lib.Functions$Function2 makeAllZonesTimer = [
    int myDelay,
    org.eclipse.xtext.xbase.lib.Functions$Function2 makeAllZonesTimer2 |
    	if(myDelay>0) {
            allZonesRunTimer = createTimer(now.plusMinutes(1))[|
            	total_minutes_remaining = (myDelay-1)%3600
        		total_hours_remaining = (myDelay-1)/3600
        		postUpdate(all_zones_total_time_remaining, String::format("%1$02d:%2$02d", total_hours_remaining, total_minutes_remaining))
            	makeAllZonesTimer2.apply(myDelay-1, makeAllZonesTimer2)
            ]
        }
   ]

As I understand it, the proper syntax for the declaration is function2<paramtype1, paramtype2, resulttype> functionname.
However I can’t seem to find documentation to tell me what type to declare the lambda as. Home Designer (I know it’s buggy anyway, but even openhab runtime logs warn me) warns me that they should be parameterized, yada yada yada. I have tried everything I can think of for what sort of type the result and the second parameter (the passed in lambda) should be: lambda, lambdatype, void, Timer, Function, FunctionType…No luck yet.

Can anyone help me out? I know it still runs and it’s only a warning that I’m getting, not an error, but the perfectionist in me isn’t satisfied. Thanks!

First, import org.eclipse.xtext.xbase.lib.Functions

With that done you have an infinite regression problem:

val Functions$Function2<Integer, Functions$Function2<Integer, Functions$Function2<Integer, Functions$Function2 .....

So you can either ignore the warning or you need to go about setting up the timer some other way.

One approach is to use the Expire binding to implement your Timer.

String all_zones_total_time_remaining
Switch all_zones_total_time_remaining_timer { expire="1m,command=OFF" }
rule "Countdown timer"
when
    Item all_zones_total_time_remaining_timer received command OFF
then
    if(myDelay > 0) {
        total_minutes_remaining = (myDelay-1)%3600
        total_hours_remaining = (myDelay-1)/3600
        all_zones_total_time_remaining.postUpdate(String::format("%1$02d:%2$02d", total_hours_remaining, total_minutes_remaining))
        all_zones_total_time_remaining_timer.sendCommand(ON)
    }
end

This is assuming that myDelay is a gobal var. Kick off the timer (equivalent to calling makeAllZonesTimer.apply) just call all_zones_total_time_remaining_timer.sendCommand(ON).

This eliminates the infinite regression on warning from Designer and the Logs because you have completely eliminated the lambdas and timers.

1 Like

I wrote this up as its own Design Pattern here. The Recursive Timers Design Pattern has a more concrete example of using timers like the above.

1 Like

sleek. thanks a lot rich!