Equana

Back to Examples

Language Basics

Variables, control flow, functions, and data types

Run AllReset

Equana is a language designed for scientific computing. It uses 1-based indexing, multiple dispatch, and a clean syntax that reads like math notation.

This tutorial covers the core syntax you need to start writing Equana code. Every code block below is interactive — edit it and run it to experiment.

Variables & Assignment

Variables are created by assigning a value with =. No declaration keyword is needed — just pick a name and assign:

Code [1]Run
x = 42
name = "Alice"
pi_approx = 3.14159

println(x)
println(name)
println(pi_approx)

Variables are dynamically typed — you can reassign to a different type at any time:

Code [2]Run
x = 10
println(x)

x = "now a string"
println(x)

Numbers

Equana has two primary numeric types: Int64 (integers) and Float64 (floating-point numbers). Arithmetic works as you'd expect:

Code [3]Run
# Integer arithmetic
a = 10 + 3
b = 10 - 3
c = 10 * 3
d = 10 / 3
e = 10 % 3
f = 2 ^ 10

println(a)
println(b)
println(c)
println(d)
println(e)
println(f)

Special numeric values are available:

Code [4]Run
println(Inf)
println(-Inf)
println(NaN)
println(1.0 / 0.0)
println(0.0 / 0.0)

The nothing value represents the absence of a value:

Code [5]Run
x = nothing
println(x)
println(x == nothing)

Booleans & Comparisons

Boolean values are true and false. Comparison operators return booleans:

Code [6]Run
# Comparison operators
println(3 > 2)
println(3 < 2)
println(3 == 3)
println(3 != 4)
println(3 >= 3)
println(3 <= 2)

Logical operators combine boolean values:

Code [7]Run
# Logical AND, OR, NOT
println(true && false)
println(true || false)
println(!true)

# Combining comparisons
x = 15
println(x > 10 && x < 20)

Strings

Create strings with double quotes. Use ${} for interpolation and + for concatenation:

Code [8]Run
greeting = "Hello"
name = "World"

# Concatenation
println(greeting + ", " + name + "!")

# String interpolation
age = 28
println("${name} is ${age} years old")
println("2 + 2 = ${2+2}")

For more on strings — template literals, escape sequences, and string functions — see the Working with Strings tutorial.

Arrays

Arrays use square brackets with comma-separated values. Indexing is 1-based (the first element is at index 1):

Code [9]Run
arr = [10, 20, 30, 40, 50]

# Access elements (1-based)
println(arr[1])
println(arr[3])

# Length
println(length(arr))

Numeric arrays are backed by typed memory (NDArrays) — you can update elements in place:

Code [10]Run
arr = [1, 2, 3]
arr[2] = 99
println(arr)

Non-numeric arrays (like strings) are growable — use push to append:

Code [11]Run
fruits = ["apple", "banana"]
push(fruits, "cherry")
println(fruits)

Slicing

Use ranges to extract sub-arrays:

Code [12]Run
arr = [10, 20, 30, 40, 50]

# Slice from index 2 to 4
println(arr[2:4])

# Every other element
println(arr[1:2:5])

Tuples

Tuples are fixed-size collections that can hold mixed types. Create them with parentheses:

Code [13]Run
t = (1, "hello", 3.14)

# Access by index (1-based)
println(t[1])
println(t[2])
println(t[3])
println(length(t))

Destructure tuples into individual variables:

Code [14]Run
point = (3.0, 4.0)
(x, y) = point
println(x)
println(y)

Ranges

Ranges represent sequences of numbers. The syntax is start:stop or start:step:stop:

Code [15]Run
# Basic range
r = 1:5
println(r)
println(length(r))

# Range with step
r2 = 0:2:10
println(r2)

# Check if a value is in a range
println(includes(1:10, 5))
println(includes(1:10, 15))

Ranges are commonly used for iteration and array slicing (shown in later sections).

Control Flow

if / elseif / else

Conditional branching uses if, elseif, and else, terminated with end:

Code [16]Run
x = 15

if x > 20
    println("large")
elseif x > 10
    println("medium")
else
    println("small")
end

for Loops

Iterate over ranges, arrays, or any collection with for ... in:

Code [17]Run
# Loop over a range
for i in 1:5
    println(i)
end
Code [18]Run
# Loop over an array
fruits = ["apple", "banana", "cherry"]
for fruit in fruits
  println("I like ${fruit}")
end

Use enumerate to get both the index and value:

Code [19]Run
colors = ["red", "green", "blue"]
for pair in enumerate(colors)
  (i, color) = pair
  println("${i}: ${color}")
end

break & continue

break exits a loop early. continue skips to the next iteration:

Code [20]Run
# Find the first multiple of 7
for i in 1:100
    if i % 7 == 0
        println("First multiple of 7: ${i}")
        break
    end
end
Code [21]Run
# Print only odd numbers
for i in 1:10
    if i % 2 == 0
        continue
    end
    println(i)
end

switch / case

Pattern match on values with switch:

Code [22]Run
day = 3

switch day
    case 1
        println("Monday")
    case 2
        println("Tuesday")
    case 3
        println("Wednesday")
    default
        println("Another day")
end

Cases can match multiple values:

Code [23]Run
x = 6

switch x % 3
    case 0
        println("divisible by 3")
    case 1, 2
        println("not divisible by 3")
end

try / catch

Handle errors gracefully with try and catch:

Code [24]Run
try
    x = 1 / 0
    println(x)
catch e
    println("Error: " + e.message)
end

Functions

Named Functions

Functions use function r = name(params) ... end syntax. The return value is assigned to the return variable (r by convention):

Code [25]Run
function r = square(x)
    r = x * x
end

function r = greet(name)
    r = "Hello, ${name}!"
end

println(square(5))
println(greet("Alice"))

Functions can return multiple values using tuple syntax:

Code [26]Run
function (q, r) = divmod(a, b)
    q = int64(a / b)
    r = a % b
end

(quotient, remainder) = divmod(17, 5)
println("17 / 5 = ${quotient} remainder ${remainder}")

Arrow Functions

Arrow functions provide a concise syntax for short functions:

Code [27]Run
double = x -> x * 2
add = (a, b) -> a + b

println(double(21))
println(add(3, 4))

Arrow functions with multi-line bodies use begin ... end:

Code [28]Run
classify = x -> begin
    if x > 0
        "positive"
    elseif x < 0
        "negative"
    else
        "zero"
    end
end

println(classify(5))
println(classify(-3))
println(classify(0))

Higher-Order Functions

Pass functions as arguments to map, filter, and reduce:

Code [29]Run
arr = [1, 2, 3, 4, 5]

# Square each element
println(map(arr, x -> x ^ 2))

# Keep only even numbers
println(filter(arr, x -> x % 2 == 0))

# Sum all elements
println(reduce(arr, (a, b) -> a + b, 0))

Comments & Block Syntax

Single-line comments start with #:

Code [30]Run
# This is a comment
x = 42 # inline comment
println(x)

Blocks are terminated with end — this applies to functions, if, for, switch, and try:

Code [31]Run
function r = add(a, b)
    r = a + b
end

println(add(1, 2))

Syntax Conveniences

Equana has a few optional syntax features that make numerical code more concise. These are all optional — you can always use the conventional forms — but they can make code more expressive.

Bracket-Free Function Calls

Any known function can be called without parentheses — just write the function name followed by its argument:

Code [32]Run
# These are equivalent:
println(sqrt(16.0))
println sqrt(16.0)

# Calls chain right-to-left:
# sin cos 0.0  means  sin(cos(0.0))
println(sin(cos(0.0)))

Implicit Multiplication

A numeric literal followed by a variable or expression is treated as multiplication — no * needed:

Code [33]Run
x = 5
println(2 x)
println(3 x ^ 2)

pi_approx = 3.14159
r = 10.0
println(2 pi_approx * r)

Method Syntax

Any function can be called as a method on its first argument using dot notation:

Code [34]Run
function r = double(x)
    r = x * 2
end

# Standard call
println(double(5))

# Method syntax — same result
println(5.double())

Useful Built-in Functions

Here's a quick reference of commonly used built-in functions:

Code [35]Run
# Math
println(sqrt(16.0))
println(abs(-5))
println(min(3, 7))
println(max(3, 7))
Code [36]Run
# Arrays
arr = [3, 1, 4, 1, 5, 9]
println(sort(arr))
println(reverse(arr))
println(sum(arr))
println(min(arr))
println(max(arr))
Code [37]Run
# Type inspection
println(typeof(42))
println(typeof(3.14))
println(typeof("hello"))
println(typeof(true))
println(typeof(nothing))

Summary

Quick Reference

ConceptSyntax
Assignmentx = 42
String interpolation"value is ${x}"
Array[1, 2, 3]
Tuple(1, "a", 3.0)
Range1:10 or 1:2:10
if/elseif cond ... else ... end
for loopfor i in 1:10 ... end
switchswitch val ... case 1 ... default ... end
Named functionfunction r = f(x) ... r = x * 2 ... end
Arrow functionf = x -> x * 2
Bracket-free callsin x instead of sin(x)
Implicit multiply2x instead of 2 * x
Method syntaxx.double() instead of double(x)
Comment# comment

What's Next

Workbench

Clear
No variables in workbench

Next Steps