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 number
  • GIVETH A STRING — Returns a string
  • GIVETH A BOOLEAN — Returns true/false
  • GIVETH A Person — Returns a Person record
  • GIVETH A LIST OF NUMBER — Returns a list of numbers
  • GIVETH 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.