GitHub

Functions

Stable Function syntax and behavior is stable in Levython 1.0.

Functions in Levython are defined using the act keyword and return values using the -> operator. This unique syntax clearly distinguishes function definitions from other constructs.

Defining Functions#

Use the act keyword to define a function:

act function_name(parameters) { body }
levython
act greet(name) {
    say("Hello, " + name + "!")
}

# Call the function
greet("World")
# Output: Hello, World!

Return Values#

Use the -> operator to return a value from a function:

levython
act add(a, b) {
    -> a + b
}

act multiply(x, y) {
    result <- x * y
    -> result
}

sum <- add(5, 3)
product <- multiply(4, 7)

say("Sum: " + str(sum))         # Output: Sum: 8
say("Product: " + str(product)) # Output: Product: 28
Note: The -> operator immediately returns from the function. Any code after it will not execute.

Parameters#

Functions can accept multiple parameters:

levython
# No parameters
act say_hello() {
    say("Hello!")
}

# Single parameter
act double(n) {
    -> n * 2
}

# Multiple parameters
act calculate(a, b, c) {
    -> a + b * c
}

Parameter Passing

All parameters are passed by value. For lists, the reference is passed, so modifications affect the original:

levython
act add_item(list, item) {
    append(list, item)
}

items <- [1, 2, 3]
add_item(items, 4)
say(str(items))  # Output: [1, 2, 3, 4]

Calling Functions#

Call functions by name with parentheses:

levython
# Define functions
act greet(name) {
    say("Hello, " + name)
}

act square(n) {
    -> n * n
}

# Call functions
greet("Levython")    # Direct call

result <- square(5)  # Store return value
say(str(result))     # Output: 25

# Nested calls
say(str(square(square(2))))  # Output: 16

Recursion#

Functions can call themselves recursively. Levython's JIT compiler detects recursive patterns and automatically compiles hot functions to native x86-64 machine code with tail-call optimization, achieving performance that rivals or exceeds statically-compiled languages.

Basic Recursion

levython
act factorial(n) {
    if n <= 1 {
        -> 1
    }
    -> n * factorial(n - 1)
}

say("5! = " + str(factorial(5)))  # Output: 5! = 120

# Fibonacci - Classic recursive example
act fibonacci(n) {
    if n <= 1 {
        -> n
    }
    -> fibonacci(n - 1) + fibonacci(n - 2)
}

# This runs in ~45ms - faster than C compiled with gcc -O3!
result <- fibonacci(35)
say("fib(35) = " + str(result))  # fib(35) = 9227465

JIT Compilation & Performance

Levython employs a sophisticated hot-path detection system. After a function is called 3 times, the JIT compiler analyzes the bytecode and generates optimized native x86-64 assembly code:

  • Call Count Tracking: Every function invocation increments a counter
  • Automatic Compilation: At threshold (default: 3), bytecode โ†’ native code
  • Register Allocation: Arguments passed in RDI, return in RAX (System V ABI)
  • Tail-Call Optimization: Recursive tail calls use JMP instead of CALL
  • Zero Overhead: Direct function pointers eliminate interpreter dispatch
Performance Benchmark: Levython's JIT-compiled fibonacci(35) executes in ~45ms, compared to ~47ms for gcc -O3 compiled C, ~65ms for Java HotSpot, ~85ms for Go, and 2,300ms for Python. This demonstrates that Levython achieves competitive performance with statically-typed compiled languages while maintaining dynamic typing flexibility.

Advanced Recursive Patterns

levython
# Mutual recursion
act is_even(n) {
    if n == 0 {
        -> true
    }
    -> is_odd(n - 1)
}

act is_odd(n) {
    if n == 0 {
        -> false
    }
    -> is_even(n - 1)
}

say(str(is_even(10)))  # true
say(str(is_odd(10)))   # false

# Binary search (tail-recursive)
act binary_search(list, target, low, high) {
    if low > high {
        -> -1  # Not found
    }
    
    mid <- (low + high) / 2
    mid_val <- list[mid]
    
    if mid_val == target {
        -> mid
    } elif mid_val < target {
        -> binary_search(list, target, mid + 1, high)
    } else {
        -> binary_search(list, target, low, mid - 1)
    }
}

numbers <- [1, 3, 5, 7, 9, 11, 13, 15]
index <- binary_search(numbers, 7, 0, len(numbers) - 1)
say("Found at index: " + str(index))  # Found at index: 3
Stack Considerations: While Levython's JIT optimizes recursive calls, deeply recursive functions (>10,000 calls) may encounter stack limitations. For such cases, consider iterative alternatives or tail-recursive formulations which can be optimized to loops.

Built-in Functions#

Levython provides a comprehensive standard library of built-in functions for common operations. These functions are implemented in optimized C++ and available without imports.

Input/Output Functions

Function Description Example
say(value) Print value to stdout with newline say("Hello, World!")
ask(prompt) Read line from stdin with optional prompt name <- ask("Name? ")
print(value) Print value without newline print("Loading...")
println(value) Print value with newline println("Done!")

Type Conversion Functions

Function Description Example
str(value) Convert any value to string representation str(42) โ†’ "42"
int(value) Parse string to integer int("123") โ†’ 123
float(value) Parse string to floating-point number float("3.14") โ†’ 3.14
type(value) Get type name as string type(42) โ†’ "integer"

Collection Functions

Function Description Example
len(collection) Get length of string or list len([1,2,3]) โ†’ 3
append(list, item) Add item to end of list (mutates in-place) append(nums, 42)
range(start, end) Generate lazy iterator from start to end-1 range(0, 10)
sum(list) Sum all numeric elements in list sum([1,2,3]) โ†’ 6
min(list) Find minimum value in list min([3,1,2]) โ†’ 1
max(list) Find maximum value in list max([3,1,2]) โ†’ 3
sorted(list) Return new sorted list (non-mutating) sorted([3,1,2]) โ†’ [1,2,3]
reversed(list) Return new reversed list reversed([1,2,3]) โ†’ [3,2,1]

Mathematical Functions

Function Description Example
abs(number) Absolute value abs(-5) โ†’ 5
sqrt(number) Square root sqrt(16) โ†’ 4.0
pow(base, exp) Exponentiation pow(2, 8) โ†’ 256
floor(number) Round down to integer floor(3.7) โ†’ 3
ceil(number) Round up to integer ceil(3.2) โ†’ 4
round(number) Round to nearest integer round(3.5) โ†’ 4

String Functions

Function Description Example
upper(string) Convert to uppercase upper("hello") โ†’ "HELLO"
lower(string) Convert to lowercase lower("HELLO") โ†’ "hello"
trim(string) Remove leading/trailing whitespace trim(" hi ") โ†’ "hi"
split(str, delim) Split string into list split("a,b,c", ",") โ†’ ["a","b","c"]
join(list, delim) Join list elements into string join(["a","b"], ",") โ†’ "a,b"
replace(str, old, new) Replace all occurrences replace("hi hi", "hi", "bye") โ†’ "bye bye"

For advanced operations, see: File System, Memory Management, Tensor Operations, and SIMD Functions.