Functional Patterns
THT has some basic capabilities for functional programming-style patterns.
List Methods
The List type has functional methods — those that take an anonymous function (i.e. closure) as an argument.
Anonymous Functions
An anonymous function is a standalone (nameless) function that can be assigned to a variable.
It can then be passed as an argument into other functions.
This enables “higher order programming”, where you dynamically specify how an operation should work.
// A function that tests if a number is even $fnIsEven = fn ($num) { return $num % 2 == 0 } $numbers = [1, 2, 3, 4, 5, 6, 7, 8] $numbers.filter($fnIsEven) //= [2, 4, 6, 8]
You can directly call a function that is assigned to a variable.
$fnIsEven(10) //= true
Closures
When an anonymous function is declared, it holds onto all variables from the outer scope.
The outer variables can then be accessed by the inner function when it is later called.
This binding of a function with its outer scope is called a “closure”.
// Return a new logging function for // the given message type fn createLogger($messageType) { $fnLog = fn ($message) { print($messageType ~ ' -> ' ~ $message) // ^----------- (from outer scope) } return $fnLog } $fnLogUserEvent = createLogger('user') $fnLogUserEvent('logged in') //= 'user -> logged in' $fnLogSystemEvent = createLogger('system') $fnLogSystemEvent('shut down') //= 'system -> shut down'
Expression Functions
Use the x{...}
shortcut to create an anonymous function that automatically returns a single expression.
Expression functions automatically define arguments $a
, $b
, and $c
for the 1st, 2nd, and 3rd arguments, respectively.
x{ $a * 10 } // is the same as... fn ($a) { return $a * 10 }
Example uses:
[1, 2, 3].map(x{ $a * 10 }) //= [10, 20, 30] // reverse sort $users.sort(x{ $b <=> $a })