No Explicit Return Statements
What are Implicit Returns?
Functions automatically return the last evaluated expression without needing an explicit return
statement.
/* Functions return the last expression automatically */
add : x y -> x + y; /* Automatically returns x + y */
double : x -> x * 2; /* Automatically returns x * 2 */
Why is This Esoteric?
Most programming languages require explicit return
statements. Our language makes them implicit - the last expression is automatically returned.
Basic Examples
/* Simple functions with implicit returns */
add : x y -> x + y;
result : add 5 3; /* 8 */
/* Single expression functions */
double : x -> x * 2;
increment : x -> x + 1;
square : x -> x * x;
/* All automatically return their last expression */
result1 : double 5; /* 10 */
result2 : increment 5; /* 6 */
result3 : square 5; /* 25 */
Complex Functions
Even complex functions with multiple expressions return the last one:
/* Function with multiple expressions */
complex_function : x ->
doubled : x * 2;
incremented : doubled + 1;
squared : incremented * incremented;
squared; /* This is what gets returned */
result : complex_function 3;
/* Step 1: doubled = 3 * 2 = 6 */
/* Step 2: incremented = 6 + 1 = 7 */
/* Step 3: squared = 7 * 7 = 49 */
/* Result: 49 */
Conditional Returns
Functions with conditional logic return the last expression in the executed branch:
/* Function with conditional logic */
classify_number : x ->
when x is
0 then "zero"
when x % 2 = 0 then "even"
when x % 2 = 1 then "odd"
_ then "unknown";
/* Each branch returns its last expression */
result1 : classify_number 0; /* "zero" */
result2 : classify_number 4; /* "even" */
result3 : classify_number 7; /* "odd" */
Nested Functions
Nested functions also use implicit returns:
/* Nested function definitions */
outer_function : x ->
inner_function : y -> y * 2;
inner_function x;
/* The nested function returns its last expression */
result : outer_function 5; /* 10 */
Table Operations
Table operations return the last expression:
/* Function that creates and modifies tables */
create_user_profile : name age ->
base_profile : {name: name, age: age};
with_id : t.set base_profile "id" "user_123";
with_timestamp : t.set with_id "created" "2024-01-01";
with_timestamp; /* Returns the final table */
result : create_user_profile "Alice" 30;
/* Result: {name: "Alice", age: 30, id: "user_123", created: "2024-01-01"} */
Function Composition
Implicit returns work seamlessly with function composition:
/* Functions that return functions */
create_multiplier : factor ->
multiplier : x -> x * factor;
multiplier; /* Returns the multiplier function */
/* Use the returned function */
double : create_multiplier 2;
triple : create_multiplier 3;
result1 : double 5; /* 10 */
result2 : triple 5; /* 15 */
Common Patterns
Data Transformation
/* Transform data with implicit returns */
transform_user_data : user ->
with_full_name : t.set user "full_name" (user.first_name + " " + user.last_name);
with_age_group : t.set with_full_name "age_group" (
when user.age < 18 then "minor"
when user.age < 65 then "adult"
_ then "senior"
);
with_age_group; /* Returns the transformed user */
user : {first_name: "Alice", last_name: "Smith", age: 30};
result : transform_user_data user;
/* Result: {first_name: "Alice", last_name: "Smith", age: 30, full_name: "Alice Smith", age_group: "adult"} */
Validation Functions
/* Validation with implicit returns */
validate_user : user ->
name_valid : user.name != "";
age_valid : user.age > 0 && user.age < 120;
email_valid : user.email.contains "@";
name_valid && age_valid && email_valid; /* Returns boolean */
user : {name: "Alice", age: 30, email: "alice@example.com"};
is_valid : validate_user user; /* true */
Configuration Builders
/* Build configuration with implicit returns */
build_config : base_config environment ->
dev_config : when environment is
"development" then t.merge base_config {debug: true, log_level: "verbose"}
"production" then t.merge base_config {debug: false, log_level: "error"}
_ then base_config;
dev_config; /* Returns the final config */
base : {timeout: 30, retries: 3};
result : build_config base "development";
/* Result: {timeout: 30, retries: 3, debug: true, log_level: "verbose"} */
When to Use Implicit Returns
Implicit returns work well when:
- Functions have a single, clear purpose
- The return value is obvious from the function name
- Functions are pure (no side effects)
- Functions are used in composition chains
- The logic is straightforward
Consider explicit structure when:
- Functions have complex conditional logic
- Multiple return paths are confusing
- Functions perform side effects
- The return value is not obvious
Key Takeaways
- Last expression returned - the last evaluated expression is automatically returned
- No return keyword - no explicit
return
statements needed - Conditional returns - the last expression in the executed branch is returned
- Nested functions - nested functions also use implicit returns
- Composition friendly - works seamlessly with function composition
Why This Matters
Implicit returns make the language more functional and concise:
- Concise syntax - less boilerplate code
- Functional style - emphasizes expressions over statements
- Composition focus - functions are treated as expressions
- Mathematical thinking - functions are mathematical mappings
- Readability - clear flow from input to output
This feature makes the language feel more like mathematical functions than traditional programming procedures! 🚀