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



```l4-file
-- 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:

```l4
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:

```l4
-- 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:

```l4
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:

```l4
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

```l4
-- 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

```l4
-- Arguments separated by spaces
#EVAL `add` 3 5       -- Result: 8
```

---

## Local Definitions with WHERE

Use `WHERE` to define helper values and functions:

```l4
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

```l4
`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

```l4
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

```l4
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`:

```l4
-- 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

```l4
-- ❌ 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

```l4
-- 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

```l4
-- ❌ 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](/l4/courses/foundation/module-5-regulative.md), you'll learn how to model legal obligations, permissions, and prohibitions using L4's deontic constructs.
