Functions¶
Functions allow you to group logic into reusable blocks.
They help organize code, avoid repetition, and make programs easier to understand.
In EasyLang, functions are written using clear English-like syntax and support:
- arguments (parameters)
- return values
- nesting (functions inside functions)
- access to outer scopes (lexical scoping)
- method-style invocation
- module-level functions
This chapter explains how to define, call, and use functions effectively.
Function Definition¶
Functions are defined using:
define <name>(arg1, arg2, ...): do [
statements...
]
Example¶
define add(a, b): do [
return a plus b
]
Structure Breakdown¶
define— starts a function definition<name>— the function’s name(a, b)— comma-separated argument list (optional): do— marks the start of the function body[ ... ]— contains the function’s statements
Calling a Function¶
To call a function:
add(10, 20)
Example with printing:
so print add(3, 5)
Function calls can appear anywhere an expression is allowed:
we let x = add(10, mul(2, 3))
Return Values¶
Functions return values using:
return <expression>
Example:
define greet(name): do [
return "Hello, " plus name
]
so print greet("GreenBugX")
Missing return¶
If no return statement is used, the function returns null (Python None).
Function Arguments¶
Arguments work like normal variables inside the function:
define area(width, height): do [
return width mul height
]
Arguments follow the same variable rules:
- must be valid identifiers
- cannot use keywords
- are local to the function
Nested Functions¶
Functions may be defined inside other functions.
Example:
define outer(): do [
we let x = 5
define inner(): do [
so print x
]
inner()
]
This prints:
5
Because EasyLang supports lexical scoping — inner functions can see outer variables.
Functions and Scope¶
Inside a function:
- arguments belong to the local scope
- variables defined inside the function remain local
- outer scope variables can be read
- but cannot be reassigned (shadowing creates new locals)
Example:
we let x = 10
define test(): do [
we let x = 5 $ shadows global x
so print x
]
test()
so print x
Output:
5
10
Functions as Values¶
Functions are first-class citizens in EasyLang. You can store them in variables:
we let f = add
so print f(2, 3)
Or pass them around:
define apply(fn, x, y): do [
return fn(x, y)
]
so print apply(add, 3, 7)
Method-Style Calls¶
EasyLang supports:
object.method(args...)
Examples:
nums.push(5)
text.upper()
user.name.strip()
In these cases:
objectbecomes the implicit first argument- the interpreter passes the object into the method call
This works for:
- list methods
- dictionary access
- module functions
- Python module wrappers
- built-in string/list utilities
Functions in Modules¶
When you bring a module:
bring "math.elangh" as math
All functions defined in that module become accessible via:
math.function()
Example:
so print math.sqrt(25)
Modules may contain:
- EasyLang functions
- Python-wrapped functions
- variables
- dictionaries
- lists
Error Handling in Functions¶
If something goes wrong inside a function, EasyLang reports:
- the error type
- the file and line
- the exact code snippet
Example error:
RuntimeError: Undefined variable 'a'
3| return a plus b
^
This is powered by the interpreter’s pretty_error() system.
Examples¶
- Simple return
define double(n): do [ return n mul 2 ] -
Using functions in expressions
we let result = double(5) plus 10 so print result -
Function that prints
define hello(): do [ so print "Hello!" ] hello() -
Nested function usage
define outer(): do [ we let x = 10 define inner(): do [ return x mul 2 ] return inner() ] so print outer()
Summary¶
In EasyLang, functions provide:
- reusable logic
- arguments and returns
- local scope
- nesting
- method-style calls
- integration with modules
- interoperability with Python functions
Functions are a powerful building block of the language and essential for structuring any non-trivial EasyLang program.
Next Steps¶
Continue to Modules to learn how Modules work in detail