control-flow.lisp 1.26 KB
Newer Older
1
2
3
4
5
6
7
(in-package :alexandria-2)

(defun line-up-iter (thread-first-p acc forms)
  "Iterative implementation for `thread-iter'.

The THREAD-FIRST-P decides where to thread the FORMS, accumulating in ACC."
  (if forms
8
      (line-up-iter thread-first-p
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
                   (let ((form (car forms)))
                     (if (listp form)
                         (if thread-first-p
                             (apply #'list (car form) acc (cdr form))
                             (append form (cons acc nil)))
                         (list form acc)))
                   (cdr forms))
      acc))

(defmacro line-up-first (&rest forms)
  "Lines up FORMS elements as the first argument of their successor.
Example:
    (thread-first
      5
      (+ 20)
      (/ 25)
      -
      (+ 40))
Is equivalent to:
    (+ (- (/ (+ 5 20) 25)) 40)
Note how the single `-' got converted into a list before
threading."
  (line-up-iter t (car forms) (cdr forms)))

(defmacro line-up-last (&rest forms)
  "Lines up FORMS elements as the last argument of their successor.
Example:
    (thread-last
      5
      (+ 20)
      (/ 25)
      -
      (+ 40))
Is equivalent to:
    (+ 40 (- (/ 25 (+ 20 5))))
Note how the single `-' got converted into a list before
threading."
  (line-up-iter nil (car forms) (cdr forms)))