From e90b24b73ad11a86ced252b38e0619b313cbe0d8 Mon Sep 17 00:00:00 2001 From: Gergely Nagy Date: Sat, 18 Jan 2014 16:27:26 +0100 Subject: [PATCH] hy/core/macros.hy: Add an (if-not) macro Sometimes it is better to start with the false condition, sometimes that makes the code clearer. For that, the (if-not) macro, which simply reverses the order of the condition blocks, can be of great use. Signed-off-by: Gergely Nagy --- docs/language/api.rst | 13 ++++++++++--- hy/core/macros.hy | 7 +++++++ tests/native_tests/native_macros.hy | 9 +++++++++ 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/docs/language/api.rst b/docs/language/api.rst index 7a3639c..349676a 100644 --- a/docs/language/api.rst +++ b/docs/language/api.rst @@ -679,13 +679,16 @@ would thrown a `NameError`. (set-a 5) (print-a) -if --- +if / if-not +----------- the `if` form is used to conditionally select code to be executed. It has to contain the condition block and the block to be executed if the condition evaluates `True`. Optionally it may contain a block that is executed in case -the evaluation of the condition is `False`. +the evaluation of the condition is `False`. The `if-not` form (*new in +0.9.13*) is similar, but the first block after the test will be +executed when the test fails, while the other, conditional one, when +the test succeeds - opposite of the order of the `if` form. Example usage: @@ -695,6 +698,10 @@ Example usage: (print "lets go shopping") (print "lets go and work")) + (if-not (money-left? account) + (print "lets go and work") + (print "lets go shopping")) + Truth values of Python objects are respected. Values `None`, `False`, zero of any numeric type, empty sequence and empty dictionary are considered `False`. Everything else is considered `True`. diff --git a/hy/core/macros.hy b/hy/core/macros.hy index 9219975..fcaa59a 100644 --- a/hy/core/macros.hy +++ b/hy/core/macros.hy @@ -138,6 +138,13 @@ ret) +(defmacro if-not [test not-branch &optional [yes-branch nil]] + "Like `if`, but execute the first branch when the test fails" + (if (nil? yes-branch) + `(if (not ~test) ~not-branch) + `(if (not ~test) ~not-branch ~yes-branch))) + + (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 0841b1e..b74c89e 100644 --- a/tests/native_tests/native_macros.hy +++ b/tests/native_tests/native_macros.hy @@ -176,3 +176,12 @@ (assert (in ":res_" s1)) (assert (in ":res_" s2)) (assert (not (= s1 s2)))) + +(defn test-if-not [] + (assert (= (if-not True :yes :no) + :no)) + (assert (= (if-not False :yes :no) + :yes)) + (assert (nil? (if-not True :yes))) + (assert (= (if-not False :yes) + :yes)))