diff --git a/docs/contrib/flow.rst b/docs/contrib/flow.rst new file mode 100644 index 0000000..46aae99 --- /dev/null +++ b/docs/contrib/flow.rst @@ -0,0 +1,59 @@ +========== +Flow +========== + +.. versionadded:: 0.10.2 + +The ``flow`` macros allow a programmer to direct the flow of his program with +greater ease. + + +Macros +====== + +.. _guard: +.. _switch: + +guard +----- + +``guard`` allows you to guard against a condition. + + +Usage: `(guard (cond1) (body1) (cond2) (body2) ...)` + +Example: + +.. code-block:: hy + + (require hy.contrib.flow) + + (defn army-greeter [age height] + (guard + (< age 18) (print "You are too young!") + (< height 170) (print "You are too small!") + True (print "Welcome aboard!"))) + + +switch +----- + +``switch`` allows you to run code based on the value of a variable. +A final extra body allows for a default case. + + +Usage: `(switch var (cond1) (body1) (cond2) (body2) ... )` + +Example: + +.. code-block:: hy + + (require hy.contrib.flow) + + (defn bmi-commenter [bmi] + (switch bmi + (<= 18.5) (print "you are underweight!") + (<= 25.0) (print "apparently normal") + (<= 30) (print "a little too heavy, but ok") + (print "You are a whale!"))) + diff --git a/docs/contrib/index.rst b/docs/contrib/index.rst index eda11f2..ebed64f 100644 --- a/docs/contrib/index.rst +++ b/docs/contrib/index.rst @@ -10,3 +10,4 @@ Contents: anaphoric loop multi + flow diff --git a/hy/contrib/flow.hy b/hy/contrib/flow.hy new file mode 100644 index 0000000..6f0aa4e --- /dev/null +++ b/hy/contrib/flow.hy @@ -0,0 +1,24 @@ +;; Additional flow macros + +(defmacro/g! guard [&rest args] + (setv g!cond (car args)) + (setv g!body (car (cdr args))) + (setv g!rest (cdr (cdr args))) + (if g!rest + `(if ~g!cond + ~g!body + (guard ~@g!rest)) + `(if ~g!cond + ~g!body))) + +(defmacro/g! switch [variable &rest args] + (setv g!comp (car args)) + (setv g!body (car (cdr args))) + (setv g!rest (cdr (cdr args))) + (setv g!cond `(~(car g!comp) ~variable ~@(cdr g!comp))) + (if g!rest + (if (cdr g!rest) + `(if ~g!cond ~g!body (switch ~variable ~@g!rest)) + `(if ~g!cond ~g!body ~@g!rest)) + `(if ~g!cond ~g!body))) +