// 12_classes_structs.ruchy - Object-oriented patterns using closures and objects
fn main() {
println("=== Object-Oriented Patterns ===\n")
// Object literals for data structures
println("=== Point Objects ===")
let p1 = { x: 3.0, y: 4.0 }
let p2 = { x: 1.0, y: 2.0 }
println(f"Point 1: ({p1.x}, {p1.y})")
println(f"Point 2: ({p2.x}, {p2.y})")
// Factory functions (constructor pattern)
fn make_point(x, y) {
{ x: x, y: y }
}
fn distance_from_origin(point) {
sqrt(point.x * point.x + point.y * point.y)
}
fn distance_between(p1, p2) {
let dx = p1.x - p2.x
let dy = p1.y - p2.y
sqrt(dx * dx + dy * dy)
}
let p3 = make_point(5.0, 12.0)
println(f"Point 3: ({p3.x}, {p3.y})")
println(f"Distance from origin: {distance_from_origin(p3)}")
println(f"Distance between p1 and p2: {distance_between(p1, p2)}")
// Bank Account pattern using functions
println("\n=== Bank Account Example ===")
fn deposit(account, amount) {
if amount > 0 {
println(f"Deposited ${amount}")
{ owner: account.owner, balance: account.balance + amount }
} else {
account
}
}
fn withdraw(account, amount) {
if amount > 0 && amount <= account.balance {
println(f"Withdrew ${amount}")
{ owner: account.owner, balance: account.balance - amount }
} else {
println("Insufficient funds")
account
}
}
fn display_account(account) {
println(f"Account: {account.owner}, Balance: ${account.balance}")
}
let account1 = { owner: "Alice", balance: 1000.0 }
display_account(account1)
let account2 = deposit(account1, 500.0)
display_account(account2)
let account3 = withdraw(account2, 200.0)
display_account(account3)
let account4 = withdraw(account3, 2000.0)
display_account(account4)
// Composition pattern
println("\n=== Composition Example ===")
fn make_employee(name, id, department) {
{ name: name, id: id, department: department }
}
fn make_manager(name, id, department, team_size) {
let emp = make_employee(name, id, department)
{ employee: emp, team_size: team_size }
}
fn display_manager(mgr) {
println(f"Manager: {mgr.employee.name}")
println(f"ID: {mgr.employee.id}")
println(f"Department: {mgr.employee.department}")
println(f"Team size: {mgr.team_size}")
}
let manager = make_manager("Bob", 12345, "Engineering", 10)
display_manager(manager)
// Container pattern
println("\n=== Container Example ===")
fn make_container(value) {
{ value: value }
}
fn get_value(container) {
container.value
}
let int_container = make_container(42)
println(f"Integer container: {get_value(int_container)}")
let string_container = make_container("Hello")
println(f"String container: {get_value(string_container)}")
// Polymorphism via duck typing
println("\n=== Shape Calculations ===")
fn make_circle(radius) {
{ kind: "circle", radius: radius }
}
fn make_rectangle(width, height) {
{ kind: "rectangle", width: width, height: height }
}
fn make_triangle(base, height) {
{ kind: "triangle", base: base, height: height }
}
fn area(shape) {
if shape.kind == "circle" {
3.14159 * shape.radius * shape.radius
} else if shape.kind == "rectangle" {
shape.width * shape.height
} else {
0.5 * shape.base * shape.height
}
}
fn describe(shape) {
if shape.kind == "circle" {
f"Circle with radius {shape.radius}"
} else if shape.kind == "rectangle" {
f"Rectangle {shape.width}x{shape.height}"
} else {
f"Triangle with base {shape.base}"
}
}
let shapes = [
make_circle(5.0),
make_rectangle(10.0, 20.0),
make_triangle(6.0, 8.0)
]
for shape in shapes {
println(f"{describe(shape)}: area = {area(shape)}")
}
// Drawable interface via convention
println("\n=== Drawable Pattern ===")
fn draw(drawable) {
if drawable.kind == "circle" {
println(f"Drawing circle with radius {drawable.radius}")
} else if drawable.kind == "rectangle" {
println(f"Drawing rectangle {drawable.width}x{drawable.height}")
} else {
println("Drawing shape")
}
}
for shape in shapes {
draw(shape)
}
println("\n=== Object Patterns Complete ===")
}