Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement -cond-> and -cond->> macros. #349

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
32 changes: 32 additions & 0 deletions README.md
Expand Up @@ -283,6 +283,8 @@ Functions pretending lists are trees.
* [-some->](#-some--x-optional-form-rest-more) `(x &optional form &rest more)`
* [-some->>](#-some--x-optional-form-rest-more) `(x &optional form &rest more)`
* [-some-->](#-some---x-optional-form-rest-more) `(x &optional form &rest more)`
* [-cond->](#-cond--x-rest-branches) `(x &rest branches)`
* [-cond->>](#-cond--x-rest-branches) `(x &rest branches)`

### Binding

Expand Down Expand Up @@ -2235,6 +2237,36 @@ and when that result is non-nil, through the next form, etc.
(-some--> '(1 3 5) (-filter 'even? it) (append it it) (-map 'square it)) ;; => nil
```

#### -cond-> `(x &rest branches)`

Conditionally thread `x` through `branches`.
Branches take the form of test-expressions pairs.
When test is non-nil, threads `x` (via [`->`](#--x-optional-form-rest-more)) through the
corresponding expression. Note that, unlike cond
branching, [`-cond->`](#-cond--x-rest-branches) threading does not short circuit after the
first true test expression.

```el
(-cond-> "abc" t (concat "def" "ghi")) ;; => "abcdefghi"
(-cond-> 10 nil number-to-string) ;; => 10
(let ((a 10)) (-cond-> a (= 10 a) number-to-string)) ;; => "10"
```

#### -cond->> `(x &rest branches)`

Conditionally thread `x` through `branches`.
Branches take the form of test-expressions pairs.
When test is non-nil, threads `x` (via [`->>`](#--x-optional-form-rest-more)) through the
corresponding expression. Note that, unlike cond
branching, [`-cond->>`](#-cond--x-rest-branches) threading does not short circuit after the
first true test expression.

```el
(-cond->> "abc" t (concat "def" "ghi")) ;; => "defghiabc"
(-cond->> 10 nil number-to-string) ;; => 10
(let ((string "abc")) (-cond->> string (string= nil string) (concat "def" "ghi"))) ;; => "abc"
```


## Binding

Expand Down
44 changes: 44 additions & 0 deletions dash.el
Expand Up @@ -1592,6 +1592,50 @@ and when that result is non-nil, through the next form, etc."
(--> ,result ,form))
,@more))))

(defmacro -cond-> (x &rest clauses)
"Conditionally thread X through CLAUSES.
Clauses take the form of (CONDITION EXPRESSION).
When condition is non-nil, threads X (via `->') through the
corresponding expression. Note that, unlike `cond',
`-cond->' threading does not short circuit after the
first non-nil test expression.
Returns the value of the last expression."
(declare (debug (form clauses))
(indent 1))
(when (= 1 (% (length clauses) 2))
(signal 'wrong-number-of-arguments (list '-> (1+ (length clauses)))))
(let ((g (make-symbol "g"))
steps)
(while clauses
(let ((test (pop clauses))
(form (pop clauses)))
(push `(,g (if ,test (-> ,g ,form) ,g)) steps)))
`(let* ((,g ,x)
,@(nreverse steps))
,g)))

(defmacro -cond->> (x &rest clauses)
"Conditionally thread X through CLAUSES.
Clauses take the form of (CONDITION EXPRESSION).
When condition is non-nil, threads X (via `->>') through the
corresponding expression. Note that, unlike `cond',
`-cond->>' threading does not short circuit after the
first non-nil test expression.
Returns the value of the last expression."
(declare (debug (form body))
(indent 1))
(when (= 1 (% 2 (length clauses)))
(signal 'wrong-number-of-arguments (list '-cond->> (+1 (length clauses)))))
(let ((g (make-symbol "g"))
steps)
(while clauses
(let ((test (pop clauses))
(form (pop clauses)))
(push `(,g (if ,test (->> ,g ,form) ,g)) steps)))
`(let* ((,g ,x)
,@(nreverse steps))
,g)))

(defun -grade-up (comparator list)
"Grade elements of LIST using COMPARATOR relation, yielding a
permutation vector such that applying this permutation to LIST
Expand Down