ESC
Type to search...
S
Soli Docs

Operators

Arithmetic, comparison, logical, compound assignment, conditional assignment, and increment/decrement 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
<< Array push (shovel) [1, 2] << 3 = [1, 2, 3]

Shovel Operator

The << (shovel) operator appends an element to an array. It modifies the array in place and returns the array.

# Append element to array
arr = [1, 2, 3]
arr << 4
print(arr);  # [1, 2, 3, 4]

# Push strings
names = ["Alice", "Bob"]
names << "Charlie"
print(names);  # ["Alice", "Bob", "Charlie"]

# Returns the array for chaining
result = [1] << 2 << 3
print(result);  # [1, 2, 3]

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.

age = 25
has_license = true

if age >= 18 && has_license
  print("Can drive")
end

At least one condition must be true.

if is_weekend || is_holiday
  print("Day off!")
end

Negates the condition.

if !is_raining
  print("No umbrella needed")
end

String Concatenation.

# Concatenation
greeting = "Hello, " + "World!";    # "Hello, World!"
message = "Value: " + 42;           # "Value: 42" (auto-conversion)
# String methods
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
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.

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

# Traditional null check
email = user["email"]
if email == null
  email = "unknown"
end

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

# Chaining with null values
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
user = get_user  # might return null

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

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

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

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

Creates a range of integers (exclusive end).

# Range creates an array
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
end

Compound Assignment Operators

Compound assignment operators combine an arithmetic operation with assignment. They modify the variable in-place.

Operator Description Equivalent
+= Add and assign a += b is a = a + b
-= Subtract and assign a -= b is a = a - b
*= Multiply and assign a *= b is a = a * b
/= Divide and assign a /= b is a = a / b
%= Modulo and assign a %= b is a = a % b
score = 0
score += 10       # score is now 10
score -= 3        # score is now 7
score *= 2        # score is now 14
score /= 7        # score is now 2
score %= 2        # score is now 0

# Also works with floats
price = 19.99
price *= 0.9      # apply 10% discount

# String concatenation with +=
msg = "Hello"
msg += " World"   # msg is now "Hello World"

Conditional Assignment

Conditional assignment operators only assign the right-hand side when the target meets a condition. The right-hand side is not evaluated when the assignment is skipped.

Operator Description Equivalent
||= Assign if current value is falsy (null or false) a ||= b is a = a || b
&&= Assign if current value is truthy a &&= b is a = a && b
??= Assign only if current value is null a ??= b is a = a ?? b
# ||= : provide a fallback for falsy values
name = null
name ||= "Anonymous"   # name is now "Anonymous"

name = "Alice"
name ||= "Anonymous"   # name stays "Alice"

# ??= : default only for null (preserves false / 0)
port = null
port ??= 8080          # port is now 8080

flag = false
flag ??= true          # flag stays false (only null triggers ??=)

# &&= : only update when already set
user = load_user()
user &&= enrich(user)  # skips enrichment when user is null

# Lazy default for hash keys
cache = {}
cache["key"] ||= expensive_lookup()  # computed once, reused on repeat

Increment & Decrement

Postfix ++ and -- operators modify a variable by 1 and return the old value.

Operator Description Returns
++ Postfix increment Old value (before increment)
-- Postfix decrement Old value (before decrement)
i = 0
i++            # i is now 1
i++            # i is now 2

old = i--  # old is 2, i is now 1

# Common pattern: loop counter
n = 0
while n < 5
  println(n)
  n = n + 1
end