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
let 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
let book = new Commerce.Product("Soli Guide", 29.99, 10)
let shirt = new Commerce.Product("T-Shirt", 19.99, 3)
println(book.in_stock()) # true
println(book.discounted(20.0)) # 23.992
let 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"
let sum = add(1, 2); # 3
let product = multiply(3, 4); # 12
# Aliased imports
import { add as sum, multiply as times } from "./math.sl"
let result = sum(10, 20); # 30
let doubled = times(5, 6); # 30
# Import everything with a namespace
import "./utils.sl" as utils
let 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"
[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"
Use Keyword
use
Alternative syntax for importing (alias for import).
use "./math.sl"
use { add, multiply } from "./math.sl"
use "./utils.sl" as utils;