ESC
Type to search...
S
Soli Docs

Operators

Arithmetic, comparison, logical, and string operators in Soli.

Arithmetic Operators

Operator Description Example
+ Addition 5 + 3 = 8
- Subtraction 5 - 3 = 2
* Multiplication 5 * 3 = 15
/ Division 6 / 2 = 3.0
% Modulo 5 % 2 = 1

Comparison Operators

Operator Description
== Equal to
!= Not equal to
< Less than
<= Less than or equal
> Greater than
>= Greater than or equal

Logical Operators

&& Logical AND

Both conditions must be true.

let age = 25;
let has_license = true;

if (age >= 18 && has_license) {
    print("Can drive");
}

At least one condition must be true.

if (is_weekend || is_holiday) {
    print("Day off!");
}

Negates the condition.

if (!is_raining) {
    print("No umbrella needed");
}

String Concatenation.

# Concatenation
let greeting = "Hello, " + "World!";    # "Hello, World!"
let message = "Value: " + 42;           # "Value: 42" (auto-conversion)
# String methods
let text = "  Hello, World!  ";
print(text.trim());           # "Hello, World!"
print(text.lstrip());         # "Hello, World!  "
print(text.rstrip());         # "  Hello, World!"
print(text.upper());          # "  HELLO, WORLD!  "
print(text.lower());          # "  hello, world!  "
print(text.len());            # 18

# Substring operations
let s = "Hello, World!";
print(s.sub(0, 5));           # "Hello" (from index 0, length 5)
print(s.find("World"));       # 7 (index of first occurrence)
print(s.contains("Hello"));   # true
print(s.starts_with("Hell")); # true
print(s.ends_with("!"));      # true

# String manipulation
print(s.replace("World", "Soli"));  # "Hello, Soli!"
print(s.split(", "));              # ["Hello", "World!"]
print(s.chomp());                 # "Hello, World!" (removes trailing newline)
print(s.reverse());               # "!dlroW ,olleH"
print(s.capitalize());            # "Hello, world!"
print(s.swapcase());              # "hELLO, wORLD!"

# String padding
print("hi".center(10));           # "    hi    "
print("hi".ljust(10));            # "hi        "
print("hi".rjust(10));            # "        hi"

# String queries
print(s.count("l"));              # 3
print(s.gsub("l", "L"));          # "HeLLo, WorLd!"
print(s.match("H(.*)o"));         # ["Hello", "ell"]
print(s.scan("[aeiou]"));         # ["e", "o", "o"]
print(s.tr("aeiou", "AEIOU"));    # "HEllO, WOrld!"

# Character operations
print("A".ord());                 # 65
print("hello".bytes());           # [104, 101, 108, 108, 111]
print("hello".chars());           # ["h", "e", "l", "l", "o"]
print("a\nb\nc".lines());         # ["a", "b", "c"]

# Partition and delete
print("hello-world-test".partition("-"));   # ["hello", "-", "world-test"]
print("hello-world".delete("l"));           # "heo-word"
print("hello".delete_prefix("hel"));        # "lo"
print("hello".delete_suffix("lo"));         # "hel"

# String encoding
print("hello".bytesize());        # 5

# Truncate
print("hello world".truncate(5)); # "he..."

Use ?? to provide default values for null.

let user = {"name": "Alice", "email": null};

# Traditional null check
let email = user["email"];
if (email == null) {
    email = "unknown";
}

# Null coalescing operator
let display_email = user["email"] ?? "unknown";

# Chaining with null values
let city = user["address"]["city"] ?? "Unknown City";
# If any key in the chain is null/missing, returns "Unknown City"

Use &. for safe navigation — access properties or call methods on values that might be null without raising an error.

# Safe navigation operator
let user = get_user()  # might return null

# Returns null if user is null, otherwise returns user.name
let name = user&.name

# Chain safe navigation for nested access
let city = user&.address&.city

# Call methods safely — returns null if user is null
let greeting = user&.greet()

# Combine with ?? for default values
let display_name = user&.name ?? "Anonymous"

Creates a range of integers (exclusive end).

# Range creates an array
let numbers = 1..5;  # [1, 2, 3, 4]

# Use in for loops
for (i in 0..10) {
    print(i);  # 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
}