summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
Diffstat (limited to 'doc')
-rw-r--r--doc/cljlib.md77
-rw-r--r--doc/macros.md207
-rw-r--r--doc/tests/test.md41
3 files changed, 174 insertions, 151 deletions
diff --git a/doc/cljlib.md b/doc/cljlib.md
index e54bcae..4634fb9 100644
--- a/doc/cljlib.md
+++ b/doc/cljlib.md
@@ -138,15 +138,12 @@ arguments to `args`, and `f` must support variadic amount of
arguments.
### Examples
-Applying `print` to different arguments:
+Applying [`add`](#add) to different amount of arguments:
``` fennel
-(apply print [1 2 3 4])
-;; prints 1 2 3 4
-(apply print 1 [2 3 4])
-;; => 1 2 3 4
-(apply print 1 2 3 4 5 6 [7 8 9])
-;; => 1 2 3 4 5 6 7 8 9
+(assert-eq (apply add [1 2 3 4]) 10)
+(assert-eq (apply add 1 [2 3 4]) 10)
+(assert-eq (apply add 1 2 3 4 5 6 [7 8 9]) 45)
```
## `add`
@@ -228,7 +225,7 @@ Function signature:
(inc ([x]))
```
-Increase number by one
+Increase number `x` by one
## `dec`
Function signature:
@@ -237,7 +234,7 @@ Function signature:
(dec ([x]))
```
-Decrease number by one
+Decrease number `x` by one
## `eq`
Function signature:
@@ -270,24 +267,24 @@ metadata attached for this test to work.
Non empty tables:
``` fennel
-(assert (map? {:a 1 :b 2}))
+(assert-is (map? {:a 1 :b 2}))
(local some-table {:key :value})
-(assert (map? some-table))
+(assert-is (map? some-table))
```
Empty tables:
``` fennel
(local some-table {})
-(assert (not (map? some-table)))
+(assert-not (map? some-table))
```
Empty tables created with [`hash-map`](#hash-map) will pass the test:
``` fennel
(local some-table (hash-map))
-(assert (map? some-table))
+(assert-is (map? some-table))
```
## `vector?`
@@ -312,24 +309,24 @@ metadata attached for this test to work.
Non empty vector:
``` fennel
-(assert (vector? [1 2 3 4]))
+(assert-is (vector? [1 2 3 4]))
(local some-table [1 2 3])
-(assert (vector? some-table))
+(assert-is (vector? some-table))
```
Empty tables:
``` fennel
(local some-table [])
-(assert (not (vector? some-table)))
+(assert-not (vector? some-table))
```
Empty tables created with [`vector`](#vector) will pass the test:
``` fennel
(local some-table (vector))
-(assert (vector? some-table))
+(assert-is (vector? some-table))
```
## `multifn?`
@@ -360,7 +357,7 @@ Function signature:
(nil? ([]) ([x]))
```
-Test if value is nil.
+Test if `x` is nil.
## `zero?`
Function signature:
@@ -369,7 +366,7 @@ Function signature:
(zero? ([x]))
```
-Test if value is equal to zero.
+Test if `x` is equal to zero.
## `pos?`
Function signature:
@@ -396,7 +393,7 @@ Function signature:
(even? ([x]))
```
-Test if value is even.
+Test if `x` is even.
## `odd?`
Function signature:
@@ -405,7 +402,7 @@ Function signature:
(odd? ([x]))
```
-Test if value is odd.
+Test if `x` is odd.
## `string?`
Function signature:
@@ -514,7 +511,7 @@ Sets additional metadata for function [`vector?`](#vector?) to work.
``` fennel
(local v (vector 1 2 3 4))
-(assert (eq v [1 2 3 4]))
+(assert-eq v [1 2 3 4])
```
## `seq`
@@ -564,7 +561,7 @@ Function signature:
(kvseq ([col]))
```
-Transforms any table to key-value sequence.
+Transforms any table `col` to key-value sequence.
## `first`
Function signature:
@@ -953,7 +950,8 @@ Function signature:
(hash-map ([]) ([& kvs]))
```
-Create associative table from keys and values
+Create associative table from `kvs` represented as sequence of keys
+and values
## `get`
Function signature:
@@ -1002,7 +1000,7 @@ Function signature:
(find ([tbl key]))
```
-Returns the map entry for `key`, or `nil` if key not present.
+Returns the map entry for `key`, or `nil` if key not present in `tbl`.
## `dissoc`
Function signature:
@@ -1011,44 +1009,45 @@ Function signature:
(dissoc ([tbl]) ([tbl key]) ([tbl key & keys]))
```
-Remove `key` from table `tbl`.
+Remove `key` from table `tbl`. Optionally takes more `keys`.
## `remove-method`
Function signature:
```
-(remove-method ([multifn dispatch-val]))
+(remove-method ([multimethod dispatch-value]))
```
-Remove method from `multifn` for given `dispatch-val`.
+Remove method from `multimethod` for given `dispatch-value`.
## `remove-all-methods`
Function signature:
```
-(remove-all-methods ([multifn]))
+(remove-all-methods ([multimethod]))
```
-Removes all of the methods of multimethod
+Removes all of the methods of `multimethod`
## `methods`
Function signature:
```
-(methods ([multifn]))
+(methods ([multimethod]))
```
-Given a multimethod, returns a map of dispatch values -> dispatch fns
+Given a `multimethod`, returns a map of dispatch values -> dispatch fns
## `get-method`
Function signature:
```
-(get-method ([multifn dispatch-val]))
+(get-method ([multimethod dispatch-value]))
```
-Given a multimethod and a dispatch value, returns the dispatch `fn`
-that would apply to that value, or `nil` if none apply and no default.
+Given a `multimethod` and a `dispatch-value`, returns the dispatch
+`fn` that would apply to that value, or `nil` if none apply and no
+default.
## `ordered-set`
Function signature:
@@ -1133,9 +1132,9 @@ and are compared for having the same keys without particular order and
same size:
``` fennel
-(assert (= (ordered-set :a :b) (ordered-set :b :a)))
-(assert (not= (ordered-set :a :b) (ordered-set :b :a :c)))
-(assert (= (ordered-set :a :b) (hash-set :a :b)))
+(assert-eq (ordered-set :a :b) (ordered-set :b :a))
+(assert-ne (ordered-set :a :b) (ordered-set :b :a :c))
+(assert-eq (ordered-set :a :b) (hash-set :a :b))
```
## `hash-set`
@@ -1168,5 +1167,5 @@ Copyright (C) 2020 Andrey Orst
License: [MIT](https://gitlab.com/andreyorst/fennel-cljlib/-/raw/master/LICENSE)
-<!-- Generated with Fenneldoc 0.0.7
+<!-- Generated with Fenneldoc 0.1.0
https://gitlab.com/andreyorst/fenneldoc -->
diff --git a/doc/macros.md b/doc/macros.md
index 1841b14..f1efa48 100644
--- a/doc/macros.md
+++ b/doc/macros.md
@@ -1,4 +1,4 @@
-# Macros.fnl (0.3.0)
+# Macros.fnl (0.4.0)
Macros for Cljlib that implement various facilities from Clojure.
**Table of contents**
@@ -27,7 +27,10 @@ Function signature:
```
Create (anonymous) function of fixed arity.
-Supports multiple arities by defining bodies as lists.
+Accepts optional `name` and `docstring?` as first two arguments,
+followed by single or multiple arity bodies defined as lists. Each
+list starts with `arglist*` vector, which supports destructuring, and
+is followed by `body*` wrapped in implicit `do`.
### Examples
Named function of fixed arity 2:
@@ -136,12 +139,12 @@ namespace tables:
([t1 t2 & tables]
(join (join t1 t2) ((or table.unpack _G.unpack) tables)))) ;; call to `join` resolves to ns.tables.join
-(ns.strings.join "a" "b" "c")
-;; => abc
-(join ["a"] ["b"] ["c"] ["d" "e"])
-;; => ["a" "b" "c" "d" "e"]
-(join "a" "b" "c")
-;; {}
+(assert-eq (ns.strings.join "a" "b" "c") "abc")
+
+(assert-eq (join ["a"] ["b"] ["c"] ["d" "e"])
+ ["a" "b" "c" "d" "e"])
+(assert-eq (join "a" "b" "c")
+ [])
```
Note that this creates a collision and local `join` overrides `join`
@@ -159,10 +162,12 @@ General purpose try/catch/finally macro.
Wraps its body in `pcall` and checks the return value with `match`
macro.
-Catch clause is written either as (catch symbol body*), thus acting as
-catch-all, or (catch value body*) for catching specific errors. It is
-possible to have several `catch` clauses. If no `catch` clauses
-specified, an implicit catch-all clause is created.
+Catch clause is written either as `(catch symbol body*)`, thus acting
+as catch-all, or `(catch value body*)` for catching specific errors.
+It is possible to have several `catch` clauses. If no `catch` clauses
+specified, an implicit catch-all clause is created. `body*`, and
+inner expressions of `catch-clause*`, and `finally-clause?` are
+wrapped in implicit `do`.
Finally clause is optional, and written as (finally body*). If
present, it must be the last clause in the `try` form, and the only
@@ -184,36 +189,36 @@ Catch all errors, ignore those and return fallback value:
(+ x y)
(catch _ 0)))
-(add nil 1) ;; => 0
+(assert-eq (add nil 1) 0)
```
Catch error and do cleanup:
``` fennel
-(let [tbl []]
- (try
- (table.insert tbl "a")
- (table.insert tbl "b" "c")
- (catch _
- (each [k _ (pairs tbl)]
- (tset tbl k nil))))
- tbl)
-;; => {}
+(local tbl [])
+
+(try
+ (table.insert tbl "a")
+ (table.insert tbl "b" "c")
+ (catch _
+ (each [k _ (pairs tbl)]
+ (tset tbl k nil))))
+
+(assert-eq (length tbl) 0)
+
```
Always run some side effect action:
``` fennel
-(local res (try 10 (finally (print "side-effect!"))))
-;; => side-effect!
-;; => nil
-res
-;; => 10
-(local res (try (error 10) (catch 10 nil) (finally (print "side-effect!"))))
-;; => side-effect!
-;; => nil
-res
-;; => nil
+(local t [])
+(local res (try 10 (finally (table.insert t :finally))))
+(assert-eq (. t 1) :finally)
+(assert-eq res 10)
+
+(local res (try (error 10) (catch 10 nil) (finally (table.insert t :again))))
+(assert-eq (. t 2) :again)
+(assert-eq res nil)
```
@@ -224,15 +229,22 @@ Function signature:
(def attr-map? name expr)
```
-Wrapper around `local` which can
-declare variables inside namespace, and as local at the same time
-similarly to [`fn*`](#fn*):
+Wrapper around `local` which can declare variables inside namespace,
+and as local `name` at the same time similarly to
+[`fn*`](#fn*). Accepts optional `attr-map?` which can contain a
+docstring, and whether variable should be mutable or not. Sets
+variable to the result of `expr`.
``` fennel
(def ns {})
(def a 10) ;; binds `a` to `10`
+(assert-eq a 10)
+
(def ns.b 20) ;; binds `ns.b` and `b` to `20`
+
+(assert-eq b 20)
+(assert-eq ns.b 20)
```
`a` is a `local`, and both `ns.b` and `b` refer to the same value.
@@ -263,42 +275,48 @@ Function signature:
```
Works the same as [`def`](#def), but ensures that later `defonce`
-calls will not override existing bindings:
+calls will not override existing bindings. Accepts same `attr-map?` as
+`def`, and sets `name` to the result of `expr`:
``` fennel
(defonce a 10)
(defonce a 20)
-(print a) ;; => prints 10
+(assert-eq a 10)
```
## `defmulti`
Function signature:
```
-(defmulti name docstring? dispatch-fn attr-map?)
+(defmulti name docstring? dispatch-fn options*)
```
-Create multifunction with
-runtime dispatching based on results from `dispatch-fn`. Returns an
-empty table with `__call` metamethod, that calls `dispatch-fn` on its
-arguments. Amount of arguments passed, should be the same as accepted
-by `dispatch-fn`. Looks for multimethod based on result from
-`dispatch-fn`.
+Create multifunction `name` with runtime dispatching based on results
+from `dispatch-fn`. Returns a proxy table with `__call` metamethod,
+that calls `dispatch-fn` on its arguments. Amount of arguments
+passed, should be the same as accepted by `dispatch-fn`. Looks for
+multimethod based on result from `dispatch-fn`.
+
+Accepts optional `docstring?`, and `options*` arguments, where
+`options*` is a sequence of key value pairs representing additional
+attributes. Supported options:
+
+`:default` - the default dispatch value, defaults to `:default`.
By default, multifunction has no multimethods, see
-[`multimethod`](#multimethod) on how to add one.
+[`defmethod`](#defmethod) on how to add one.
## `defmethod`
Function signature:
```
-(defmethod multifn dispatch-val fnspec)
+(defmethod multi-fn dispatch-value fnspec)
```
-Attach new method to multi-function dispatch value. accepts the `multi-fn`
-as its first argument, the dispatch value as second, and function tail
-starting from argument list, followed by function body as in
-[`fn*`](#fn).
+Attach new method to multi-function dispatch value. accepts the
+`multi-fn` as its first argument, the `dispatch-value` as second, and
+`fnspec` - a function tail starting from argument list, followed by
+function body as in [`fn*`](#fn).
### Examples
Here are some examples how multimethods can be used.
@@ -315,7 +333,7 @@ to another multimethod:
(defmethod fac 0 [_] 1)
(defmethod fac :default [x] (* x (fac (- x 1))))
-(fac 4) ;; => 24
+(assert-eq (fac 4) 24)
```
`:default` is a special method which gets called when no other methods
@@ -348,22 +366,30 @@ tables to Lua's one:
(defmulti to-lua-str (fn [x] (type x)))
(defmethod to-lua-str :number [x] (tostring x))
-(defmethod to-lua-str :table [x] (let [res []]
- (each [k v (pairs x)]
- (table.insert res (.. "[" (to-lua-str k) "] = " (to-lua-str v))))
- (.. "{" (table.concat res ", ") "}")))
+(defmethod to-lua-str :table [x]
+ (let [res []]
+ (each [k v (pairs x)]
+ (table.insert res (.. "[" (to-lua-str k) "] = " (to-lua-str v))))
+ (.. "{" (table.concat res ", ") "}")))
(defmethod to-lua-str :string [x] (.. "\"" x "\""))
(defmethod to-lua-str :default [x] (tostring x))
-(print (to-lua-str {:a {:b 10}}))
-;; => {["a"] = {["b"] = 10}}
+(assert-eq (to-lua-str {:a {:b 10}}) "{[\"a\"] = {[\"b\"] = 10}}")
-(print (to-lua-str [:a :b :c [:d {:e :f}]]))
-;; => {[1] = "a", [2] = "b", [3] = "c", [4] = {[1] = "d", [2] = {["e"] = "f"}}}
+(assert-eq (to-lua-str [:a :b :c [:d {:e :f}]])
+ "{[1] = \"a\", [2] = \"b\", [3] = \"c\", [4] = {[1] = \"d\", [2] = {[\"e\"] = \"f\"}}}")
```
And if we call it on some table, we'll get a valid Lua table, which we
-can then reformat as we want and use in Lua if we want.
+can then reformat as we want and use in Lua.
+
+All of this can be done with functions, and single entry point
+function, that uses if statement and branches on the type, however one
+of the additional features of multimethods, is that separate libraries
+can extend such multimethod by adding additional claues to it without
+needing to patch the source of the function. For example later on
+support for userdata or coroutines can be added to `to-lua-str`
+function as a separate multimethods for respective types.
## `into`
Function signature:
@@ -372,7 +398,7 @@ Function signature:
(into to from)
```
-Transform one table into another. Mutates first table.
+Transform table `from` into another table `to`. Mutates first table.
Transformation happens in runtime, but type deduction happens in
compile time if possible. This means, that if literal values passed
@@ -380,15 +406,15 @@ to `into` this will have different effects for associative tables and
vectors:
``` fennel
-(into [1 2 3] [4 5 6]) ;; => [1 2 3 4 5 6]
-(into {:a 1 :c 2} {:a 0 :b 1}) ;; => {:a 0 :b 1 :c 2}
+(assert-eq (into [1 2 3] [4 5 6]) [1 2 3 4 5 6])
+(assert-eq (into {:a 1 :c 2} {:a 0 :b 1}) {:a 0 :b 1 :c 2})
```
Conversion between different table types is also supported:
``` fennel
-(into [] {:a 1 :b 2 :c 3}) ;; => [[:a 1] [:b 2] [:c 3]]
-(into {} [[:a 1] [:b 2]]) ;; => {:a 1 :b 2}
+(assert-eq (into [] {:a 1}) [[:a 1]])
+(assert-eq (into {} [[:a 1] [:b 2]]) {:a 1 :b 2})
```
Same rules apply to runtime detection of table type, except that this
@@ -396,7 +422,7 @@ will not work for empty tables:
``` fennel
(local empty-table {})
-(into empty-table {:a 1 :b 2}) ;; => [[:a 1] [:b 2]]
+(assert-eq (into empty-table {:a 1}) [[:a 1]])
``` fennel
If table is empty, `into` defaults to sequential table, because it
@@ -408,8 +434,8 @@ runtime, and this works as expected:
``` fennel
(local t1 [1 2 3])
(local t2 {:a 10 :c 3})
-(into t1 {:a 1 :b 2}) ;; => [1 2 3 [:a 1] [:b 2]]
-(into t2 {:a 1 :b 2}) ;; => {:a 1 :b 2 :c 3}
+(assert-eq (into t1 {:a 1}) [1 2 3 [:a 1]])
+(assert-eq (into t2 {:a 1}) {:a 1 :c 3})
```
`cljlib.fnl` module provides two additional functions `vector` and
@@ -417,8 +443,8 @@ runtime, and this works as expected:
at runtime:
``` fennel
-(into (vector) {:a 1 :b 2}) ;; => [[:a 1] [:b 2]]
-(into (hash-map) [[:a 1 :b 2]]) ;; => {:a 1 :b 2}
+(assert-eq (into (vector) {:a 1}) [[:a 1]])
+(assert-eq (into (hash-map) [[:a 1] [:b 2]]) {:a 1 :b 2})
```
## `empty`
@@ -442,10 +468,10 @@ and return result of the same type:
(table.insert res (f v)))
(into (empty tbl) res)))
-(map (fn [[k v]] [(string.upper k) v]) {:a 1 :b 2 :c 3})
-;; => {:A 1 :B 2 :C 3}
-(map #(* $ $) [1 2 3 4])
-;; [1 4 9 16]
+(assert-eq (map (fn [[k v]] [(string.upper k) v]) {:a 1 :b 2 :c 3})
+ {:A 1 :B 2 :C 3})
+(assert-eq (map #(* $ $) [1 2 3 4])
+ [1 4 9 16])
```
See [`into`](#into) for more info on how conversion is done.
@@ -456,11 +482,11 @@ Function signature:
(when-meta [& body])
```
-Wrapper that compiles away if metadata support was not enabled. What
-this effectively means, is that everything that is wrapped with this
-macro will disappear from the resulting Lua code if metadata is not
-enabled when compiling with `fennel --compile` without `--metadata`
-switch.
+Wrapper that compiles away if metadata support was not enabled.
+What this effectively means, is that everything that is wrapped with
+this macro and its `body` will disappear from the resulting Lua code
+if metadata is not enabled when compiling with `fennel --compile`
+without `--metadata` switch.
## `with-meta`
Function signature:
@@ -469,7 +495,7 @@ Function signature:
(with-meta value meta)
```
-Attach metadata to a value. When metadata feature is not enabled,
+Attach `meta` to a `value`. When metadata feature is not enabled,
returns the value without additional metadata.
``` fennel
@@ -526,9 +552,9 @@ Function signature:
(if-let [binding test] then-branch else-branch)
```
-If test is logical true,
-evaluates `then-branch` with binding-form bound to the value of test,
-if not, yields `else-branch`.
+If `binding` is set by `test` to logical true, evaluates `then-branch`
+with binding-form bound to the value of test, if not, yields
+`else-branch`.
## `when-let`
Function signature:
@@ -537,8 +563,8 @@ Function signature:
(when-let [binding test] & body)
```
-If test is logical true,
-evaluates `body` in implicit `do`.
+If `binding` was bound by `test` to logical true, evaluates `body` in
+implicit `do`.
## `if-some`
Function signature:
@@ -547,9 +573,8 @@ Function signature:
(if-some [binding test] then-branch else-branch)
```
-If test is non-`nil`, evaluates
-`then-branch` with binding-form bound to the value of test, if not,
-yields `else-branch`.
+If `test` is non-`nil`, evaluates `then-branch` with `binding`-form bound
+to the value of test, if not, yields `else-branch`.
## `when-some`
Function signature:
@@ -558,8 +583,8 @@ Function signature:
(when-some [binding test] & body)
```
-If test is non-`nil`,
-evaluates `body` in implicit `do`.
+If `test` sets `binding` to non-`nil`, evaluates `body` in implicit
+`do`.
---
@@ -569,5 +594,5 @@ Copyright (C) 2020 Andrey Orst
License: [MIT](https://gitlab.com/andreyorst/fennel-cljlib/-/raw/master/LICENSE)
-<!-- Generated with Fenneldoc 0.0.7
+<!-- Generated with Fenneldoc 0.1.0
https://gitlab.com/andreyorst/fenneldoc -->
diff --git a/doc/tests/test.md b/doc/tests/test.md
index 8a6c7e5..f9d8ae9 100644
--- a/doc/tests/test.md
+++ b/doc/tests/test.md
@@ -16,7 +16,7 @@ Function signature:
(deftest name ...)
```
-Simple way of grouping tests.
+Simple way of grouping tests with `name`.
## `testing`
Function signature:
@@ -25,7 +25,7 @@ Function signature:
(testing description ...)
```
-Print test description and run it.
+Print test `description` and run it.
## `assert-eq`
Function signature:
@@ -34,30 +34,26 @@ Function signature:
(assert-eq expr1 expr2 msg)
```
-Like `assert`, except compares results of two expressions on equality.
+Like `assert`, except compares results of `expr1` and `expr2` for equality.
Generates formatted message if `msg` is not set to other message.
### Example
Compare two expressions:
``` fennel
->> (assert-eq 1 (+1 1))
-runtime error: equality assertion failed
- Left: 1
- Right: 3
+;; (assert-eq 1 (+1 1))
+;; => runtime error: equality assertion failed
+;; => Left: 1
+;; => Right: 3
```
Deep compare values:
``` fennel
->> (assert-eq [1 {[2 3] [4 5 6]}] [1 {[2 3] [4 5]}])
-runtime error: equality assertion failed
- Left: [1 {
- [2 3] [4 5 6]
- }]
- Right: [1 {
- [2 3] [4 5]
- }]
+;; (assert-eq [1 {[2 3] [4 5 6]}] [1 {[2 3] [4 5]}])
+;; => runtime error: equality assertion failed
+;; => Left: [1 {[2 3] [4 5 6]}]
+;; => Right: [1 {[2 3] [4 5]}]
```
## `assert-ne`
@@ -67,7 +63,9 @@ Function signature:
(assert-ne expr1 expr2 msg)
```
-Assert for unequality. Same as [`assert-eq`](#assert-eq).
+Assert for unequality. Like `assert`, except compares results of
+`expr1` and `expr2` for equality. Generates formatted message if
+`msg` is not set to other message. Same as [`assert-eq`](#assert-eq).
## `assert-is`
Function signature:
@@ -76,12 +74,12 @@ Function signature:
(assert-is expr msg)
```
-Assert for truth. Same as inbuilt `assert`, except generates more
+Assert `expr` for truth. Same as inbuilt `assert`, except generates more
verbose message if `msg` is not set.
``` fennel
->> (assert-is (= 1 2 3))
-runtime error: assertion failed for (= 1 2 3)
+;; (assert-is (= 1 2 3))
+;; => runtime error: assertion failed for (= 1 2 3)
```
## `assert-not`
@@ -91,8 +89,9 @@ Function signature:
(assert-not expr msg)
```
-Assert for not truth. Works the same as [`assert-is`](#assert-is).
+Assert `expr` for not truth. Generates more verbose message if
+ `msg` is not set. Works the same as [`assert-is`](#assert-is).
-<!-- Generated with Fenneldoc 0.0.7
+<!-- Generated with Fenneldoc 0.1.0
https://gitlab.com/andreyorst/fenneldoc -->