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: Decision Logic - Complete Examples
-- All examples are validated and use natural language identifiers
IMPORT prelude
-- =======================================
-- SECTION 1: Basic Eligibility Decisions
-- =======================================
-- Simple age-based eligibility
GIVEN `the person's age` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `the person is an adult` IF `the person's age` >= 18
-- Voting eligibility
GIVEN `the person's age` IS A NUMBER
`is citizen` IS A BOOLEAN
GIVETH A BOOLEAN
DECIDE `the person is eligible to vote` IF
`the person's age` >= 18
AND `is citizen`
-- Senior discount qualification
GIVEN `the customer's age` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `qualifies for senior discount` IF
`the customer's age` >= 65
-- Student status determination
GIVEN `the person's age` IS A NUMBER
`is enrolled` IS A BOOLEAN
GIVETH A BOOLEAN
DECIDE `the person is a student` IF
`the person's age` >= 16
AND `the person's age` <= 25
AND `is enrolled`
-- =======================================
-- SECTION 2: Using DECIDE IF vs DECIDE IS vs MEANS
-- =======================================
-- DECIDE IF: Best for yes/no questions with conditions
GIVEN `the income` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `qualifies for exemption` IF `the income` < 10000
-- DECIDE IS: Best for classification or value assignment
GIVEN `the income` IS A NUMBER
GIVETH A STRING
DECIDE `the tax bracket` IS
BRANCH
IF `the income` < 10000 THEN "exempt"
IF `the income` < 50000 THEN "standard"
OTHERWISE "higher rate"
-- MEANS: Best for computations and definitions
GIVEN `the income` IS A NUMBER
GIVETH A STRING
`the income category` MEANS
BRANCH
IF `the income` < 20000 THEN "low"
IF `the income` < 80000 THEN "medium"
OTHERWISE "high"
-- =======================================
-- SECTION 3: Tax and Financial Calculations with WHERE
-- =======================================
-- Simple tax calculation
GIVEN `the gross income` IS A NUMBER
`the tax rate` IS A NUMBER
GIVETH A NUMBER
`the tax owed` MEANS
`the taxable income` * `the tax rate`
WHERE
`the standard deduction` MEANS 12000
`the taxable income` MEANS
IF `the gross income` > `the standard deduction`
THEN `the gross income` - `the standard deduction`
ELSE 0
-- Progressive tax with multiple brackets
GIVEN `the income` IS A NUMBER
GIVETH A NUMBER
`the income tax owed` MEANS
`tax on first bracket` + `tax on second bracket` + `tax on third bracket`
WHERE
`tax on first bracket` MEANS
`amount in first bracket` * 0.10
`tax on second bracket` MEANS
`amount in second bracket` * 0.20
`tax on third bracket` MEANS
`amount in third bracket` * 0.30
`amount in first bracket` MEANS
BRANCH
IF `the income` <= 10000 THEN `the income`
OTHERWISE 10000
`amount in second bracket` MEANS
BRANCH
IF `the income` <= 10000 THEN 0
IF `the income` <= 50000 THEN `the income` - 10000
OTHERWISE 40000
`amount in third bracket` MEANS
BRANCH
IF `the income` <= 50000 THEN 0
OTHERWISE `the income` - 50000
-- Net income calculation
GIVEN `the gross income` IS A NUMBER
`the expenses` IS A NUMBER
GIVETH A NUMBER
`the net income` MEANS
`the gross income` - `the total deductions`
WHERE
`the standard deduction` MEANS
IF `calculated deduction` >= 1000
THEN `calculated deduction`
ELSE 1000
`calculated deduction` MEANS `the gross income` * 0.10
`the total deductions` MEANS
`the standard deduction` + `the expenses`
-- =======================================
-- SECTION 4: Structured Entity Examples
-- =======================================
DECLARE Person HAS
name IS A STRING
age IS A NUMBER
citizenship IS A STRING
`annual income` IS A NUMBER
`criminal record` IS A BOOLEAN
-- Comprehensive benefit eligibility
GIVEN `the applicant` IS A Person
GIVETH A BOOLEAN
DECIDE `the applicant is eligible for benefit` IF
`the applicant is a qualifying resident`
AND `the applicant is of age`
AND `the applicant meets income threshold`
AND NOT `the applicant is disqualified`
WHERE
`the applicant is a qualifying resident` MEANS
`the applicant`'s citizenship = "citizen"
`the applicant is of age` MEANS
`the applicant`'s age >= 21
AND `the applicant`'s age < 65
`the applicant meets income threshold` MEANS
`the applicant`'s `annual income` < 30000
`the applicant is disqualified` MEANS
`the applicant`'s `criminal record`
-- Tax bracket determination with record
GIVEN `the taxpayer` IS A Person
GIVETH A STRING
DECIDE `the taxpayer's bracket` IS
BRANCH
IF `the taxpayer`'s `annual income` < 10000 THEN "exempt"
IF `the taxpayer`'s `annual income` < 50000 THEN "standard"
IF `the taxpayer`'s `annual income` < 100000 THEN "higher"
OTHERWISE "top rate"
-- =======================================
-- SECTION 5: Multi-Factor Decisions
-- =======================================
-- Loan approval decision
GIVEN `the income` IS A NUMBER
`the credit score` IS A NUMBER
`the loan amount` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `the loan is approved` IF
`income requirement is met`
AND `credit score is sufficient`
AND `debt to income ratio is acceptable`
WHERE
`income requirement is met` MEANS
`the income` >= `the loan amount` * 0.3
`credit score is sufficient` MEANS
`the credit score` >= 650
`debt to income ratio is acceptable` MEANS
`the loan amount` <= `the income` * 4
-- Insurance premium calculation
GIVEN `the insured age` IS A NUMBER
`the coverage amount` IS A NUMBER
`is smoker` IS A BOOLEAN
GIVETH A NUMBER
`the annual premium` MEANS
`the base premium` * `the age factor` * `the smoking factor`
WHERE
`the base premium` MEANS
`the coverage amount` * 0.001
`the age factor` MEANS
BRANCH
IF `the insured age` < 30 THEN 1.0
IF `the insured age` < 50 THEN 1.5
OTHERWISE 2.0
`the smoking factor` MEANS
IF `is smoker` THEN 1.5 ELSE 1.0
-- =======================================
-- SECTION 6: Real-World Contract Scenarios
-- =======================================
-- Late payment penalty calculation
GIVEN `the principal amount` IS A NUMBER
`days overdue` IS A NUMBER
GIVETH A NUMBER
`the late payment penalty` MEANS
BRANCH
IF `days overdue` <= 0 THEN 0
IF `days overdue` <= 30 THEN `the principal amount` * 0.02
OTHERWISE `the principal amount` * 0.05
-- Lease renewal qualification
GIVEN `years as tenant` IS A NUMBER
`late payments` IS A NUMBER
`current rent` IS A NUMBER
`market rent` IS A NUMBER
GIVETH A BOOLEAN
DECIDE `qualifies for lease renewal` IF
`tenant is in good standing`
AND `rent is at market rate`
WHERE
`tenant is in good standing` MEANS
`years as tenant` >= 1
AND `late payments` = 0
`rent is at market rate` MEANS
`current rent` >= `market rent` * 0.9
-- =======================================
-- SECTION 7: Test Data
-- =======================================
`test person eligible` MEANS
Person "Alice" 25 "citizen" 25000 FALSE
`test person ineligible age` MEANS
Person "Bob" 17 "citizen" 20000 FALSE
`test person ineligible citizenship` MEANS
Person "Carol" 30 "permanent resident" 20000 FALSE
`test person ineligible income` MEANS
Person "David" 30 "citizen" 50000 FALSE
`test person disqualified` MEANS
Person "Eve" 30 "citizen" 20000 TRUE
-- =======================================
-- SECTION 8: Tests
-- =======================================
-- Basic eligibility tests
#EVAL `the person is an adult` 21
#EVAL `the person is an adult` 16
#EVAL `the person is eligible to vote` 25 TRUE
#EVAL `the person is eligible to vote` 16 TRUE
#EVAL `qualifies for senior discount` 70
#EVAL `qualifies for senior discount` 50
-- Tax calculation tests
#EVAL `the tax owed` 50000 0.20
#EVAL `the income tax owed` 75000
#EVAL `the net income` 100000 15000
-- Structured entity tests
#EVAL `the applicant is eligible for benefit` `test person eligible`
#EVAL `the applicant is eligible for benefit` `test person ineligible age`
#EVAL `the applicant is eligible for benefit` `test person ineligible citizenship`
#EVAL `the applicant is eligible for benefit` `test person ineligible income`
#EVAL `the applicant is eligible for benefit` `test person disqualified`
#EVAL `the taxpayer's bracket` `test person eligible`
-- Multi-factor decision tests
#EVAL `the loan is approved` 60000 700 200000
#EVAL `the loan is approved` 40000 700 200000
#EVAL `the annual premium` 35 100000 FALSE
#EVAL `the annual premium` 35 100000 TRUE
-- Contract scenario tests
#EVAL `the late payment penalty` 1000 15
#EVAL `the late payment penalty` 1000 45
#EVAL `qualifies for lease renewal` 2 0 1800 2000
#EVAL `qualifies for lease renewal` 2 3 1800 2000
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.