Functions
L4 programs use functions to express definitions and decisions.
Expressing Definitions with MEANS
Expressions can be written in a straightforward manner:
x MEANS 2 + 2
y MEANS x * x
This defines x
to be 4
and y
(using the definition of x
) to be 16
. Note that x
and y
are constants. Their value does never change.
Identifiers cannot be used if they are not defined, but the definition may occur after their first use:
p MEANS q
q MEANS TRUE
In this case, both p
and q
are TRUE
.
Decision Function Example with GIVEN, GIVETH, DECIDE/IS, MEANS
Perhaps we have three kinds of fruit in our grocery bag, and some more already in a bowl on the table.
How many fruit do we have in total?
GIVEN apples IS A `count of fruit in my bag`
bananas IS A `count of fruit in my bag`
oranges IS A `count of fruit in my bag`
`in the bowl` IS A NUMBER
DECIDE `total fruit` IS
apples + bananas + oranges + `in the bowl`
Decision functions rely purely on the inputs that are given, and on values that are available in the environment's scope.
You can see this example in the file fruit.l4.
The GIVEN
keywords indicate the types of the input parameters.
The GIVETH
keyword indicates the return type of the function. It is optional; it will be inferred when omitted.
The name of the function comes between DECIDE
and IS
. Boolean functions read more naturally when you use the word IF
instead of IS
.
MEANS
== DECIDE ... IS/IF
MEANS
== DECIDE ... IS/IF
These forms are equivalent:
DECIDE `total fruit` IS ...
`total fruit` MEANS ...
Constant Values
Constant values are simply functions which aren't given any arguments.
`pi` MEANS 3.1415926
`bananas per bunch` MEANS 5
Maybe the bananas were counted by the bunch. To get the actual number of bananas, we need to multiply by 5.
`total fruit` MEANS
apples
+ bananas * `bananas per bunch`
+ oranges
+ `in the bowl`
In real-world L4, you will see that the definitions section of a legal text shows up as a long sequence of MEANS
statements.
WHERE syntax
The fact that bananas come five to a bunch may not be relevant anywhere outside this fruit-counting function.
We can relegate it to a coda at the end of the function definition:
`total fruit` MEANS
apples
+ bananas * `bananas per bunch`
+ oranges
+ `in the bowl`
WHERE `bananas per bunch` MEANS 5
This is a common pattern.
Conditional Expressions
Conditionals are written using the IF
, THEN
, and ELSE
keywords.
Some programmers may be familiar with the punctuated form: if ? then : else
.
GIVEN n IS A NUMBER
GIVETH A NUMBER
factorial n MEANS
IF n EQUALS 0
THEN 1
ELSE n * factorial (n - 1)
Open <tutorial-code/factorial.l4> in VS Code and mouse-over the #EVAL
line.
IDE feature: Inline EVAL
This is a quick way to test expressions.
In the VS Code IDE with L4 extensions enabled, if you write
#EVAL `numbers are big` 1 2
#EVAL `numbers are big` 1000 1000
#EVAL `numbers are big` 1000 1001
#EVAL `numbers are big` 1001 1000
#EVAL `numbers are big` 1001 1001
#EVAL `numbers are big` 10001 0
#EVAL `numbers are big` 0 20001
You can mouseover the expressions and see the result of evaluation:
False
False
False
False
True
True
True
Example: Fibonacci Function
§ `Fibonacci function`
GIVEN n IS A NUMBER
GIVETH A NUMBER
DECIDE fibNaive n IS
IF n EQUALS 0
THEN 0
ELSE IF n EQUALS 1
THEN 1
ELSE fibNaive (n - 1) + fibNaive (n - 2)
#EVAL fibNaive 20
#EVAL and #CHECK
Besides the inline #EVAL
discussed above, the L4 IDE plugin also supports the #CHECK
directive. This shows typechecking.
Last updated