-
Notifications
You must be signed in to change notification settings - Fork 9
Functions
A LENS script can define custom functions using the fun
keyword. Here are a few examples:
fun report ->
println "{0}: everything is fine!" DateTime.Now
fun reportError (msg:string) ->
println "an error has been reported: {0}" msg
fun add:int (x:int y:int) -> x + y
fun distance:double (p1:Point p2:Point) ->
let x = p1.X - p2.X
let y = p1.Y - p2.Y
Math::Sqrt (x ** 2 + y ** 2)
A function must have a name and a body. If the whole body is a single expression, it can be written in a line. Function overloading is supported: several functions can have one and the same name as long as they have a different set of arguments.
Each function has its own namespace:
fun fx1 ->
var a = 1
print "fx1: a = {0}" a
fun fx2 ->
var a = "test"
print "fx2: a = {0}" a
var a = true
fx1 () // a = 1
fx2 () // a = test
print "script body: a = {0}" a // a = true
The return value of a function is its last expression. Control statements like if
, while
and for
also return a value when they are the last expression in the function body.
The type of the last expression must be compatible to the return type specified in the function declaration. If no return value is desired, a unit
literal can be used:
fun check (x:int y:int) ->
if x < y then print "less!"
() // unit literal means "no return"
If a function should modify several values from the calling site, they can be passed by reference using the ref
keyword:
fun replace (x:ref int y:ref int) ->
let tmp = x
x = y
y = tmp
var x = 1
var y = 2
replace (ref x) (ref y)
print "x = {0}, y = {1}" x y // x = 2, y = 1
There is no out
modifier in LENS, because there is no such thing as an uninitialized variable. If you need to call a method that has an out
argument, use the same good old ref
:
var oneStr = "1"
var oneNum : int
int::TryParse oneStr (ref oneNum)
print oneNum // 1
Please note that ref arguments cannot be closured. This limitation is imposed by the .NET framework itself.
Much like in C#, you can declare a function that accepts an arbitrary list of values. The ellipsis type modifier is used in the last argument:
fun count:int (data:object...) -> data.Length
count 1 2 3 // 3
count 5 4 3 2 true // 5
Please note that there is no explicit array specification on the argument type! T[]...
would be considered an array of arrays!
Memoization support is built-in in LENS. If you prefix a function with the pure
modifier, its return value will be cached. Next time you call the function with the same set of arguments, the previously calculated result will be yielded from the cache instead of invoking the function:
pure fun add:int (x:int y:int) ->
println "invoked"
x + y
add 1 1 // "invoked"
add 1 2 // "invoked"
add 1 2 // no output this time: value is cached
Please keep in mind that the pure
modifier does not make LENS check the function body for side effects.