Io syntax highlighting
Io is a prototype-based programming language inspired by Smalltalk, Self, Lua, and others.
Example:
# Comments start with hash
// C++-style comments also work
/* C-style block comments */
# Assignment
x := 42
name := "Alice"
# Slot creation (creates a setter too)
x ::= 42
# Printing
"Hello, World!" println
x println
Example:
# Everything is an object
# Create a new object by cloning
Person := Object clone
# Add slots (methods and data)
Person name := "Unknown"
Person age := 0
# Add a method using 'method'
Person greet := method(
"Hello, my name is " .. self name .. "!" println
)
# Clone to create instances
alice := Person clone
alice name = "Alice"
alice age = 30
alice greet
# Output: Hello, my name is Alice!
bob := Person clone setName("Bob") setAge(25)
Example:
# Method with parameters
add := method(a, b,
a + b
)
add(3, 4) println # Output: 7
# Method with default parameters
greet := method(name,
if(name == nil, name = "World")
"Hello, " .. name .. "!" println
)
greet # Output: Hello, World!
greet("Alice") # Output: Hello, Alice!
# Multiple statements in a method
factorial := method(n,
if(n <= 1,
return 1,
return n * factorial(n - 1)
)
)
factorial(5) println # Output: 120
Example:
# if-then-else
x := 10
if(x > 0,
"positive" println,
"not positive" println
)
# Nested if
if(x < 0,
"negative" println,
if(x > 0,
"positive" println,
"zero" println
)
)
# while loop
i := 0
while(i < 5,
i println
i = i + 1
)
# for loop
for(i, 1, 10,
i println
)
# Loop with step
for(i, 0, 100, 10,
i println
)
# break and continue
for(i, 1, 10,
if(i == 3, continue)
if(i == 7, break)
i println
)
Example:
# Create a list
numbers := list(1, 2, 3, 4, 5)
# Or using List clone
fruits := List clone
fruits append("apple")
fruits append("banana")
fruits append("cherry")
# Access elements
fruits at(0) println # Output: apple
fruits first println # Output: apple
fruits last println # Output: cherry
# List size
fruits size println # Output: 3
# Check if empty
fruits isEmpty println # Output: false
# Remove elements
fruits remove("banana")
fruits removeAt(0)
# Iterate over list
fruits foreach(fruit,
fruit println
)
# Map
squared := numbers map(x, x * x)
# Result: list(1, 4, 9, 16, 25)
# Filter
evens := numbers select(x, x % 2 == 0)
# Result: list(2, 4)
# Reduce
sum := numbers reduce(total, num, total + num, 0)
# Result: 15
Example:
# Create a map
person := Map clone
person atPut("name", "Alice")
person atPut("age", 30)
person atPut("city", "NYC")
# Access values
person at("name") println # Output: Alice
# Check if key exists
person hasKey("name") println # Output: true
# Get all keys
person keys foreach(key,
key println
)
# Get all values
person values foreach(value,
value println
)
# Iterate over map
person foreach(key, value,
(key .. ": " .. value) println
)
# Remove key
person removeAt("city")
Example:
# String literals
greeting := "Hello, World!"
name := 'Alice'
# String concatenation
fullName := "Alice" .. " " .. "Smith"
# String interpolation using concatenation
age := 30
message := "I am " .. age .. " years old"
# String methods
greeting size println # Length
greeting uppercase println # HELLO, WORLD!
greeting lowercase println # hello, world!
# String contains
greeting contains("World") println # true
# Split string
parts := "one,two,three" split(",")
parts foreach(part, part println)
# Replace
text := "Hello, Bob!" replace("Bob", "Alice")
# Result: "Hello, Alice!"
# Substring
text := "Hello, World!"
text slice(0, 5) println # Output: Hello
text slice(7) println # Output: World!
Example:
# Integers and floats
x := 42
y := 3.14
# Arithmetic
a := 10 + 5 # 15
b := 10 - 5 # 5
c := 10 * 5 # 50
d := 10 / 5 # 2
e := 10 % 3 # 1
# Comparison
x == y # false
x != y # true
x < y # false
x > y # true
# Math methods
(-5) abs println # 5
(3.7) ceil println # 4
(3.7) floor println # 3
(3.7) round println # 4
(16) sqrt println # 4
(2) pow(8) println # 256
# Random numbers
Number random println # Random float 0-1
(1 to(100)) random println # Random int 1-100
Example:
# Block (like lambda/anonymous function)
square := block(x, x * x)
square call(5) println # Output: 25
# Blocks capture scope
makeCounter := method(
count := 0
block(
count = count + 1
count
)
)
counter := makeCounter
counter call println # Output: 1
counter call println # Output: 2
counter call println # Output: 3
# Blocks with lists
list(1, 2, 3, 4, 5) map(block(x, x * 2)) println
# Output: list(2, 4, 6, 8, 10)
Example:
# Base object
Animal := Object clone
Animal name := "Unknown"
Animal speak := method("..." println)
# Derive from Animal
Dog := Animal clone
Dog speak := method("Woof!" println)
Cat := Animal clone
Cat speak := method("Meow!" println)
# Create instances
fido := Dog clone
fido name = "Fido"
fido speak # Output: Woof!
whiskers := Cat clone
whiskers name = "Whiskers"
whiskers speak # Output: Meow!
# Check prototype chain
fido proto == Dog # true
Dog proto == Animal # true
Example:
# try-catch
result := try(
# Code that might raise exception
x := 10 / 0
) catch(Exception,
"Error occurred!" println
0 # Default value
)
# Raising exceptions
validate := method(x,
if(x < 0,
Exception raise("Value must be positive")
)
x
)
# Custom exception handling
try(
validate(-5)
) catch(Exception,
"Caught: " .. (Exception message) println
)
Example:
# Read file
contents := File with("data.txt") contents
# Write file
File with("output.txt") write("Hello, World!")
# Append to file
File with("log.txt") appendToContents("Log entry\n")
# Check if file exists
File with("data.txt") exists println
# Create directory
Directory with("mydir") create
# List directory contents
Directory with(".") items foreach(item,
item name println
)
Example:
# Fibonacci sequence
fibonacci := method(n,
if(n <= 1,
return n,
return fibonacci(n - 1) + fibonacci(n - 2)
)
)
# Generate fibonacci sequence
fib := list()
for(i, 0, 10,
fib append(fibonacci(i))
)
fib println # list(0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55)
# Quicksort
quicksort := method(lst,
if(lst size <= 1,
return lst
)
pivot := lst at(0)
rest := lst slice(1)
less := rest select(x, x < pivot)
greater := rest select(x, x >= pivot)
return quicksort(less) append(pivot) appendSeq(quicksort(greater))
)
unsorted := list(3, 1, 4, 1, 5, 9, 2, 6)
quicksort(unsorted) println
# Output: list(1, 1, 2, 3, 4, 5, 6, 9)
# Object-oriented example: Bank account
Account := Object clone
Account balance := 0
Account deposit := method(amount,
if(amount <= 0,
Exception raise("Deposit amount must be positive")
)
self balance = self balance + amount
self
)
Account withdraw := method(amount,
if(amount <= 0,
Exception raise("Withdrawal amount must be positive")
)
if(amount > self balance,
Exception raise("Insufficient funds")
)
self balance = self balance - amount
self
)
Account getBalance := method(
self balance
)
# Create and use account
myAccount := Account clone
myAccount deposit(1000)
myAccount withdraw(250)
myAccount getBalance println # Output: 750
# Method chaining
myAccount deposit(500) withdraw(100) deposit(50)
myAccount getBalance println # Output: 1200
# Observer pattern
Observable := Object clone
Observable observers := list()
Observable addObserver := method(observer,
self observers append(observer)
)
Observable notifyObservers := method(
self observers foreach(observer,
observer update(self)
)
)
Observer := Object clone
Observer update := method(subject,
"Observer notified!" println
)
subject := Observable clone
observer1 := Observer clone
observer2 := Observer clone
subject addObserver(observer1)
subject addObserver(observer2)
subject notifyObservers
# Output:
# Observer notified!
# Observer notified!
Example:
# Get list of slots (methods/attributes)
Person slotNames println
# Check if object has a slot
Person hasSlot("name") println # true
# Get slot value
Person getSlot("name") println
# Set slot value
Person setSlot("city", "NYC")
# Dynamically call methods
Person perform("greet")
# Create methods dynamically
Person setSlot("age", 0)
Person setSlot("setAge", method(newAge,
self age = newAge
))
# Forward unknown messages
ForwardingObject := Object clone
ForwardingObject forward := method(
"Called: " .. call message name println
"Arguments: " .. call message arguments println
)
obj := ForwardingObject clone
obj unknownMethod(1, 2, 3)
# Output:
# Called: unknownMethod
# Arguments: list(1, 2, 3)