diff options
| author | Jan Tuomi <jans.tuomi@gmail.com> | 2022-12-05 11:03:32 +0200 |
|---|---|---|
| committer | Jan Tuomi <jans.tuomi@gmail.com> | 2022-12-05 14:21:53 +0200 |
| commit | ac6b455f4a9be11d322551a927c4330532f9f184 (patch) | |
| tree | c5dd421f4aeb8ca60eadabc5cc7edf03ae58e743 | |
| parent | 9f4ca350ee81a874b0c838c2e82076efde6db8b2 (diff) | |
Add record, union concepts
| -rw-r--r-- | examples/impure-concept.lisp | 2 | ||||
| -rw-r--r-- | examples/records-concept.lisp | 51 | ||||
| -rw-r--r-- | stdlib/maybe-with-unions.lisp | 42 | ||||
| -rw-r--r-- | stdlib/maybe.lisp | 4 |
4 files changed, 96 insertions, 3 deletions
diff --git a/examples/impure-concept.lisp b/examples/impure-concept.lisp index e612339..f769424 100644 --- a/examples/impure-concept.lisp +++ b/examples/impure-concept.lisp @@ -3,7 +3,7 @@ ; Pure functions can only call pure functions. ; Impure function names end in an exclamation mark (!) by convention. ; The top-level context is impure but has special rules -; related to (import!) and (let!). +; related to `import!`, `let!`, and other builtins. ; pure function (let! f (\[x] x)) diff --git a/examples/records-concept.lisp b/examples/records-concept.lisp new file mode 100644 index 0000000..420fa9f --- /dev/null +++ b/examples/records-concept.lisp @@ -0,0 +1,51 @@ +; Records are named tuples with an identifier. `record!` is a builtin function +; that generates functions for creating, reading and modifying a record. +; In type system terms, records are intersections. + +; `record!` can only be called in the top-level context. + +(record! Ns/User + name + phone-number) + +; Generates the following functions: + +(let! user + (Ns/User/create "John" "010-123-456")) + ; user ~> (Ns/User name:"John" phone-number:"010-123-456") + +(Ns/User/get-name user) ; => "John" +(Ns/User/get-phone-number user) ; => "010-123-456" + +(Ns/User/set-name "Rick" user) + ; => (Ns/User name:"Rick" phone-number:"010-123-456") +(Ns/User/set-phone-number unit user) + ; => (Ns/User name:"Rick" phone-number:<unit>) + + + + +; Unions are unions of records with an identifier. `union!` is a builtin function +; that generates functions for manipulating the records in the union. + +; `union!` can only be called in the top-level context. + +(union! Ns/Maybe + (just value) + (nothing)) + +; Generates the following functions: + +(let! m1 (Ns/Maybe/just 10)) ; m1 ~> (Ns/Maybe/Just value:10) +(let! m2 (Ns/Maybe/nothing)) ; m2 ~> (Ns/Maybe/Nothing) + +(Ns/Maybe/Just/get-value m1) ; => 10 + + + + +; The builtin function `kind` returns the identifier as a string for any record value + +(kind m1) ; => "Ns/Maybe/Just" +(kind m2) ; => "Ns/Maybe/Nothing" +(kind user) ; => "Ns/User" diff --git a/stdlib/maybe-with-unions.lisp b/stdlib/maybe-with-unions.lisp new file mode 100644 index 0000000..53a5024 --- /dev/null +++ b/stdlib/maybe-with-unions.lisp @@ -0,0 +1,42 @@ +; LIB + +(union! Maybe + (just value) + (nothing)) + +(let! Maybe/map (\[f m] + (match (kind m) + "Maybe/Just" (Maybe/just (f (Maybe/Just/get-value m))) + "Maybe/Nothing" (Maybe/nothing)))) + +(let! Maybe/and-then (\[f m] + (match (kind m) + "Maybe/Just" (f (Maybe/Just/get-value m)) + "Maybe/Nothing" (Maybe/nothing)))) + +; TESTING + +;; (let! print-line! (\[s] +;; (print! (concat s "\n")))) + +;; (let! a (Maybe/just 10)) +;; (let! b (Maybe/nothing)) + +;; (Maybe/map (+ 5) a) +;; (Maybe/map (+ 5) b) + +;; (Maybe/and-then (\[n] (Maybe/just (+ n 5))) a) +;; (Maybe/and-then (\[n] (Maybe/just (+ n 5))) b) + +;; (let! m (Maybe/just 10)) +;; (match m +;; (Maybe/just _) +;; (print-line! (fmt "found just {0}!" [(Maybe/Just/get-value m)])) +;; (Maybe/nothing) +;; (print-line! "found nothing!")) + +;; (let! m (Maybe/just 10)) +;; (pipe m [ +;; (Maybe/map (+ 5)) +;; (Maybe/and-then (\[val] (Maybe/just (- val 3)))) +;; ]) diff --git a/stdlib/maybe.lisp b/stdlib/maybe.lisp index 07adaee..086b0dc 100644 --- a/stdlib/maybe.lisp +++ b/stdlib/maybe.lisp @@ -1,9 +1,9 @@ ; LIB (let! Maybe/just (\[a] - ["maybe" "just" a])) + ["Maybe" "just" a])) (let! Maybe/nothing (\[] - ["maybe" "nothing"])) + ["Maybe" "nothing"])) (let! Maybe/#at (\[n seq] (match seq |
