Module 4: Functions
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 examples to work along.
-- Module 4: Functions - Complete Examples
-- All examples are validated and use natural language identifiers
IMPORT prelude
-- =============================================================================
-- SECTION 1: Basic Functions
-- =============================================================================
-- Square a number
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the square of` MEANS n * n
-- Add two numbers together
GIVEN x IS A NUMBER
y IS A NUMBER
GIVETH A NUMBER
`the sum of` MEANS x + y
-- Check if a person is an adult
GIVEN age IS A NUMBER
GIVETH A BOOLEAN
DECIDE `the person is an adult` IF age >= 18
-- =============================================================================
-- SECTION 2: Using DECIDE IF vs MEANS
-- =============================================================================
-- These are equivalent ways to define a boolean function:
GIVEN age IS A NUMBER
GIVETH A BOOLEAN
`is adult (using MEANS)` MEANS age >= 18
GIVEN age IS A NUMBER
GIVETH A BOOLEAN
DECIDE `is adult (using DECIDE IF)` IF age >= 18
GIVEN age IS A NUMBER
GIVETH A BOOLEAN
DECIDE `is adult (using DECIDE IS)` IS age >= 18
-- =============================================================================
-- SECTION 3: Local Definitions with WHERE
-- =============================================================================
-- Compound interest calculation
GIVEN principal IS A NUMBER
rate IS A NUMBER
years IS A NUMBER
GIVETH A NUMBER
`the compound interest` MEANS
principal * (`power` factor years)
WHERE
factor MEANS 1 + rate
-- Simple power function (integer exponents only)
GIVEN base IS A NUMBER
exp IS A NUMBER
GIVETH A NUMBER
`power` MEANS
IF exp <= 0
THEN 1
ELSE base * (`power` base (exp - 1))
-- Monthly payment calculation (simplified)
GIVEN loan IS A NUMBER
annualRate IS A NUMBER
months IS A NUMBER
GIVETH A NUMBER
`the monthly payment` MEANS
loan * monthlyRate / (1 - discountFactor)
WHERE
monthlyRate MEANS annualRate / 12
discountFactor MEANS `power` (1 + monthlyRate) (0 - months)
GIVEN base IS A NUMBER
exp IS A NUMBER
GIVETH A NUMBER
`power` MEANS
IF exp <= 0
THEN 1 / (`positive power` base (0 - exp))
ELSE `positive power` base exp
GIVEN base IS A NUMBER
exp IS A NUMBER
GIVETH A NUMBER
`positive power` MEANS
IF exp <= 0
THEN 1
ELSE base * (`positive power` base (exp - 1))
-- =============================================================================
-- SECTION 4: Recursive Functions
-- =============================================================================
-- Factorial: n!
GIVEN n IS A NUMBER
GIVETH A NUMBER
`the factorial of` MEANS
IF n <= 1
THEN 1
ELSE n * (`the factorial of` (n - 1))
-- Sum a list of numbers (using 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
-- Count elements in a list
GIVEN xs IS A LIST OF NUMBER
GIVETH A NUMBER
`the length of` MEANS
CONSIDER xs
WHEN EMPTY THEN 0
WHEN x FOLLOWED BY rest THEN 1 + `the length of` rest
-- =============================================================================
-- SECTION 5: Higher-Order Functions
-- =============================================================================
-- Double each number in a list
GIVEN numbers IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`the doubled list` MEANS
map (GIVEN n YIELD n * 2) numbers
-- Get only positive numbers
GIVEN numbers IS A LIST OF NUMBER
GIVETH A LIST OF NUMBER
`the positive numbers in` MEANS
filter (GIVEN n YIELD n > 0) numbers
-- Check if all numbers satisfy a condition
GIVEN numbers IS A LIST OF NUMBER
threshold IS A NUMBER
GIVETH A BOOLEAN
DECIDE `all numbers are above threshold` IF
all (GIVEN n YIELD n > threshold) numbers
-- =============================================================================
-- SECTION 6: Test Data
-- =============================================================================
`test numbers` MEANS LIST 1, 2, 3, 4, 5
`mixed numbers` MEANS LIST -2, -1, 0, 1, 2, 3
-- =============================================================================
-- SECTION 7: Tests
-- =============================================================================
-- Basic function tests
#EVAL `the square of` 5
#EVAL `the sum of` 3 4
#EVAL `the person is an adult` 21
#EVAL `the person is an adult` 16
-- Equivalent definitions all return TRUE for age 25
#EVAL `is adult (using MEANS)` 25
#EVAL `is adult (using DECIDE IF)` 25
#EVAL `is adult (using DECIDE IS)` 25
-- WHERE clause tests
#EVAL `the compound interest` 1000 0.05 3
-- Recursive function tests
#EVAL `the factorial of` 5
#EVAL `the sum of the list` `test numbers`
#EVAL `the length of` `test numbers`
-- Higher-order function tests
#EVAL `the doubled list` `test numbers`
#EVAL `the positive numbers in` `mixed numbers`
#EVAL `all numbers are above threshold` `test numbers` 0
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 firstName IS A STRING
lastName IS A STRING
age IS A NUMBER
GIVETH A Person
`create person` MEANS Person firstName lastName age
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 `add` 3 5 -- Result: 8
Local Definitions with WHERE
Use WHERE to define helper values and functions:
GIVEN principal IS A NUMBER
rate IS A NUMBER
years IS A NUMBER
GIVETH A NUMBER
`the compound interest` MEANS
principal * (factor ^ years)
WHERE
factor MEANS 1 + rate
Multiple Local Definitions
`the monthly payment` MEANS
loan * (monthlyRate * compoundFactor) / (compoundFactor - 1)
WHERE
monthlyRate MEANS annualRate / 12
compoundFactor MEANS (1 + monthlyRate) ^ 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 xs IS A LIST OF NUMBER
GIVETH A NUMBER
`the sum of` MEANS
CONSIDER xs
WHEN EMPTY THEN 0
WHEN x FOLLOWED BY rest THEN x + `the sum of` 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
Exercises
Exercise 1: Simple Function
Write a function that calculates the area of a rectangle.
Exercise 2: Function with WHERE
Write a function that calculates the area of a circle using π ≈ 3.14159.
Exercise 3: Recursive Function
Write a recursive function to calculate the sum of a list of numbers.
Exercise 4: Higher-Order Function
Use filter to get all numbers greater than 10 from a list. (Remember to IMPORT prelude.)
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
`subtract` MEANS x - y
-- ❌ Wrong: Gets 3 - 10 = -7, not 10 - 3
#EVAL `subtract` 3 10
-- ✅ Right: Match the order in GIVEN
#EVAL `subtract` 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 localDef MEANS value |
| Recursion | Function calls itself in definition |
| Lambda | GIVEN x YIELD expression |
| Function application | functionName arg1 arg2 |
What's Next?
In Module 5: Regulative Rules, you'll learn how to model legal obligations, permissions, and prohibitions using L4's deontic constructs.