-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
240 additions
and
282 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,162 +1,110 @@ | ||
;; Lust is a simple Lisp-like language based on the idea of term rewriting. | ||
;; It is a functional language with a simple syntax and semantics. | ||
;; Terms are rewritten using pattern matching and substitution. | ||
;; The language is dynamically typed and has first-class functions. | ||
|
||
;; Special Forms: | ||
;; - def: define a variable | ||
;; - let: bind variables in a scope | ||
;; - match: pattern match a term | ||
;; - list: create a list | ||
;; - set: create a set | ||
;; - map: create a map | ||
;; - array: create an array | ||
;; - byte-array: create a byte array | ||
;; - apply: apply a function to a list of arguments | ||
;; - eval: evaluate a term | ||
;; - read: read a term from a string | ||
;; - fn: create a lambda function | ||
;; - and: short-circuiting logical and | ||
;; - or: short-circuiting logical or | ||
;; - quote: prevent evaluation of a term | ||
;; - quasiquote: prevent evaluation of a term, except for unquoted terms | ||
;; - unquote: evaluate a term in a quasiquote | ||
;; - unquote-splicing: evaluate a term in a quasiquote and splice the result | ||
;; - module: define a module | ||
|
||
;; def declarations | ||
(def x 42) | ||
|
||
(def (fib n) | ||
(if (<= n 1) | ||
n | ||
(+ (fib (- n 1)) (fib (- n 2))))) | ||
|
||
(def (fib n) | ||
(if (<= n 1) | ||
n | ||
(+ (fib (- n 1)) (fib (- n 2))))) | ||
|
||
(def (fib-iter n) | ||
(let loop ((a 0) (b 1) (i n)) | ||
(if (= i 0) | ||
a | ||
(loop b (+ a b) (- i 1))))) | ||
|
||
;; def fib_iter n = | ||
;; let loop a b i = | ||
;; if i = 0 then a | ||
;; else loop b (a + b) (i - 1) | ||
;; in loop 0 1 n | ||
|
||
(def (fib-iter n) | ||
(letf (loop a b i) | ||
(if (= i 0) | ||
a | ||
(loop b (+ a b) (- i 1))) | ||
(loop 0 1 n))) | ||
|
||
;; this could also be done with a `match` expression | ||
(def (fib n) | ||
(match n | ||
(0 0) | ||
(1 1) | ||
(n (+ (fib (- n 1)) (fib (- n 2)))))) | ||
|
||
;; call the `fib` function | ||
(fib 10) | ||
|
||
;; Note: The pattern matching in the `fib` function is not the same as in other languages. | ||
;; You might think `(fib 0)` would be syntax sugar for binding `n` to `0` in the `fib` function. | ||
;; However, it is actually binding the whole term `(fib 0)` to `0` in the `fib` function. | ||
;; This is equivalent to telling the runtime that it can replace `(fib 0)` with `0`. | ||
|
||
;; let expressions | ||
(let ((x 1) (y 2)) (+ x y)) | ||
|
||
;; fn expressions | ||
(let ((x 1) | ||
((foo y) (+ x y))) | ||
(foo 2)) | ||
|
||
|
||
;; quote expressions | ||
(quote (1 2 3)) | ||
'(1 2 3) | ||
;; > '(1 2 3) | ||
;; (1 2 3) | ||
|
||
;; quasiquote/unquote expressions | ||
(quasiquote (1 2 (unquote (+ 1 2)) 4)) | ||
`(1 2 ,(+ 1 2) 4) | ||
|
||
;; lambda expressions | ||
(fn (x) (+ x 1)) | ||
;; lambda call | ||
((fn (x) (+ x 1)) 2) | ||
|
||
;; and expressions (short-circuiting) | ||
(and (< 1 2) (> 2 1)) | ||
|
||
;; or expressions (short-circuiting) | ||
(or (< 1 2) (> 2 1)) | ||
|
||
;; not expressions | ||
(not (< 1 2)) | ||
|
||
;; list expressions | ||
[1 2 (+ 1 2) 4] | ||
|
||
;; this is equivalent to | ||
(List.new 1 2 (+ 1 2) 4) | ||
|
||
;; maps | ||
{:a 1 :b 2} | ||
|
||
;; this is equivalent to | ||
(Map.new :a 1 :b 2) | ||
|
||
;; Maps that use keyword symbols as keys are called records. | ||
;; Keywords are symbols that evaluate to themselves they | ||
;; are used to represent named arguments and are often | ||
;; used as keys in maps. | ||
:foo | ||
; => :foo | ||
|
||
;; map update | ||
(Map.insert {:a 1 :b 2} :a 3) | ||
|
||
;; map access | ||
(Map.get {:a 1 :b 2} :a) | ||
(def m {:a 1 :b 2}) | ||
(m.a) | ||
|
||
;; map remove | ||
(Map.remove {:a 1 :b 2} :a) | ||
|
||
;; sets | ||
#{1 2 3} | ||
|
||
;; this is equivalent to | ||
(Set.new 1 2 3) | ||
|
||
;; Macros are rules for transforming terms at compile time. | ||
;; They are used to define new syntax and to optimize code. | ||
;; Macros are defined using the `macro` special form. | ||
(macro (if cond then else) | ||
`(match ,cond | ||
(#t ,then) | ||
(#f ,else))) | ||
|
||
;; Reader macros are rules for transforming terms at read time. | ||
;; They are used to define new syntax and to optimize code. | ||
;; The most common reader macro is the quote reader macro. | ||
;; Quote can be defined as a reader macro using the `reader` special form | ||
;; and template matching. | ||
(reader-macro (quote stream) | ||
(match stream | ||
("'{term}" (quote term)))) | ||
|
||
;; module declarations | ||
(module Vector | ||
(def (new) {:data []}) | ||
(def (new &xs) {:data xs})) | ||
|
||
(def (fib n) | ||
(match n | ||
(0 0) | ||
(1 1) | ||
(n (+ (fib (- n 1)) (fib (- n 2)))))) | ||
|
||
;; Built-in Functions: | ||
;; - +: add numbers | ||
;; - -: subtract numbers | ||
;; - *: multiply numbers | ||
;; - /: divide numbers | ||
;; - %: modulo | ||
;; - =: equality | ||
;; - <: less than | ||
;; - >: greater than | ||
;; - <=: less than or equal to | ||
;; - >=: greater than or equal to | ||
;; - head: get the first element of a list | ||
;; - tail: get the rest of the elements of a list | ||
;; - empty?: check if a list is empty | ||
;; - pair: create a pair | ||
|
||
;; Built-in data types: | ||
;; - Num | ||
;; - Real | ||
;; - Rational | ||
;; - BigRational | ||
;; - Int | ||
;; - BigInt | ||
;; - Nat | ||
;; - BigNat | ||
;; - Byte | ||
;; - Boolean | ||
;; - List | ||
;; - Set | ||
;; - Map | ||
;; - Array | ||
;; - ByteArray | ||
;; - Symbol | ||
;; - Char | ||
;; - String | ||
|
||
(def x 10) | ||
x | ||
; => 10 | ||
|
||
; Function definition | ||
(def (add x y) (+ x y)) | ||
|
||
; Function call | ||
(add 1 2) | ||
; => 3 | ||
|
||
; Let binding | ||
(let ((x 10) (y 20)) (+ x y)) | ||
; => 30 | ||
|
||
; List creation | ||
(list 1 2 3) | ||
|
||
; Lambda function | ||
((fn (x) (+ x 1)) 1) | ||
|
||
; Logical and | ||
(and true false) | ||
; => false | ||
|
||
; Logical or | ||
(or true false) | ||
; => true | ||
|
||
; Quote | ||
(quote (+ 1 2)) ; or | ||
'(+ 1 2) | ||
; => (+ 1 2) | ||
|
||
; Quasiquote/unquote | ||
`(1 2 ,(+ 1 2)) | ||
; => (1 2 3) | ||
|
||
; Unquote-splicing | ||
`(1 2 ,@(list 3 4)) | ||
; => (1 2 3 4) | ||
|
||
; Symbol | ||
'symbol | ||
; => symbol | ||
|
||
; Keyword symbol | ||
:keyword | ||
; => :keyword | ||
|
||
; byte array | ||
(byte-array 1 2 3) ; or | ||
#u8(1 2 3) | ||
; => #u8(1 2 3) | ||
|
Oops, something went wrong.