Towards 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?
Functions over procedures: Instead of step-by-step instructions, you define what something IS
Immutable data: Legal facts don't change—you create new states rather than modifying existing ones
Composition: Complex legal rules are built by combining simpler ones
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` applicantWhy 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 operatorslength applicant's purposesis parsed as(length applicant)'s purposesThe parser expects
lengthto be applied toapplicant, then tries to accesspurposesfield of the resultBut
applicantis not a list, solength applicantis 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 field→field objectobject's field1's field2→field2 (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:
Check if function exists in prelude (like
length,elem,filter)Define missing functions at the top of your file
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:
Function precedence: Are field accesses in function arguments wrapped in parentheses?
Missing functions: Is the function defined in prelude or your file?
Type mismatches: Are you using STRING operations on LISTs or vice versa?
Possessive syntax: Can you convert to function application form?
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
