The LAMBDA function creates small, inline functions that can be passed around as IDL strings. These Lambda routines can be used to make function calls, or used as inputs to the ::Filter, ::Map, and ::Reduce methods.
Tip: You can use the LAMBDAP routine to create inline procedures instead of functions.
Note: LAMBDA can only create functions with a single return statement. To dynamically create functions with multiple IDL statements, you can use the COMPILE_CODE routine.
First we use a simple Lambda function with the Map method, to return the square root of a number:
var = [0:5]
PRINT, var.Map(LAMBDA(n: sqrt(n)))
0.000000 1.00000 1.41421 1.73205 2.00000 2.23607
Next we use a LAMBDA function with the Filter method, to return only prime numbers:
var = [2:50]
lam = LAMBDA(n:n le 3 || MIN(n mod [2:FIX(SQRT(n))]))
newvar = var.Filter(lam)
2 3 5 7 11 13 17 19 23 29 31 37 41 43 47
We can also make function calls directly on the returned Lambda variable:
PRINT, lam(499), lam(4999), lam(49999), lam(499999), lam(4999999)
1 1 1 0 1
See the bottom of this topic for more examples.
Result = LAMBDA( Code )
A string giving IDL's internal name for the Lambda function. You should ignore the actual value, but instead, you should pass the string into your Filter, Map, or Reduce call. You can also make direct function calls on the returned string and IDL will call your Lambda routine. For example:
lam1 = Lambda('n: n^3')
Note: To make direct calls on a Lambda function, you should make sure that compile_opt strictarr (or compile_opt idl2) is turned on so that IDL interprets the parentheses as a function call instead of array indices. See COMPILE_OPT for details.
A string containing your Lambda code, or the actual code itself. The string or code should have the following form:
"arg1, arg2, arg3,... : expression"
Your Lambda routine must accept at least one argument, although it does not necessarily need to use that argument.
The expression must be any valid IDL expression statement and can include any combination of unary, binary, or ternary (conditional) operators as well as function calls. The expression cannot contain multiple statements (using "&") and cannot contain any flow-control statements (such as if/then, while, etc.).
Note: If you use actual code within the LAMBDA call, then all of your statements must fit on a single line. You cannot use "$" to continue the code onto the next line. If your code is too long to easily fit on a single line, use a string containing the code. You can then break the string across multiple lines.
Note: The actual names of the arguments do not matter, as long as they are valid IDL variable names, and they match the variable names within the expression. When the Lambda function is called, the input variables will be passed into your Lambda function in the same order as the call.
Note: If you call Lambda again with the identical Code string, then for efficiency a new Lambda routine will not be created. Instead, the existing Lambda routine will be returned. If for some reason you must have a new function, you should change the code string, for example by changing the names of the arguments.
Internally, LAMBDA calls the COMPILE_CODE routine to create a new function with the following form:
FUNCTION IDL$LAMBDAFxxx, arg1, arg2,...
COMPILE_OPT IDL2, hidden
The "xxx" is filled in with a unique number for each call to Lambda.
IDL then compiles the newly-created routine, and returns the name of the routine in the Result.
If you call Lambda again with the identical Code string, IDL first looks in its list to see if this routine already exists, and returns the same routine name. This makes it efficient to do nested Lambda calls and avoids the overhead of creating extra routines.
Note: Since Lambda functions are dynamically created at runtime, the routines are not saved within IDL SAVE files. To use the Lambda function in a future IDL session, you must re-run the code that creates the Lambda function.
Note: RESOLVE_ALL cannot resolve calls to LAMBDA functions, and will throw an error with the name of the "unresolved" variable. You should either set the SKIP_ROUTINES keyword to the name of your Lambda variable, or use CONTINUE_ON_ERROR to suppress the errors.
Nested Lambdas with Function Calls
Now, we use a nested Lambda function that creates other Lambda functions. Notice that we use a string containing the code, which allows us to dynamically convert the "n" argument to an actual value:
lexp = LAMBDA('n: LAMBDA("sum,x: sum + x^" + n.ToString())')
lam2 = lexp(2)
lam3 = lexp(3)
a = [1, 2, 3, 4, 5]
PRINT, a.Reduce(lam2), a.Reduce(lam3)
Using Lambda as a User-Defined Function
You can also pass the Lambda function into another IDL routine that expects a user-defined function. For example, we can use QROMB to integrate a cubic polynomial over a certain range:
result = QROMB(LAMBDA(x:x^3 + (x-1)^2 + 3), -4, 4)
We can also pass in this same Lambda function to the Plot's EQUATION property:
p = PLOT(Lambda(x:x^3 + (x-1)^2 + 3), $
XRANGE=[-4,4], /FILL_BACKGROUND, FILL_LEVEL=0)
t = TEXT(-2, 55, '$y = x^3 + (x-1)^2 + 3$', /DATA)
t = TEXT(-2, 40, 'Area = ' + result.ToString('(F5.2)'), /DATA)
COMPILE_CODE, LAMBDAP, Static Methods and Properties, Filter method, Map method, Reduce method