Medley of utility macros for a more expressive idiomatic code
weavejester/medley specifically includes only functions so macros are explicitly excluded. This library intends to provide a home for all those macros that are very useful but self-contained and small enough not to be part of their own framework or purpose library.
Include this dependency in your Leiningen or Boot project.
[macro-medley 0.1.0]
Require the namespace as usual
(require '[macro-medley.core :refer :all])
Now you can use the library macros
A pattern you may have come across is this
(zipmap [:a :b :c] [a b c])
which is needed to build a map as an input to a map destructuring function (or build the map manually). The bindings are very often named identically to the input map's keys.
This set of functions remove the redundancy of having to reapeat the binding symbol as a keyword and reduces the boilerplate.
(let [a 1 b 2]
(selfmapk a))
yields {:a 1}
.
(let [a 1 b 2]
(selfmapk a b))
evaluates to {:a 1 :b 2}
Several flavours provided: the map's key types can be plain key, qualified key, string and symbol. For example, when using the following command within the REPL
(let [a 1 b 2]
(selfmapq a b))
we would get namespace-qualified keywords as map keys {:user/a 1 :user/b 2}
, assuming the current namespace is the default REPL namespace user
.
Despite having to decide what a multiple-binding when-let or if-let has to do, if evaluating the body if all, some, the first or the last binding is not falsey, these forms are often very handing to reduce the amout of let blocks and increase the legibility and declarativeness of the code (equivalently, reduce the imperativeness).
(when-let* [a 1
b 2]
[a b])
would evaluate to [1 2]
. However
(when-let* [a 1
b nil]
[a b])
would evaluate to nil
. Similarly
(if-let* [a 1
b 2]
[a b]
[3 4])
would evaluate to [1 2]
and
(if-let* [a 1
b nil]
[a b]
[3 4])
would yield [3 4]
. When the else form is absent, the result is nil
as expected.
Remember: never do with a macro what you can do with a function. If your utility code is a function (i.e., something that processes run time data) then I suggest you open your pull request to weavejester/medley
Otherwise, if your code operates with compiler data structures, such as binding names and the like, then I will be more than happy to include your utilities in the library.
Copyright © 2017 Javier Arriero
Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.