Fletching Macros Save

Clojure macros that complement the clojure.core threading (arrow) macros

Project README

Fletching macros

A collection of Clojure macros that complement the clojure.core threading macros -> and ->>.

Setup

To start, create a Leiningen project and add the following dependency to project.clj:

Clojars Project

Next, load the macros as follows:

(require '[fletching.macros :refer :all])

>>

The macro >> removes itself from the head of the enclosing S-expression, and then moves the second form in the remaining expression to the end of the expression.

Intended to be used within -> to switch to ->> conventions.

(-> [[1 2 3] [3 4 5]]
    (nth 1)
    (->> (map -))
    (nth 1))
;=> -4

This can be rewritten as

(-> [[1 2 3] [3 4 5]]
    (nth 1)
    (>> map -)
    (nth 1))
;=> -4

<<

The macro << removes itself from the head of the enclosing S-expression, and then moves the last form in the expression to the second position.

This macro addresses the problem of nesting -> within ->>.

Working around this composition problem using clojure.core macros was already possible, but not always very elegant. You might have been writing code like this:

(-> (->> [-1 -2 -3 -4 -5]
         (map -)
         (filter even?))
    last
    range
    rest
    (->> (reduce *)))
;=> 6

Or like this:

(as-> [-1 -2 -3 -4 -5] x
      (map - x)
      (filter even? x)
      (-> x last range rest)
      (reduce * x))
;=> 6

Now you can write this:

(->> [-1 -2 -3 -4 -5]
     (map -)
     (filter even?)
     (<< -> last range rest)
     (reduce *))
;=> 6

Of course, << is also useful in one-off situations:

(->> [1 2 3 4 5]
     (map -)
     (<< nth 2)
     (/ 6))
;=> -2

?>, <?

The macros ?> and <? remove themselves from the head of the enclosing S-expression, and then remove the second (?>) or last (<?) form in the remaining expression and bind it to ?.

These macros are useful when you're composing functions using -> or ->> and you find yourself needing a little bit more flexibility for some of the threaded expressions.

(->> [1 2 3 4 5]
     (take 3)
     (reduce *)
     (<? str ? " is " (if (even? ?) "even" "odd"))
     (<? do [? ?]))
;=> ["6 is even" "6 is even"]

><

The macro >< removes itself from the head of the enclosing S-expression.

This macro is useful when you want to thread functions (as opposed to function arguments):

(-> [+ - * /]
    (nth 2)
    (>< 3 4)
    inc)
;=> 13

Equivalently,

(->> [+ - * /]
     (drop 2)
     first
     (<< >< 3 4)
     inc)
;=> 13

<fn, <&fn

The macros <fn and <&fn remove themselves from the head of the enclosing S-expression, and then insert a variable in the second position of the remaining expression. Finally, the expression is transformed into a 1-ary (<fn) or variadic (<&fn) lambda, which binds the variable.

<fn and <&fn can be used for defining functions in a point-free style:

(def f (<fn ->> (map -)
                (filter even?)
                (reduce *)))
(f [2 4 5 6])
;=> -48

<&fn is like <fn but takes a variable number of arguments, which it threads into the expression as a sequence.

(def g (<&fn ->> (map -)
                 (filter even?)
                 (reduce *)))
(g 2 4 5 6)
;=> -48

License

Copyright © 2015 Jonas De Vuyst

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

Open Source Agenda is not affiliated with "Fletching Macros" Project. README Source: jdevuyst/fletching-macros
Stars
33
Open Issues
0
Last Commit
4 years ago

Open Source Agenda Badge

Open Source Agenda Rating