summaryrefslogtreecommitdiff
path: root/doc/0.1.0
diff options
context:
space:
mode:
Diffstat (limited to 'doc/0.1.0')
-rw-r--r--doc/0.1.0/cljlib-macros.md288
-rw-r--r--doc/0.1.0/cljlib.md674
2 files changed, 962 insertions, 0 deletions
diff --git a/doc/0.1.0/cljlib-macros.md b/doc/0.1.0/cljlib-macros.md
new file mode 100644
index 0000000..d99dad6
--- /dev/null
+++ b/doc/0.1.0/cljlib-macros.md
@@ -0,0 +1,288 @@
+# Cljlib-macros.fnl
+Macro module for Fennel Cljlib.
+
+## Metadata macros
+Metadata in Fennel is a pretty tough subject, as there's no such thing as metadata in Lua.
+Therefore, the metadata usage in Fennel is more limited compared to Clojure.
+This library provides some facilities for metadata management, which are experimental and should be used with care.
+
+There are several important gotchas about using metadata.
+
+First, note that this works only when used with Fennel, and only when `(require fennel)` works.
+For compiled Lua library this feature is turned off.
+
+Second, try to avoid using metadata with anything else than tables and functions.
+When storing function or table as a key into metatable, its address is used, while when storing string of number, the value is used.
+This, for example, may cause documentation collision, when you've set some variable holding a number value to have certain docstring, and later you've defined another variable with the same value, but different docstring.
+While this isn't a major breakage, it may confuse if someone will explore your code in the REPL with `doc`.
+
+Lastly, note that prior to Fennel 0.7.1 `import-macros` wasn't respecting `--metadata` switch.
+So if you're using Fennel < 0.7.1 this stuff will only work if you use `require-macros` instead of `import-macros`.
+
+
+### `when-meta`
+This macros is a 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`.
+
+
+### `with-meta`
+Attach metadata to a value.
+
+ >> (local foo (with-meta (fn [...] (let [[x y z] [...]] (+ x y z)))
+ {:fnl/arglist [:x :y :z :...]
+ :fnl/docstring "sum first three values"}))
+ >> (doc foo)
+ (foo x y z ...)
+ sum first three values
+
+When metadata feature is not enabled, returns the value without additional metadata.
+
+
+### `meta`
+Get metadata table from object:
+
+ >> (meta (with-meta {} {:meta "data"}))
+ {
+ :meta "data"
+ }
+
+
+## `def` and `defonce`
+`def` is wrappers around `local` which can declare variables inside namespace, and as local at the same time:
+
+ >> (def ns {})
+ >> (def a 10)
+ >> a
+ 10
+ >> (def ns.a 20)
+ >> a
+ 20
+ >> ns.a
+ 20
+
+Both `ns.a` and `a` refer to the same value.
+
+`defonce` ensures that the binding isn't overridden by another `defonce`:
+
+ >> (defonce ns {})
+ >> (defonce ns.a 42)
+ >> (defonce ns 10)
+ >> ns
+ {:a 42}
+ >> a
+ 42
+
+Both `def` and `defonce` support literal metadata table as first argument, or a :dynamic keyword, that uses Fennel `var` instead of `local`:
+
+ >> (def {:dynamic true} a 10)
+ >> (set a 20)
+ >> a
+ 20
+ >> (defonce :dynamic b 40)
+ >> (set b 42)
+ >> b
+ 42
+
+Documentation string can be attached to value via `:doc` keyword.
+However it is not recommended to attach metadata to everything except tables and functions:
+
+ ;; Bad, may overlap with existing documentation for 299792458, if any
+ >> (def {:doc "The speed of light in m/s"} c 299792458)
+ >> (doc c)
+ c
+ The speed of light in m/s
+
+ ;; OK
+ >> (def {:doc "default connection options"}
+ defaults {:port 1234
+ :host localhost})
+
+
+## `fn*`
+Clojure's `fn` equivalent.
+Returns a function of fixed amount of arguments by doing runtime dispatch based on argument count.
+Capable of producing multi-arity functions:
+
+ (fn* square "square number" [x] (^ x 2))
+
+ (square 9) ;; => 81.0
+ (square 1 2) ;; => error
+
+ (fn* range
+ "Returns increasing sequence of numbers from `lower' to `upper'.
+ If `lower' is not provided, sequence starts from zero.
+ Accepts optional `step'"
+ ([upper] (range 0 upper 1))
+ ([lower upper] (range lower upper 1))
+ ([lower upper step]
+ (let [res []]
+ (for [i lower (- upper step) step]
+ (table.insert res i))
+ res)))
+
+ (range 10) ;; => [0 1 2 3 4 5 6 7 8 9]
+ (range -10 0) ;; => [-10 -9 -8 -7 -6 -5 -4 -3 -2 -1]
+ (range 0 1 0.2) ;; => [0.0 0.2 0.4 0.6 0.8]
+
+Both variants support up to one arity with `& more`:
+
+ (fn* vec [& xs] xs)
+
+ (vec 1 2 3) ;; => [1 2 3]
+
+ (fn* add
+ "sum two or more values"
+ ([] 0)
+ ([a] a)
+ ([a b] (+ a b))
+ ([a b & more] (add (+ a b) (unpack more))))
+
+ (add) ;; => 0
+ (add 1) ;; => 1
+ (add 1 2) ;; => 3
+ (add 1 2 3 4) ;; => 10
+
+One extra capability of `fn*` supports the same semantic as `def` regarding namespaces:
+
+ (local ns {})
+
+ (fn* ns.plus
+ ([] 0)
+ ([x] x)
+ ([x y] (+ x y))
+ ([x y & zs] (apply plus (+ x y) zs)))
+
+ ns
+
+Note, that `plus` is used without `ns` part, e.g. not `ns.plus`.
+If we `require` this code from file in the REPL, we will see that our `ns` has single function `plus`:
+
+ >> (local ns (require :module))
+ >> ns
+ {add #<function 0xbada55code>}
+
+This is possible because `fn*` separates the namespace part from the function name, and creates a `local` variable with the same name as function, then defines the function within lexical scope of `do`, sets `namespace.foo` to it and returns the function object to the outer scope.
+
+ (local plus
+ (do (fn plus [...]
+ ;; plus body
+ )
+ (set ns.plus plus)
+ plus))
+
+See `core.fnl` for more examples.
+
+
+## `fn+`
+Works similarly to Fennel's `fn`, by creating ordinary function without arity semantics, except does the namespace automation like `fn*`, and has the same order of arguments as the latter:
+
+ (local ns {})
+
+ ;; module & file-local functions
+ (fn+ ns.double
+ "double the number"
+ [x]
+ (* x 2))
+
+ (fn+ ns.triple
+ [x]
+ (* x 3))
+
+ ;; no namespace, file-local function
+ (fn+ quadruple
+ [x]
+ (* x 4))
+
+ ;; anonymous file-local function
+ (fn+ [x] (* x 5))
+
+ ns
+
+See `core.fnl` for more examples.
+
+
+## `if-let` and `when-let`
+When test expression is not `nil` or `false`, evaluates the first body form with the `name` bound to the result of the expressions.
+
+ (if-let [val (test)]
+ (print val)
+ :fail)
+
+Expanded form:
+
+ (let [tmp (test)]
+ (if tmp
+ (let [val tmp]
+ (print val))
+ :fail))
+
+`when-let` is mostly the same, except doesn't have false branch and accepts any amount of forms:
+
+ (when-let [val (test)]
+ (print val)
+ val)
+
+Expanded form:
+
+ (let [tmp (test)]
+ (if tmp
+ (let [val tmp]
+ (print val)
+ val)))
+
+
+## `if-some` and `when-some`
+Much like `if-let` and `when-let`, except tests expression for not being `nil`.
+
+ (when-some [val (foo)]
+ (print (.. "val is not nil: " val))
+ val)
+
+
+## `into`
+Clojure's `into` function is implemented as macro, because Fennel has no runtime distinction between `[]` and `{}` tables, since Lua also doesn't feature this feature.
+However we can do this at compile time.
+
+ (into [1 2 3] [4 5 6]) ;; => [1 2 3 4 5 6]
+ (into [] {:a 1 :b 2 :c 3 :d 4}) ;; => [["d" 4] ["a" 1] ["b" 2] ["c" 3]]
+ (into {} [[:d 4] [:a 1] [:b 2] [:c 3]]) ;; => {:a 1 :b 2 :c 3 :d 4}
+ (into {:a 0 :e 5} {:a 1 :b 2 :c 3 :d 4}) ;; => {:a 1 :b 2 :c 3 :d 4 :e 5}
+
+Because the type check at compile time it will only respect the type when literal representation is used.
+If a variable holding the table, its type is checked at runtime.
+Empty tables default to sequential ones:
+
+ (local a [])
+ (into a {:a 1 :b 2}) ;; => [["b" 2] ["a" 1]]
+
+ (local b {})
+ (into b {:a 1 :b 2}) ;; => [["b" 2] ["a" 1]]
+
+However, if target table is not empty, its type can be deduced:
+
+ (local a {:c 3})
+ (into a {:a 1 :b 2}) ;; => {:a 1 :b 2 :c 3}
+
+ (local b [1])
+ (into b {:a 1 :b 2}) ;; => [1 ["b" 2] ["a" 1]]
+
+Note that when converting associative table into sequential table order is determined by the `pairs` function.
+Also note that if variable stores the table has both integer key 1, and other associative keys, the type will be the same as of sequential table.
+
+
+## `defmulti` and `defmethod`
+A bit more simple implementations of Clojure's `defmulti` and `defmethod`.
+`defmulti` macros returns an empty table with `__call` metamethod, that calls dispatching function on its arguments.
+Methods are defined inside `multimethods` table, which is also stored in the metatable.
+
+`defmethod` adds a new method to the metatable of given `multifn`.
+It accepts the multi-fn table as its first argument, the dispatch value as second, and Fennel's arglist followed by the body:
+
+ (defmulti fac (fn [x] x))
+
+ (defmethod fac 0 [_] 1)
+ (defmethod fac :default [x] (* x (fac (- x 1))))
+
+ (fac 4) ;; => 24
+
+`:default` is a special method which gets called when no other methods were found for given dispatch value.
diff --git a/doc/0.1.0/cljlib.md b/doc/0.1.0/cljlib.md
new file mode 100644
index 0000000..1226591
--- /dev/null
+++ b/doc/0.1.0/cljlib.md
@@ -0,0 +1,674 @@
+# Cljlib.fnl
+Fennel-cljlib - functions from Clojure's core.clj implemented on top of Fennel.
+
+Documentation for version: 0.1.0
+
+## `add`
+Function signature:
+
+```
+(add
+ ([a])
+ ([a b])
+ ([a b c])
+ ([a b c d])
+ ([a b c d & rest]))
+```
+
+Sum arbitrary amount of numbers.
+
+## `apply`
+Function signature:
+
+```
+(apply
+ ([f args])
+ ([f a args])
+ ([f a b args])
+ ([f a b c args])
+ ([f a b c d & args]))
+```
+
+Apply `f` to the argument list formed by prepending intervening
+arguments to `args`.
+
+## `assoc`
+Function signature:
+
+```
+(assoc
+ ([tbl k v])
+ ([tbl k v & kvs]))
+```
+
+Associate key `k` with value `v` in `tbl`.
+
+## `boolean?`
+Function signature:
+
+```
+(boolean? [x])
+```
+
+Test if `x` is a Boolean
+
+## `butlast`
+Function signature:
+
+```
+(butlast [col])
+```
+
+Returns everything but the last element of a table as a new
+ table. Calls `seq` on its argument.
+
+## `comp`
+Function signature:
+
+```
+(comp
+ ([f])
+ ([f g])
+ ([f g & fs]))
+```
+
+Compose functions.
+
+## `complement`
+Function signature:
+
+```
+(complement [f])
+```
+
+Takes a function `f` and returns the function that takes the same
+amount of arguments as `f`, has the same effect, and returns the
+oppisite truth value.
+
+## `concat`
+Function signature:
+
+```
+(concat
+ ([x])
+ ([x y])
+ ([x y & xs]))
+```
+
+Concatenate tables.
+
+## `conj`
+Function signature:
+
+```
+(conj
+ ([tbl])
+ ([tbl x])
+ ([tbl x & xs]))
+```
+
+Insert `x` as a last element of indexed table `tbl`. Modifies `tbl`
+
+## `cons`
+Function signature:
+
+```
+(cons [x tbl])
+```
+
+Insert `x` to `tbl` at the front. Modifies `tbl`.
+
+## `constantly`
+Function signature:
+
+```
+(constantly [x])
+```
+
+Returns a function that takes any number of arguments and returns `x`.
+
+## `dec`
+Function signature:
+
+```
+(dec [x])
+```
+
+Decrease number by one
+
+## `div`
+Function signature:
+
+```
+(div
+ ([a])
+ ([a b])
+ ([a b c])
+ ([a b c d])
+ ([a b c d & rest]))
+```
+
+Divide arbitrary amount of numbers.
+
+## `double?`
+Function signature:
+
+```
+(double? [x])
+```
+
+Test if `x` is a number with floating point data.
+
+## `empty?`
+Function signature:
+
+```
+(empty? [x])
+```
+
+Check if collection is empty.
+
+## `eq`
+Function signature:
+
+```
+(eq
+ ([x])
+ ([x y])
+ ([x y & xs]))
+```
+
+Deep compare values.
+
+## `even?`
+Function signature:
+
+```
+(even? [x])
+```
+
+Test if value is even.
+
+## `every?`
+Function signature:
+
+```
+(every? [pred tbl])
+```
+
+Test if every item in `tbl` satisfies the `pred`.
+
+## `false?`
+Function signature:
+
+```
+(false? [x])
+```
+
+Test if `x` is `false`
+
+## `filter`
+Function signature:
+
+```
+(filter [pred col])
+```
+
+Returns a sequential table of the items in `col` for which `pred`
+ returns logical true.
+
+## `first`
+Function signature:
+
+```
+(first [col])
+```
+
+Return first element of a table. Calls `seq` on its argument.
+
+## `ge`
+Function signature:
+
+```
+(ge
+ ([x])
+ ([x y])
+ ([x y & more]))
+```
+
+Returns true if nums are in monotonically non-increasing order
+
+## `get`
+Function signature:
+
+```
+(get
+ ([tbl key])
+ ([tbl key not-found]))
+```
+
+Get value from the table by accessing it with a `key`.
+Accepts additional `not-found` as a marker to return if value wasn't
+found in the table.
+
+## `get-in`
+Function signature:
+
+```
+(get-in
+ ([tbl keys])
+ ([tbl keys not-found]))
+```
+
+Get value from nested set of tables by providing key sequence.
+Accepts additional `not-found` as a marker to return if value wasn't
+found in the table.
+
+## `get-method`
+Function signature:
+
+```
+(get-method [multifn dispatch-val])
+```
+
+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.
+
+## `gt`
+Function signature:
+
+```
+(gt
+ ([x])
+ ([x y])
+ ([x y & more]))
+```
+
+Returns true if nums are in monotonically increasing order
+
+## `hash-map`
+Function signature:
+
+```
+(hash-map
+ ([& kvs]))
+```
+
+Create associative table from keys and values
+
+## `identity`
+Function signature:
+
+```
+(identity [x])
+```
+
+Returns its argument.
+
+## `inc`
+Function signature:
+
+```
+(inc [x])
+```
+
+Increase number by one
+
+## `int?`
+Function signature:
+
+```
+(int? [x])
+```
+
+Test if `x` is a number without floating point data.
+
+## `kvseq`
+Function signature:
+
+```
+(kvseq [tbl])
+```
+
+Transforms any table kind to key-value sequence.
+
+## `last`
+Function signature:
+
+```
+(last [col])
+```
+
+Returns the last element of a table. Calls `seq` on its argument.
+
+## `le`
+Function signature:
+
+```
+(le
+ ([x])
+ ([x y])
+ ([x y & more]))
+```
+
+Returns true if nums are in monotonically non-decreasing order
+
+## `lt`
+Function signature:
+
+```
+(lt
+ ([x])
+ ([x y])
+ ([x y & more]))
+```
+
+Returns true if nums are in monotonically decreasing order
+
+## `map?`
+Function signature:
+
+```
+(map? [tbl])
+```
+
+Check whether `tbl` is an associative table.
+
+## `mapv`
+Function signature:
+
+```
+(mapv
+ ([f col])
+ ([f col1 col2])
+ ([f col1 col2 col3])
+ ([f col1 col2 col3 & cols]))
+```
+
+Maps function `f` over one or more collections.
+
+Accepts arbitrary amount of tables, calls `seq` on each of it.
+Function `f` must take the same amount of parameters as the amount of
+tables passed to `mapv`. Applies `f` over first value of each
+table. Then applies `f` to second value of each table. Continues until
+any of the tables is exhausted. All remaining values are
+ignored. Returns a table of results.
+
+## `memoize`
+Function signature:
+
+```
+(memoize [f])
+```
+
+Returns a memoized version of a referentially transparent function.
+The memoized version of the function keeps a cache of the mapping from
+arguments to results and, when calls with the same arguments are
+repeated often, has higher performance at the expense of higher memory
+use.
+
+## `methods`
+Function signature:
+
+```
+(methods [multifn])
+```
+
+Given a multimethod, returns a map of dispatch values -> dispatch fns
+
+## `mul`
+Function signature:
+
+```
+(mul
+ ([a])
+ ([a b])
+ ([a b c])
+ ([a b c d])
+ ([a b c d & rest]))
+```
+
+Multiply arbitrary amount of numbers.
+
+## `neg-int?`
+Function signature:
+
+```
+(neg-int? [x])
+```
+
+Test if `x` is a negetive integer.
+
+## `neg?`
+Function signature:
+
+```
+(neg? [x])
+```
+
+Test if `x` is less than zero.
+
+## `nil?`
+Function signature:
+
+```
+(nil?
+ ([x]))
+```
+
+Test if value is nil.
+
+## `not-any?`
+Function signature:
+
+```
+(not-any? pred tbl)
+```
+
+Test if no item in `tbl` satisfy the `pred`.
+
+## `not-empty`
+Function signature:
+
+```
+(not-empty [x])
+```
+
+If `x` is empty, returns `nil`, otherwise `x`.
+
+## `odd?`
+Function signature:
+
+```
+(odd? [x])
+```
+
+Test if value is odd.
+
+## `pos-int?`
+Function signature:
+
+```
+(pos-int? [x])
+```
+
+Test if `x` is a positive integer.
+
+## `pos?`
+Function signature:
+
+```
+(pos? [x])
+```
+
+Test if `x` is greater than zero.
+
+## `range`
+Function signature:
+
+```
+(range
+ ([upper])
+ ([lower upper])
+ ([lower upper step]))
+```
+
+return range of of numbers from `lower` to `upper` with optional `step`.
+
+## `reduce`
+Function signature:
+
+```
+(reduce
+ ([f col])
+ ([f val col]))
+```
+
+Reduce collection `col` using function `f` and optional initial value `val`.
+
+`f` should be a function of 2 arguments. If val is not supplied,
+returns the result of applying f to the first 2 items in coll, then
+applying f to that result and the 3rd item, etc. If coll contains no
+items, f must accept no arguments as well, and reduce returns the
+result of calling f with no arguments. If coll has only 1 item, it is
+returned and f is not called. If val is supplied, returns the result
+of applying f to val and the first item in coll, then applying f to
+that result and the 2nd item, etc. If coll contains no items, returns
+val and f is not called. Calls `seq` on `col`.
+
+## `reduce-kv`
+Function signature:
+
+```
+(reduce-kv [f val col])
+```
+
+Reduces an associative table using function `f` and initial value `val`.
+
+`f` should be a function of 3 arguments. Returns the result of
+applying `f` to `val`, the first key and the first value in `coll`,
+then applying `f` to that result and the 2nd key and value, etc. If
+`coll` contains no entries, returns `val` and `f` is not called. Note
+that reduce-kv is supported on sequential tables and strings, where
+the keys will be the ordinals.
+
+## `remove-all-methods`
+Function signature:
+
+```
+(remove-all-methods [multifn])
+```
+
+Removes all of the methods of multimethod
+
+## `remove-method`
+Function signature:
+
+```
+(remove-method [multifn dispatch-val])
+```
+
+Remove method from `multifn` for given `dispatch-val`.
+
+## `rest`
+Function signature:
+
+```
+(rest [seq])
+```
+
+Returns table of all elements of a table but the first one. Calls
+ `seq` on its argument.
+
+## `reverse`
+Function signature:
+
+```
+(reverse [tbl])
+```
+
+Returns table with same items as in `tbl` but in reverse order.
+
+## `seq`
+Function signature:
+
+```
+(seq [col])
+```
+
+Create sequential table.
+Transforms original table to sequential table of key value pairs
+stored as sequential tables in linear time. If `col` is an
+associative table, returns `[[key1 value1] ... [keyN valueN]]` table.
+If `col` is sequential table, returns its shallow copy.
+
+## `seq?`
+Function signature:
+
+```
+(seq? [tbl])
+```
+
+Check whether `tbl` is an sequential table.
+
+## `some`
+Function signature:
+
+```
+(some [pred tbl])
+```
+
+Test if any item in `tbl` satisfies the `pred`.
+
+## `string?`
+Function signature:
+
+```
+(string? [x])
+```
+
+Test if `x` is a string.
+
+## `sub`
+Function signature:
+
+```
+(sub
+ ([a])
+ ([a b])
+ ([a b c])
+ ([a b c d])
+ ([a b c d & rest]))
+```
+
+Subtract arbitrary amount of numbers.
+
+## `true?`
+Function signature:
+
+```
+(true? [x])
+```
+
+Test if `x` is `true`
+
+## `vector`
+Function signature:
+
+```
+(vector [& args])
+```
+
+Constructs sequential table out of it's arguments.
+
+## `zero?`
+Function signature:
+
+```
+(zero? [x])
+```
+
+Test if value is zero.
+
+
+<!-- Generated with Fenneldoc 0.0.1--> \ No newline at end of file