This is my racket library. Nothing too interesting here yet, just a few things to make me feel comfortable in this Lisp.
functional/monads provides a few simple monads and a mlet* for for
simulating Haskell do notation. This is pretty similar to my
implementation of monadic binding in Emacs.
utilities/fancy-destructuring provides a clojure-like destructuring
bind suite with dlet*, defn and fn. This tries to be more
Scheme flavored than the Elisp version, and its built up on top of
hygienic macros.
This implementation of destructuring bind can bind symbols, lists, or
racket "dicts" in the racket/dict module. It looks like this:
(dlet* ((x 10)) x)
x here is bound to ten. When sumbols appear on the right hand side
of each binding expression, dlet* is identical to let*. However,
dlet* extends the binding abilities of let* to include
destructuring. For example:
(dlet* (((: a b c) (list 1 2 3)))
(+ a b c))
is 6. The : sigil indicates that we want to destructure a list
into three variables a, b, and c. Destructuring can be nested
arbitrarily. We can destructure a list within a list as so:
(dlet* (((: (: a b) c) (list (list 1 2) 3)))
(+ a b c))
is also 6.
fancy-destructuring also supports destructuring anything which is a
dict in accordance with Racket's racket/dict library. This covers
structs, various kinds of hash tables, and association lists. Dict
destructuring is introduced with the :> sigil:
(dlet* (((:> x 'a y 'b) '((a . 10) (b . 11))))
(list x y))
evaluates to: (10 11). You can nest destructuring expressions for
lists or tables anywhere a symbol is expected above.
If an item is not in the data structure to be destructured, then the
variable corresponding to that item is bound to unbound.
It is useful to have a way of binding where default values are supported. This library uses decorated sigils to accomplish this task:
(dlet* ((((: or '(1 2 3)) a b c)
(list 10 11)))
(list a b c))
evaluates to: (10 11 3) because the provided list is too short to
provide all the bindings.
It is also useful to bind the structure itself occasionally. This is
supported with the as sigil decoration:
(dlet* ((((:> as table) a 'x)
'((x . 10))))
(list table a))
evaluates to ( ((x . 10)) 10). as causes the input table to be
bound directly to the provided name. as and or can be used
together and specified in any order.
It is nice to have this destructuring for function definition argument
lists, so the library provides defn and fn forms which use these
features to destructure their arguments.
(defn (add-three-list (: a b c))
(+ a b c))
Takes a list with at least three arguments and adds them together. Pretty useful!