9. Miscellaneous
So far, in this tutorial series, we have seen different aspects of Moonli (and Common Lisp) without seeing constructs to write your own code. Here we cover some of those constructs.
Conditional Execution
Moonli supports the standard conditional form if..elif..else. This is translated to the Common Lisp form cond.
if x > 10:
format(t, "Large")
elif x > 5:
format(t, "Medium")
else:
format(t, "Small")
end
- Conditions evaluate top-to-bottom.
- The first true condition’s block is executed.
- The
elifandelsebranches are optional.
Looping
Moonli provides two main looping constructs
for …
This is based on Shinmera’s for and corresponds to the standard for loops in other languages. These are useful for iterating over a data structures, or for iterating a fixed number of times.
For has a number of clauses. A generic clause is over that allows iteration over lists as well as vectors.
# Iterate over lists
for x in (1, 2, 3):
print(x)
end
# Iterate over vectors
for x in [1, 2, 3]:
print(x)
end
To iterate over ranges:
for i repeat 10:
print(i)
end
loop
Because Moonli runs on Common Lisp, you also have full access to the powerful loop. This is a mini-language for writing concise iteration and accumulation logic.
1. Simple Repetition
The simplest form counts from 1 to N:
loop :for i :from 1 :to 5 :do
print(i)
end
loop :for i :from 0 :to 20 :by 5 do
print(i)
end
2. Iterating Over Lists
You can loop directly over a list:
loop :for x :in (10, 20, 30) :do
print(x)
end
Or over any sequence:
loop :for ch :across "moonli" :do
print(ch)
end
3. Conditional Execution Inside loop
The code following :do can be arbitrary Moonli code. This can include conditional statements. However, you can also put conditional statements with the loop itself:
loop :for n :from 1 :to 10
:when (rem(n, 2) == 0) :do
format(t, "~d is even~%", n)
end
4. Collect, Sum, Maximizing
One of the most powerful features is accumulation. loop can build lists, sums, and more without extra variables.
loop :for i :in (1, 2, 3, 4)
:collect i * 2
end
#=> (2, 4, 6, 8)
loop :for x :in (1, 2, 3, 4)
:sum x
end
#=> 10
loop :for x :in (2, 3, 4, 1)
:maximizing x
end
#=> 4
5. Finally
A finally clause runs after the iteration and lets you return a final value:
loop :for word :in ("hello", "world", "Moonli", "is", "powerful")
:count word :into n
:finally return(format(nil, "Found ~d words", n))
end
#=> "Found 5 words"
6. Using Multiple Clauses
loop shines when you combine iteration, conditionals, and accumulation:
loop :for x :in (-1, 2, 3, -1, 5)
:when x > 0
:collect x :into positives
:finally return({
:positives : positives,
:total : apply(function(+), positives)
})
end
#=> {
:positives : (2, 3, 5),
:total : 10
}
This runs in one pass but builds structured results.
Format – Producing Structured Output
Moonli’s format follows a simplified Lisp-style template mechanism. It allows inserting variables into strings or writing formatted text to output.
The first argument to format indicates the stream. This can be t which corresponds to the standard-output stream. Or nil which obtains the result as a string. Or any variable or expression that evaluates to a stream.
3.1 Basic formatting
format(nil, "Hello, ~a!", "Moonli")
#=> "Hello, Moonli!"
~a inserts the argument using its “human-friendly” representation.
3.2 Multiple arguments
format(nil, "~a + ~a = ~a", a, b, a + b)
3.3 Common directives
| Directive | Meaning |
|---|---|
~a | Insert readable form |
~s | Insert literal/escaped form |
~d | Insert decimal integer |
~f | Insert floating-point number |
~% | Insert newline |
Examples:
format("Count: ~d", n)
format("Value: ~f", pi)
format("Debug: ~s", obj)
3.4 List Iteration with a joiner
format(t, "~{~A~^, ~}", (1,2,3))
#=> (prints) 1, 2, 3
More directives
The wikipedia page on format lists the variety of directives supported by format.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.