A functional, dynamically-typed programming language implemented in OCaml, targeting a custom bytecode VM. I wrote a blog post about it here, talking a bit about its history.
dune exec oops with no other arguments to enter a REPL. Add a filename at the end, and that file will be run.
# single line comments only
3 # numbers
"aaaa" # strings
false # booleans
[1, 2, []] # (linked) lists
{1: false, 2: "a"} # maps
x = 4 # variables
if x == 4 then
print(4)
elseif x < 4 then
print("less than 4")
else
print("greater than 4")
end
let x = 2 in
print(x) # let-delcared variables shadow outer variables, this will print 2
end
# no while loops or iteration by design, to encourage recursion (don't worry, there are tail calls)
(fun(x, y) x + y)(6, 7) # lambdas, and they are closures!
struct Fib
c
n
end # declares a new type called Fib with fields c and n
f = Fib{c: 0, n: 1} # creates a new Fib, field names have to be given as keywords
impl Stream for Fib
def head()
self.c
end
def tail()
Fib{c: self.n, n: self.c + self.n}
end
def is_empty()
self.c >= 4000000
end
end # when a trait's requirements are satisfied, they provide the implementing type with new behavior
# the stream type needs the 3 methods head, tail, and is_empty and provides methods like map, filter, and fold
f.filter(fun(x) x % 2 == 0 end).fold(fun(x, y) x + y end) # an easy solution to Project Euler problem 2 in O(n) time
import "other_file.oops" for x, y, z # equivalent of "import x, y, z from other_file" in Python
export x, f # you have to explicitly choose what to export (make public)
try
throw 8
catch
case n then
n
end # error handling, with multiple cases allowed
match f
case Fib{c: 0, n: 1} then
print("unchanged")
case x then
print(x)
end # pattern matching