diff --git a/README.md b/README.md index 9227fad..340d66a 100644 --- a/README.md +++ b/README.md @@ -65,7 +65,9 @@ Or you can just dump `dash.el` in your load path somewhere. * [->>](#--x-form-rest-more) `(x form &rest more)` * [-->](#---x-form-rest-more) `(x form &rest more)` * [-when-let](#-when-let-var-val-rest-body) `(var-val &rest body)` +* [-when-let*](#-when-let-vars-vals-rest-body) `(vars-vals &rest body)` * [-if-let](#-if-let-var-val-then-optional-else) `(var-val then &optional else)` +* [-if-let*](#-if-let-vars-vals-then-optional-else) `(vars-vals then &optional else)` * [!cons](#-cons-car-cdr) `(car cdr)` * [!cdr](#-cdr-list) `(list)` @@ -689,7 +691,7 @@ in in second form, etc. ### -when-let `(var-val &rest body)` If `val` evaluates to non-nil, bind it to `var` and execute body. -`var-val` should be a (var val) pair. +`var-val` should be a (`var` `val`) pair. ```cl (-when-let (match-index (string-match "d" "abcd")) (+ match-index 2)) ;; => 5 @@ -697,16 +699,38 @@ If `val` evaluates to non-nil, bind it to `var` and execute body. (--when-let (even? 3) (cat it :a)) ;; => nil ``` +### -when-let* `(vars-vals &rest body)` + +If all `vals` evaluate to true, bind them to their corresponding + `vars` and execute body. `vars-vals` should be a list of (`var` `val`) + pairs (corresponding to bindings of `let*`). + +```cl +(-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z)) ;; => 15 +(-when-let* ((x 5) (y nil) (z 7)) (+ x y z)) ;; => nil +``` + ### -if-let `(var-val then &optional else)` If `val` evaluates to non-nil, bind it to `var` and do `then`, -otherwise do `else`. `var-val` should be a (`var` `val`) pair. +otherwise do `else`. `var-val` should be a (`var` `val`) pair. ```cl (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7) ;; => 7 (--if-let (even? 4) it nil) ;; => t ``` +### -if-let* `(vars-vals then &optional else)` + +If all `vals` evaluate to true, bind them to their corresponding + `vars` and do `then`, otherwise do `else`. `vars-vals` should be a list + of (`var` `val`) pairs (corresponding to the bindings of `let*`). + +```cl +(-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo") ;; => 15 +(-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo") ;; => "foo" +``` + ### !cons `(car cdr)` Destructive: Sets `cdr` to the cons of `car` and `cdr`. diff --git a/dash.el b/dash.el index 2c3c120..252dd27 100644 --- a/dash.el +++ b/dash.el @@ -696,6 +696,17 @@ VAR-VAL should be a (VAR VAL) pair." (when ,var ,@body)))) +(defmacro -when-let* (vars-vals &rest body) + "If all VALS evaluate to true, bind them to their corresponding + VARS and execute body. VARS-VALS should be a list of (VAR VAL) + pairs (corresponding to bindings of `let*')." + (if (= (length vars-vals) 1) + `(-when-let ,(car vars-vals) + ,@body) + `(-when-let ,(car vars-vals) + (-when-let* ,(cdr vars-vals) + ,@body)))) + (defmacro --when-let (val &rest body) "If VAL evaluates to non-nil, bind it to `it' and execute body." @@ -711,6 +722,18 @@ otherwise do ELSE. VAR-VAL should be a (VAR VAL) pair." `(let ((,var ,val)) (if ,var ,then ,else)))) +(defmacro -if-let* (vars-vals then &optional else) + "If all VALS evaluate to true, bind them to their corresponding + VARS and do THEN, otherwise do ELSE. VARS-VALS should be a list + of (VAR VAL) pairs (corresponding to the bindings of `let*')." + (let ((first-pair (car vars-vals)) + (rest (cdr vars-vals))) + (if (= (length vars-vals) 1) + `(-if-let ,first-pair ,then ,else) + `(-if-let ,first-pair + (-if-let* ,rest ,then ,else) + ,else)))) + (defmacro --if-let (val then &optional else) "If VAL evaluates to non-nil, bind it to `it' and do THEN, otherwise do ELSE." @@ -718,8 +741,10 @@ otherwise do ELSE." (if it ,then ,else))) (put '-when-let 'lisp-indent-function 1) +(put '-when-let* 'lisp-indent-function 1) (put '--when-let 'lisp-indent-function 1) (put '-if-let 'lisp-indent-function 1) +(put '-if-let* 'lisp-indent-function 1) (put '--if-let 'lisp-indent-function 1) (defun -distinct (list) @@ -868,8 +893,10 @@ Returns nil if N is less than 1." "->>" "-->" "-when-let" + "-when-let*" "--when-let" "-if-let" + "-if-let*" "--if-let" "-distinct" "-intersection" diff --git a/dev/examples.el b/dev/examples.el index 45ad8bf..67b0dc7 100644 --- a/dev/examples.el +++ b/dev/examples.el @@ -282,10 +282,18 @@ (--when-let (member :b '(:a :b :c)) (cons :d it)) => '(:d :b :c) (--when-let (even? 3) (cat it :a)) => nil) +(defexamples -when-let* + (-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z)) => 15 + (-when-let* ((x 5) (y nil) (z 7)) (+ x y z)) => nil) + (defexamples -if-let (-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7) => 7 (--if-let (even? 4) it nil) => t) +(defexamples -if-let* + (-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo") => 15 + (-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo") => "foo") + (defexamples !cons (let (l) (!cons 5 l) l) => '(5) (let ((l '(3))) (!cons 5 l) l) => '(5 3))