- Modern feel
- No archaic syntax or keywords besides the parentheses
- No over-use of the word ‘def’ (defmacro, defun, defgeneric, etc.)
- Strong text manipulation out of the box for terminal scripting purposes
- Fast
- JIT compiled with Julia-style method monomorphisation
- Macros!!
- Case sensitive
- Lisp-2
- Racket-style brace semantics
A neat feature in some modern languages is to make functions and closures isomorphic. That is to say, the syntax for defining a function and a closure is the same.
;; this is a closure
(func (x y z) (* z (+ x y)))
;; this is a function
(func foo (x y z) (* z (+ x y)))
Note how they only differ in one aspect: the function is named.
Multimethods are baked in, and types are specified in-line
(func foo ((x num) (y num) (z num))
(* z (+ x y)))
If need be, the multimethod’s signature can be defined ahead of time
(generic foo (x y z)
(doc "This method adds `x` and `y` and multiplies the result with `z`"))
Structs are basic collections of data with no notion of hierarchy.
(struct Person
"Documentation goes here"
(name
age
email
occupation))
Structs can also optionally be typed
(struct Person
"Documentation goes here"
((name string)
(age int)
(email string)
(occupation string)))
The definition of a struct generates default accessors
;; getter
(name some-person)
;; setter
(set! (name some-person) "Charles McDonnel")
Accessors are just regular functions with one important change, they specify that they’re overrides
(func email :override ((self Person))
"This email has been redacted for security reasons")
(func (set! email) :override (new-email (self Person))
(if (validate-email new-email)
;; override can use the original setter
(set! (email person) new-email)
(panic! "Invalid email format!!")))