7Towards L4 Mastery

Functional programming for legal professionals

7.1 The Functional Mindset: "Think More in a Haskell Way"

Critical insight: L4 is fundamentally a functional programming language. Understanding this is essential for writing correct L4 code.

What does "functional" mean for lawyers?

  1. Functions over procedures: Instead of step-by-step instructions, you define what something IS

  2. Immutable data: Legal facts don't change—you create new states rather than modifying existing ones

  3. Composition: Complex legal rules are built by combining simpler ones

  4. Type safety: The computer prevents logical errors by checking that everything "fits together"

Example transformation from procedural to functional thinking:

❌ Procedural mindset:

-- "Step 1: Check if application complete"
-- "Step 2: Check if purposes charitable"
-- "Step 3: If both true, register charity"

✅ Functional mindset:

-- Define what completeness IS
GIVEN applicant IS A RegisterEntry
GIVETH A BOOLEAN
`application is complete` MEANS
    `constitution is written` applicant
    AND `has at least one purpose` applicant
    AND `has valid public benefit statement` applicant

-- Define what charitable purposes ARE
GIVEN charity IS A RegisterEntry
GIVETH A BOOLEAN
`all purposes are charitable` MEANS
    all (GIVEN p YIELD `is charitable purpose` p) (charity's purposes)

-- Define registration criteria using the above
GIVEN applicant IS A RegisterEntry
GIVETH A BOOLEAN
`should register` MEANS
    `application is complete` applicant
    AND `all purposes are charitable` applicant

Why this matters: Legal reasoning is naturally functional—we define criteria and apply them, rather than executing procedures.

7.2 Function Application Precedence - The Critical Pattern

The most important syntax rule in L4: Function application has higher precedence than field access.

This causes systematic errors that look like this:

Problem examples and solutions:

❌ Wrong - Parser confusion:

✅ Correct - Use parentheses:

The pattern: When passing field access as function arguments, always wrap in parentheses.

Why this happens:

  • L4 follows Haskell-like precedence: function application > field access > comparison > boolean operators

  • length applicant's purposes is parsed as (length applicant)'s purposes

  • The parser expects length to be applied to applicant, then tries to access purposes field of the result

  • But applicant is not a list, so length applicant is a type error, and the parser gets confused

7.3 Field Access Patterns - Possessive vs Functional

L4 supports both possessive syntax and function application for field access.

When possessive syntax works:

When you MUST use function application:

Convert possessive to functional:

  • object's fieldfield object

  • object's field1's field2field2 (field1 object)

For deeply nested access:

7.4 List Operations and Quantifiers

Key insight: Use prelude functions instead of inventing syntax.

❌ Non-existent syntax:

✅ Use prelude functions:

Pattern for quantified conditions:

7.5 Type Safety and Missing Functions

Problem: L4's prelude is minimal—common functions may be missing.

Systematic approach:

  1. Check if function exists in prelude (like length, elem, filter)

  2. Define missing functions at the top of your file

  3. Use proper types (don't mix STRING and LIST operations)

Essential missing functions to define:

Type checking patterns:

7.6 Boolean Logic and Comparison Patterns

Prefer direct comparisons over negation:

❌ Unnecessarily complex:

✅ Cleaner and clearer:

Comparison precedence patterns:

Boolean combination patterns:

7.7 Systematic Debugging Approach

When you see syntax errors, follow this checklist:

  1. Function precedence: Are field accesses in function arguments wrapped in parentheses?

  2. Missing functions: Is the function defined in prelude or your file?

  3. Type mismatches: Are you using STRING operations on LISTs or vice versa?

  4. Possessive syntax: Can you convert to function application form?

  5. Boolean logic: Are comparisons and boolean operations correctly parenthesized?

Error patterns and fixes:

Success Check: You now understand L4's functional nature, can handle precedence correctly, use proper quantifiers, and systematically debug type and syntax errors.

Last updated