Syntax
Elle is a Lisp. Expressions are parenthesized, prefix-notation forms. This document covers literal syntax and reader-level constructs.
Immediates
nil # absence of value (falsy)
true false # booleans (not #t/#f)
42 # integer (64-bit signed)
3.14 # float (64-bit IEEE 754)
-7 # negative integer
0xFF # hexadecimal (255)
0o755 # octal (493)
0b1010 # binary (10)
1_000_000 # underscores are whitespace in numbers
Keywords and symbols
Keywords are self-evaluating and interned. Symbols name bindings. Both convert to the same string:
(type-of :foo) # => :keyword
(type-of 'foo) # => :symbol
# a keyword and a symbol with the same name are not equal
(= 'name :name) # => false
# but they share the same string representation
(assert (= (string :keyword) (string 'keyword) "keyword"))
Empty list vs nil
() is the empty list — it is truthy. nil is the absence of a value and is falsy. Lists terminate with (), not nil. Use empty? to test for end-of-list; nil? will not work. See empty-list.md for the full rationale.
(empty? (list)) # => true
(nil? (list)) # => false
(if (list) :truthy :falsy) # => :truthy
(if nil :truthy :falsy) # => :falsy
Comments
# starts a line comment. Everything from # to end-of-line is ignored. This is not Scheme — ; is the splice operator, not a comment character.
Splice
;expr splices a sequence into the surrounding form. Works in function calls and collection literals.
[1 ;[2 3] 4] # => [1 2 3 4]
[;[1] ;[2] ;[3]] # => [1 2 3]
(defn add3 [a b c] (+ a b c))
(add3 ;[1 2 3]) # => 6
Quoting
'expr quotes — prevents evaluation, returning the form as data.
(type-of '(+ 1 2)) # => :list (quoted list is data, not a call)
(first '(a b c)) # => a
Quasiquote ( ) builds templates. ,expr unquotes (evaluates one subexpression). ,;expr unquote-splices (evaluates and spreads).
(let [x 10]
`(a ,x b)) # => (a 10 b)
(let [items '(2 3 4)]
`(1 ,;items 5)) # => (1 2 3 4 5)
Collection literals
Bare forms are immutable. @-prefixed forms are mutable.
Syntax Type Mutable?
──────────────────────────────────
[1 2 3] array no
@[1 2 3] @array yes
{:a 1} struct no
@{:a 1} @struct yes
"hello" string no
@"hello" @string yes
|1 2 3| set no
@|1 2 3| @set yes
b[1 2 3] bytes no
@b[1 2 3] @bytes yes
# immutable types
(type-of [1 2 3]) # => :array
(type-of {:a 1}) # => :struct
(type-of "hello") # => :string
(type-of |1 2 3|) # => :set
# mutable types
(type-of @[1 2 3]) # => :@array
(type-of @{:a 1}) # => :@struct
(type-of @"hello") # => :@string
(type-of @|1 2 3|) # => :@set
Truthiness
Only nil and false are falsy. Everything else is truthy, including 0, "", (), and [].
(if 0 :yes :no) # => :yes
(if "" :yes :no) # => :yes
(if [] :yes :no) # => :yes
(if (list) :yes :no) # => :yes
(if nil :yes :no) # => :no
(if false :yes :no) # => :no