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 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 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.