Module 5: Functions
Prerequisites: Modules 1–4
In this module, you'll learn how to define reusable functions in L4.
Learning Objectives
By the end of this module, you will be able to:
- Define functions with GIVEN and GIVETH
- Use DECIDE and MEANS appropriately
- Create local definitions with WHERE
- Write recursive functions
- Understand function application
Function Basics
This is the complete working example to work along.
-- Module 5: Functions - Complete Examples
-- All examples are validated and use natural language identifiers
IMPORT prelude
-- =============================================================================
-- SECTION 1: Function Basics
-- =============================================================================
-- A function with two parameters and a NUMBER result
GIVEN x IS A NUMBER
y IS A NUMBER
GIVETH A NUMBER
`the sum of x and y` MEANS
x + y
-- A function with one parameter
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the square of` MEANS n * n
-- Argument order matters
GIVEN x IS A NUMBER
y IS A NUMBER
GIVETH A NUMBER
`the difference of` MEANS x - y
-- DECIDE IF for boolean predicates
GIVEN `the person's age` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `the person is an adult` IF `the person's age` >= 18
-- =============================================================================
-- SECTION 2: Polymorphic Functions
-- =============================================================================
-- Works with values of any type
GIVEN a IS A TYPE
x IS AN a
y IS AN a
GIVETH AN a
`the first of` MEANS x
-- =============================================================================
-- SECTION 3: Local Definitions with WHERE
-- =============================================================================
-- Compound interest with a named helper
GIVEN `the principal` IS A NUMBER
`the annual rate` IS A NUMBER
`the years` IS A NUMBER
GIVETH A NUMBER
`the compound interest` MEANS
`the principal` * EXPONENT `the growth factor` `the years`
WHERE
`the growth factor` MEANS 1 + `the annual rate`
-- Loan payment with several helpers
GIVEN `the loan amount` IS A NUMBER
`the annual rate` IS A NUMBER
`the term in months` IS A NUMBER
GIVETH A NUMBER
`the monthly payment` MEANS
`the loan amount` *
(`the monthly rate` * `the compound factor`) /
(`the compound factor` - 1)
WHERE
`the monthly rate` MEANS `the annual rate` / 12
`the compound factor` MEANS EXPONENT (1 + `the monthly rate`) `the term in months`
-- =============================================================================
-- SECTION 4: Recursive Functions
-- =============================================================================
-- Simple recursion
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the factorial of` MEANS
IF n <= 1
THEN 1
ELSE n * `the factorial of` (n - 1)
-- List recursion with CONSIDER
GIVEN numbers IS A LIST OF NUMBER
GIVETH A NUMBER
`the sum of the list` MEANS
CONSIDER numbers
WHEN EMPTY THEN 0
WHEN x FOLLOWED BY rest THEN x + `the sum of the list` rest
-- =============================================================================
-- SECTION 5: Higher-Order Functions
-- =============================================================================
-- Transform every element with map
GIVEN numbers IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`the doubled numbers` MEANS
map (GIVEN n YIELD n * 2) numbers
-- Keep matching elements with filter
GIVEN numbers IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`the positive numbers` MEANS
filter (GIVEN n YIELD n > 0) numbers
-- Combine a whole list into one value with foldl
GIVEN numbers IS A LIST OF NUMBER
GIVETH A NUMBER
`the total of` MEANS
foldl (GIVEN acc, n YIELD acc + n) 0 numbers
-- =============================================================================
-- SECTION 6: Tests
-- =============================================================================
-- Function basics
#EVAL `the sum of x and y` 3 5
#EVAL `the square of` 5
#EVAL `the square of` (3 + 2)
#EVAL `the difference of` 10 3
#EVAL `the person is an adult` 21
-- Polymorphic functions
#EVAL `the first of` 1 2
#EVAL `the first of` "yes" "no"
-- WHERE
#EVAL `the compound interest` 1000 0.05 10
#EVAL `the monthly payment` 300000 0.06 360
-- Recursion
#EVAL `the factorial of` 5
#EVAL `the sum of the list` (LIST 1, 2, 3, 4, 5)
-- Higher-order functions
#EVAL `the doubled numbers` (LIST 1, 2, 3)
#EVAL `the positive numbers` (LIST -1, 2, -3, 4)
#EVAL `the total of` (LIST 1, 2, 3, 4, 5)
The Structure of a Function
Every L4 function has these parts:
GIVEN x IS A NUMBER -- Parameters (inputs)
y IS A NUMBER
GIVETH A NUMBER -- Return type (output)
`the sum of x and y` MEANS -- Name and definition
x + y
DECIDE vs MEANS
Both define the same thing—use whichever reads better:
-- These are equivalent
DECIDE `the person is an adult` IF age >= 18
`the person is an adult` MEANS age >= 18
DECIDE `the person is an adult` IS age >= 18
| Syntax | Best for |
|---|---|
DECIDE name IS expr |
Rules, decisions, conditions |
DECIDE name IF expr |
Boolean predicates |
name MEANS expr |
Definitions, computations |
Type Signatures
The GIVETH clause declares what type the function returns:
GIVETH A NUMBER— Returns a numberGIVETH A STRING— Returns a stringGIVETH A BOOLEAN— Returns true/falseGIVETH A Person— Returns a Person recordGIVETH A LIST OF NUMBER— Returns a list of numbersGIVETH A MAYBE NUMBER— Returns a number or nothing
Function Parameters
Multiple Parameters
List parameters with GIVEN, separated by newlines or commas:
GIVEN x IS A NUMBER
y IS A NUMBER
GIVETH A NUMBER
`the difference of` MEANS x - y
The order of the parameters is the order in which callers supply arguments.
Polymorphic Functions
Use TYPE for functions that work with any type:
GIVEN a IS A TYPE
x IS AN a
y IS AN a
GIVETH AN a
`the first of` MEANS x
Calling Functions
Simple Function Calls
-- Define a function
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the square of` MEANS n * n
-- Call it
#EVAL `the square of` 5 -- Result: 25
#EVAL `the square of` (3 + 2) -- Result: 25
Multi-Argument Calls
-- Arguments separated by spaces
#EVAL `the sum of x and y` 3 5 -- Result: 8
Local Definitions with WHERE
Use WHERE to define helper values and functions. (EXPONENT base power is L4's built-in exponentiation function.)
GIVEN `the principal` IS A NUMBER
`the annual rate` IS A NUMBER
`the years` IS A NUMBER
GIVETH A NUMBER
`the compound interest` MEANS
`the principal` * EXPONENT `the growth factor` `the years`
WHERE
`the growth factor` MEANS 1 + `the annual rate`
Multiple Local Definitions
GIVEN `the loan amount` IS A NUMBER
`the annual rate` IS A NUMBER
`the term in months` IS A NUMBER
GIVETH A NUMBER
`the monthly payment` MEANS
`the loan amount` *
(`the monthly rate` * `the compound factor`) /
(`the compound factor` - 1)
WHERE
`the monthly rate` MEANS `the annual rate` / 12
`the compound factor` MEANS EXPONENT (1 + `the monthly rate`) `the term in months`
Recursive Functions
L4 supports recursion—functions that call themselves:
Simple Recursion
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the factorial of` MEANS
IF n <= 1
THEN 1
ELSE n * `the factorial of` (n - 1)
#EVAL `the factorial of` 5 -- Result: 120
List Recursion
GIVEN numbers IS A LIST OF NUMBER
GIVETH A NUMBER
`the sum of the list` MEANS
CONSIDER numbers
WHEN EMPTY THEN 0
WHEN x FOLLOWED BY rest THEN x + `the sum of the list` rest
#EVAL `the sum of the list` (LIST 1, 2, 3, 4, 5) -- Result: 15
The CONSIDER walks the list: an empty list sums to 0; otherwise add the first element to the sum of the rest.
Higher-Order Functions
Functions that take or return other functions.
Note: You must IMPORT prelude to use map, filter, all, any, etc.
Anonymous Functions (Lambdas)
Use GIVEN ... YIELD:
-- Double each number
map (GIVEN n YIELD n * 2) (LIST 1, 2, 3)
-- Result: LIST 2, 4, 6
-- Filter positive numbers
filter (GIVEN n YIELD n > 0) (LIST -1, 2, -3, 4)
-- Result: LIST 2, 4
Multi-parameter lambdas separate their parameters with commas: GIVEN acc, n YIELD acc + n.
Folding a List into One Value
foldl combines a whole list into a single result, starting from an initial value:
GIVEN numbers IS A LIST OF NUMBER
GIVETH A NUMBER
`the total of` MEANS
foldl (GIVEN acc, n YIELD acc + n) 0 numbers
#EVAL `the total of` (LIST 1, 2, 3, 4, 5) -- Result: 15
Use foldl (fold from the left) or foldr (fold from the right) from the prelude.
Exercises
Exercise 1: Simple Function
Write a function that calculates the area of a rectangle.
Solution
GIVEN `the width` IS A NUMBER
`the height` IS A NUMBER
GIVETH A NUMBER
`the area of the rectangle` MEANS
`the width` * `the height`
#EVAL `the area of the rectangle` 4 5
Exercise 2: Function with WHERE
Write a function that calculates the area of a circle using π ≈ 3.14159.
Solution
GIVEN `the radius` IS A NUMBER
GIVETH A NUMBER
`the area of the circle` MEANS
pi * `the radius` * `the radius`
WHERE
pi MEANS 3.14159
#EVAL `the area of the circle` 10
Exercise 3: Recursive Function
Write a recursive function to calculate the sum of a list of numbers.
Solution
GIVEN numbers IS A LIST OF NUMBER
GIVETH A NUMBER
`the sum of the list` MEANS
CONSIDER numbers
WHEN EMPTY THEN 0
WHEN x FOLLOWED BY rest THEN x + `the sum of the list` rest
#EVAL `the sum of the list` (LIST 1, 2, 3, 4, 5)
Exercise 4: Higher-Order Function
Use filter to get all numbers greater than 10 from a list. (Remember to IMPORT prelude.)
Solution
IMPORT prelude
GIVEN numbers IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`the numbers above ten` MEANS
filter (GIVEN n YIELD n > 10) numbers
#EVAL `the numbers above ten` (LIST 5, 15, 8, 22, 10)
Common Mistakes
1. Missing Return Type
-- ❌ Wrong: No GIVETH
GIVEN n IS A NUMBER
`the square of` MEANS n * n
-- ✅ Right: Include GIVETH
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the square of` MEANS n * n
2. Wrong Argument Order in Calls
-- Definition
GIVEN x IS A NUMBER
y IS A NUMBER
GIVETH A NUMBER
`the difference of` MEANS x - y
-- ❌ Wrong: Gets 3 - 10 = -7, not 10 - 3
#EVAL `the difference of` 3 10
-- ✅ Right: Match the order in GIVEN
#EVAL `the difference of` 10 3 -- Gets 10 - 3 = 7
3. Missing Parentheses in Function Calls
-- ❌ Wrong: f applied to g, not to result of g x
f g x
-- ✅ Right: Apply g to x, then f to result
f (g x)
Summary
| Concept | Syntax |
|---|---|
| Function definition | GIVEN params GIVETH Type name MEANS expr |
| Decision function | DECIDE name IF condition |
| Local definitions | expr WHERE helper MEANS value |
| Recursion | Function calls itself in definition |
| Lambda | GIVEN x YIELD expression |
| Multi-param lambda | GIVEN acc, x YIELD expression |
| Fold | foldl (GIVEN acc, x YIELD ...) start xs |
| Function application | `function name` arg1 arg2 |
What's Next?
In Module 6: Regulative Rules, you'll learn how to model legal obligations, permissions, and prohibitions using L4's deontic constructs.