hy

Difference between using a for loop to run a body in a macro versus mapping `exec' over the body


What's the difference between using (map exec ~body) versus (for [node ~body] node) in the following code?

(defmacro with-cwd [dir #* body]
          `(let [ cwd (.cwd Path) ]
               (try (.chdir os ~dir)

                    ;; Should I use this?
                    (map exec ~body)

                    ;; Or this?
                    (for [node body] node)

                    ;; UPDATE: Or this...
                    (do ~@body)

                    ;; UPDATE: Or this?
                    ~@body

                    (finally (.chdir os cwd)))))

Which one is safer, or are they both alright? exec() doesn't seem to run strings of code anymore, which I believe was changed in Python 3, so is it alright now? I just want to use something more concise; I'm not good at naming variables.

UPDATE: I also just realized (do ~@body) is also an option, which seems to be what most people do; what is the difference between that and simply doing ~@body?


Solution

  • What's the difference between using (map exec ~body) versus (for [node ~body] node)

    map collects results whereas for ignores them. exec runs a string of Python code or a Python code object, so it probably won't do anything useful with whatever the return value of body is.

    exec() doesn't seem to run strings of code anymore

    It does. You gotta read the documentation, my man.

    (do ~@body) is also an option, which seems to be what most people do; what is the difference between that and simply doing ~@body?

    In this position, nothing, because try already evaluates its body forms in sequence and returns the last one, just like do.