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.
# models.sl
# Private helper class (not exported)
class ValidationResult
is_valid: Bool;
errors: String[];
new
this.is_valid = true;
this.errors = [];
end
def add_error(msg: String)
this.is_valid = false;
this.errors.push(msg);
end
end
# Exported classes
export class User
id: Int;
username: String;
email: String;
new(id: Int, username: String, email: String)
this.id = id;
this.username = username;
this.email = email;
end
def get_display_name -> String
this.username + " (" + this.email + ")"
end
end
export class Post
id: Int;
title: String;
content: String;
author: User;
new(id: Int, title: String, content: String, author: User)
this.id = id;
this.title = title;
this.content = content;
this.author = author;
end
def get_summary -> String
let preview = this.content.slice(0, 100);
this.title + " by " + this.author.username
end
end
Nested Classes in Modules
Modules can also contain nested classes using the :: pattern for domain organization.
# controllers.sl
export class Posts
class Action
def create(title: String, content: String) -> Post
# Create a new post
new Post(0, title, content, current_user())
end
def update(id: Int, updates: Any) -> Post?
# Update an existing post
find_post_by_id(id).update(updates)
end
def delete(id: Int) -> Bool
# Delete a post
remove_post(id)
end
end
class View
def list(page: Int, per_page: Int) -> Post[]
paginated_posts(page, per_page)
end
def show(id: Int) -> Post?
find_post_by_id(id)
end
end
end
export class Users
class Action
def register(username: String, email: String) -> User
new User(0, username, email)
end
def login(email: String, password: String) -> User?
authenticate_user(email, password)
end
end
class Validator
def validate_registration(data: Any) -> Bool
data["username"] != null && data["email"] != null
end
end
end
Importing Classes
Import classes from modules using named imports or module namespace.
# Import classes by name
import { User, Post } from "./models.sl";
let user = new User(1, "alice", "[email protected]");
let post = new Post(1, "Hello World", "Content here", user);
# Import with namespace
import "./controllers.sl" as controllers;
let action = new controllers.Posts.Action();
action.create("My Post", "Post content");
# Import nested classes directly
import { Posts::Action, Posts::View } from "./controllers.sl";
let view = new Posts::View();
let posts = view.list(1, 10);
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;