When in python do as Pythonistas unless...

| categories: python | tags: | View Comments

Many lisps have a when/unless conditional syntax that works like this:

(when t (print "when evaluated"))

(unless nil (print "unless evaluated"))

"when evaluated"

"unless evaluated"


Those are actually just macros that expand to the more verbose if function:

(macroexpand '(unless nil (print "unless evaluated")))

(if nil nil
(print "unless evaluated"))


In Python, we only have this syntax for this kind of construct:

if True: print "when equivalent"

if not False: print "unless equivalent"

when equivalent
unless equivalent


I thought is would be fun to get as close as possible to the lisp syntax in Python. It is not that easy though. The benefit of a macro is we do not evaluate the arguments until they need to be evaluated. In Python, all arguments of functions are immediately evaluated.

One way to avoid this is to put code inside a function. Then it will not be executed until the function is called. So, here is an example of how to get an unless function in Python that conditionally evaluates a function.

def unless(condition, f):
if not condition:
return f()

def func():
return "executed. Condition was not true."

print unless(1 > 0, func)

print unless(1 < 0, func)

None
executed. Condition was not true.


That is close, but requires us to wrap our code in a function. There does not seem to be any alternative though. It thought maybe a context manager could be used, but there does not seem to be a way to bypass the execution of the code (https://www.python.org/dev/peps/pep-0377/ ). Still, it might be a useful way to change how to think about doing some things differently in Python.