Lambdas
A small procedure that is used in one place reads better written in that
place. A lambda is a procedure without a name, written as an expression:
function( parameters ) as Type ... end function, or sub( parameters ) ... end sub when nothing is returned.
'' A lambda is a procedure written as an expression, where it is used.
type Transform as function( byval x as int32 ) as int32
sub ApplyAll( values( ) as int32, byval f as Transform )
for i as int32 = lbound( values ) to ubound( values )
values( i ) = f( values( i ) )
next
end sub
'' Stored in a variable of a matching procedure type...
dim as Transform double_ = function( byval x as int32 ) as int32
return x * 2
end function
print double_( 21 )
'' ...or in a var, which takes its type from the lambda. A short body
'' fits on one line, with colons between the statements.
var cube = function( byval x as int32 ) as int32 : return x * x * x : _
end function
print cube( 3 )
'' ...or passed straight to the procedure that wants it.
dim as int32 readings( 0 to 3 ) = { 1, 2, 3, 4 }
ApplyAll( readings( ), function( byval x as int32 ) as int32
return x + 100
end function )
for each r in readings
print r;
next
print
'' A lambda with nothing to return is a sub.
var greet = sub( byref who as ustring )
print "hello, " & who
end sub
greet( "lambda" )
Output
42
27
101 102 103 104
hello, lambda
A lambda can go wherever an expression can:
- into a variable of a matching procedure pointer type, like
double_; - into a
var, which takes its type from the lambda, likecubeandgreet; - straight into an argument, like the one
ApplyAllreceives.
The body is ordinary statements. Because : separates statements, a short
body fits on one line, as cube's does. A lambda is called like any other
procedure: cube( 3 ).
A lambda that uses only its own parameters and locals is compiled to an
ordinary procedure, and its value is that procedure's address. That is why it
can be stored in a Transform variable and passed where a Transform is
wanted. A lambda that uses variables from the code around it is a
closure, which is a different kind of value.
Activities
- Pass
ApplyAlla lambda that replaces every value with its square. - Store a lambda that returns the larger of two
int32values in avar, and call it.