Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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, like cube and greet;
  • straight into an argument, like the one ApplyAll receives.

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

  1. Pass ApplyAll a lambda that replaces every value with its square.
  2. Store a lambda that returns the larger of two int32 values in a var, and call it.