Modules
module MyModule
def hello
println("Hello from MyModule!")
end
end
Import a module.
import MyModule from "./my_module.sl"
MyModule.hello()
Import specific members.
import { hello } from "./my_module.sl"
hello()
Organize code with exports, imports, classes, and module structure.
Export Declarations
export
Makes a function, class, or constant available to other modules.
# math.sl
# Private function (not exported)
def validate_number(n: Int) -> Bool
n >= 0
end
# Exported functions
export def add(a: Int, b: Int) -> Int
a + b
end
export def subtract(a: Int, b: Int) -> Int
a - b
end
export def multiply(a: Int, b: Int) -> Int
a * b
end
export def divide(a: Int, b: Int) -> Float
if (b == 0)
panic("Division by zero")
end
float(a) / float(b)
end
export def factorial(n: Int) -> Int
if (n <= 1)
return 1
end
n * factorial(n - 1)
end
Classes in Modules
Modules can contain classes, enabling organized domain-driven code structures.
# shapes.sl
module Shapes
class Circle
radius: Float
new(radius: Float)
this.radius = radius
end
def area -> Float
3.14159 * this.radius * this.radius
end
def perimeter -> Float
2 * 3.14159 * this.radius
end
end
class Rectangle
width: Float
height: Float
new(width: Float, height: Float)
this.width = width
this.height = height
end
def area -> Float
this.width * this.height
end
def perimeter -> Float
2 * (this.width + this.height)
end
end
end
Nested Classes in Modules
Modules can also contain nested classes using the :: pattern for domain organization.
# commerce.sl
module Commerce
class Product
name: String
price: Float
quantity: Int
new(name: String, price: Float, quantity: Int)
this.name = name
this.price = price
this.quantity = quantity
end
def in_stock -> Bool
this.quantity > 0
end
def discounted(percent: Float) -> Float
this.price * (1 - percent / 100)
end
end
class Cart
items: Product[]
new
this.items = []
end
def add(product: Product)
this.items.push(product)
end
def total -> Float
sum = 0.0
for item in this.items
sum = sum + item.price
end
sum
end
end
end
Importing Classes
Import classes from modules using named imports or module namespace.
# Import the Commerce module from commerce.sl
import Commerce from "./commerce.sl"
# Use classes from the module
book = new Commerce.Product("Soli Guide", 29.99, 10)
shirt = new Commerce.Product("T-Shirt", 19.99, 3)
println(book.in_stock()) # true
println(book.discounted(20.0)) # 23.992
cart = new Commerce.Cart()
cart.add(book)
cart.add(shirt)
println(cart.total()) # 49.98
Import Statements
import
Import functions and classes from other modules.
# Import all exports
import "./math.sl"
print(add(2, 3)); # 5
print(factorial(5)); # 120
# Named imports
import { add, multiply } from "./math.sl"
sum = add(1, 2); # 3
product = multiply(3, 4); # 12
# Aliased imports
import { add as sum, multiply as times } from "./math.sl"
result = sum(10, 20); # 30
doubled = times(5, 6); # 30
# Import everything with a namespace
import "./utils.sl" as utils
formatted = utils.format_date(DateTime.utc());
Project Structure
my-project/
├── soli.toml
├── src/
│ ├── main.sl
│ ├── config.sl
│ └── utils/
│ ├── mod.sl
│ ├── string.sl
│ ├── array.sl
│ └── datetime.sl
└── lib/
└── math/
├── mod.sl
├── basic.sl
└── advanced.sl
Package Configuration
[package]
name = "my-app"
version = "1.0.0"
description = "My awesome soli application"
main = "src/main.sl"
soli_version = "1.16.0" # minimum Soli version required to run this project
[dependencies]
# Local dependency
utils = { path = "./lib/utils" }
[dev-dependencies]
test-utils = { path = "./tests/test-utils" }
[scripts]
dev = "soli serve"
build = "soli build --release"
test = "soli test"
The optional soli_version field declares the
minimum Soli interpreter version the project needs — the same idea as
Cargo's rust-version (MSRV). When it is set,
soli serve, soli test, and running a
script inside the project refuse to start on an older soli and print an
upgrade message. It is a bare minimum: a running version equal to or newer than the declared one passes.
Omit the field to accept any Soli version.
Use Keyword
use
Alternative syntax for importing (alias for import).
use "./math.sl"
use { add, multiply } from "./math.sl"
use "./utils.sl" as utils;