diff --git a/docs/language/api.rst b/docs/language/api.rst index 57f6029..ef9099a 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -726,6 +726,34 @@ any numeric type, empty sequence and empty dictionary are considered `False`. Everything else is considered `True`. +lisp-if / lif +------------- + +For those that prefer a more lisp-y if clause, we have lisp-if, or lif. This +*only* considers None/nil as false! All other values of python +"falseiness" are considered true. + + +.. code-block:: clj + + => (lisp-if True "true" "false") + "true" + => (lisp-if False "true" "false") + "true" + => (lisp-if 0 "true" "false") + "true" + => (lisp-if nil "true" "false") + "false" + => (lisp-if None "true" "false") + "false" + + ; And, same thing + => (lif True "true" "false") + "true" + => (lif nil "true" "false") + "false" + + import ------ diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 531350e..486cf0e 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -145,6 +145,11 @@ `(if (not ~test) ~not-branch ~yes-branch))) +(defmacro-alias [lisp-if lif] [test &rest branches] + "Like `if`, but anything that is not None/nil is considered true." + `(if (is-not ~test nil) ~@branches)) + + (defmacro when [test &rest body] "Execute `body` when `test` is true" `(if ~test (do ~@body))) diff --git a/tests/native_tests/native_macros.hy b/tests/native_tests/native_macros.hy index 5bdf821..654c06d 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -191,6 +191,25 @@ :yes))) +(defn test-lisp-if [] + "test that lisp-if works as expected" + ; nil is false + (assert (= (lisp-if None "true" "false") "false")) + (assert (= (lisp-if nil "true" "false") "false")) + + ; But everything else is True! Even falsey things. + (assert (= (lisp-if True "true" "false") "true")) + (assert (= (lisp-if False "true" "false") "true")) + (assert (= (lisp-if 0 "true" "false") "true")) + (assert (= (lisp-if "some-string" "true" "false") "true")) + (assert (= (lisp-if "" "true" "false") "true")) + (assert (= (lisp-if (+ 1 2 3) "true" "false") "true")) + + ; Just to be sure, test the alias lif + (assert (= (lif nil "true" "false") "false")) + (assert (= (lif 0 "true" "false") "true"))) + + (defn test-defn-alias [] (defn-alias [tda-main tda-a1 tda-a2] [] :bazinga) (defun-alias [tda-main tda-a1 tda-a2] [] :bazinga)