Anaphoric macros
(require anaphoric) | package: anaphoric |
1 Overview
This package provides anaphoric versions of if, when, cond, map, and filter. These bind the syntax parameter it to the value produced by the condition expression.
(aif (member 'a lst) (displayln it) (displayln "not found"))
(awhen (member 'a lst) (displayln it))
(acond [(member 'a lst) (displayln it)] [(member 'b lst) (displayln it)] [else (displayln "not found")])
In the else clause of acond and in the else branch of aif, the it syntax parameter keeps its value. This means it keeps the value bound by the surrounding conditional, if any. Otherwise it acts exactly as when it is used at the top-level, and raises a syntax error.
(aif 'first (aif (eq? 'second 'no) 'not-executed (displayln it)) 'not-executed)
In the example above, (displayln it) prints 'first. In the example below, (displayln it) raises a syntax error, as it appears in a sequence of else branches:
(aif (eq? 'first 'no) 'not-executed (aif (eq? 'second 'no) 'not-executed (displayln it)))
This package also provides the hygienic versions if-let, when-let and cond-let, for which the user needs to specify an identifier instead of using it.
2 The anaphoric conditionals aif, awhen and acond
syntax
Raises a syntax error when used outside of the true-branch of an aif or the body of an awhen or the body of a non-else case in acond.
syntax
(aif condition true-branch false-branch)
syntax
(awhen condition body ...+)
Each condition is evaluated at most once, and evaluation stops at the first false condition. The body is only evaluated when every conditionᵢ is successful.
3 The hygienic versions if-let, when-let and cond-let
syntax
(if-let [identifier condition] true-branch false-branch)
syntax
(when-let [identifier condition] body ...+)
syntax
(cond-let [[identifierᵢ conditionᵢ] bodyᵢ ...+] ...)
(cond-let [[identifierᵢ conditionᵢ] bodyᵢ ...+] ... [else body ...+]) (cond-let identifier [conditionᵢ bodyᵢ ...+] ...) (cond-let identifier [conditionᵢ bodyᵢ ...+] ... [else body ...+])
The last two variants are shorthands for using the same identifier in all cases (except the else case).
Each conditionᵢ is evaluated at most once (evaluation stops at the first successful conditionᵢ).
Each conditionᵢ is evaluated at most once, and evaluation stops at the first false condition. The body is only evaluated when every conditionᵢ is successful.
4 Anaphoric map and filter
amap works with nested function calls:
(amap (string-append (string-upcase it) "!") '("apple" "banana"))
The syntax parameter it may be used multiple times in the procedure:
afilter works with nested function calls: