title: How to wrap and execute a lisp s-expression by another s-expression?
body: <p>I tried to wrap a lisp expression by another lisp expression. I guess, a macro should do it, but I don't get the trick. Can someone help me, who knows how to do it?</p>
  
  <p>My actual aim is to write a macro which wraps a batch of <code>with-open-file</code> expressions around  some  macro-body code.</p>
  
  <p>(I want to write a script/program, which opens one or two input files, process them line by line, but also outputs the processing result in several different independent output files. For that I would love to have the <code>with-open-file</code> macro calls piled up around the code which processes and writes to the independent output files - all opened for the macro-body code).</p>
  
  <p>Since the <code>with-open-file</code> requires a symbol (handler) for the input or output stream and the path variable to the output (or input) file, and some additional information (direction of the file etc.), I want to put them into lists.</p>
  
  <pre><code>;; Output file-paths:
  (defparameter *paths* '("~/out1.lisp" "~/out2.lisp" "~/out3.lisp"))
  
  ;; stream handlers (symbols for the output streams)
  (defparameter *handlers* '(out1 out2 out3))
  
  ;; code which I would love to execute in the body
  (print "something1" out1)
  (print "something2" out2)
  (print "something3" out3)
  </code></pre>
  
  <p>How I would love the macro to be called:</p>
  
  <pre><code>(with-open-files (*handlers* *paths* '(:direction :output :if-exists :append))
    ;; the third macro argument should be what should be passed to the
    ;; individual `with-open-file` calls
    ;; and it might be without `quote`-ing or with `quote`-ing
    ;; - is there by the way a good-practice for such cases? -
    ;; - is it recommended to have `quote`-ing? Or how would you do that? -
    ;; and then follows the code which should be in the macro body:
    (print "something1" out1)
    (print "something2" out2)
    (print "something3" out3))
  </code></pre>
  
  <p>To what the macro call should expand:</p>
  
  <pre><code>(with-open-file (out1 "~/out1.lisp" :direction :output :if-exists :append)
    (with-open-file (out2 "~/out2.lisp" :direction :output :if-exists :append)
      (with-open-file (out3 "~/out3.lisp" :direction :output :if-exists :append)
        (print "something1" out1)
        (print "something2" out2)
        (print "something3" out3))))
  </code></pre>
  
  <p>As one step, I thought I have to make an s-expression wrap another s-expression.</p>
  
  <p>My first question was: <strong>How to wrap an s-expression by another s-expression?</strong> But I just couldn't manage it already at this point.
  All I could do was to write a function which just spills out an un-executed expression. How to write a macro which does the same but also executes the code after expanding it in this way?</p>
  
  <pre><code>(defun wrap (s-expr-1 s-expr-2)
    (append s-expr-1 (list s-expr-2)))
  
  (wrap '(func1 arg1) '(func2 arg2))
  ;; =&gt; (FUNC1 ARG1 (FUNC2 ARG2))
  
  (wrap '(with-open-files (out1 "~/out1.lisp" :direction :output :if-exists :append))
    '(with-open-files (out2 "~/out2.lisp" :direction :output :if-exists :append) 
        (print "something1" out1)
        (print "something2" out2)
        (print "something3" out3)))
  </code></pre>
  
  <p>Which gives:</p>
  
  <pre><code>(WITH-OPEN-FILES (OUT1 "~/out1.lisp" :DIRECTION :OUTPUT :IF-EXISTS :APPEND)
   (WITH-OPEN-FILES (OUT2 "~/out2.lisp" :DIRECTION :OUTPUT :IF-EXISTS :APPEND)
    (PRINT "something1" OUT1) 
    (PRINT "something2" OUT2)
    (PRINT "something3" OUT3)))
  </code></pre>
  
  <p>In this way, applying <code>wrap</code> function successively, looping over the input-lists, I could build the code maybe ...</p>
  
  <p>However, these functions would generate only code but don't execute it.
  And I would be forced at the end to use the <code>eval</code> function to evaluate the built code ... (But somehow I know this shouldn't be done like this. And I just didn't really understood how to write macros which do such things ... Actually, macros are there for solving exactly such problems ... )</p>
  
  <p>With the execution, I just came into big trouble. And since one cannot call <code>funcall</code> or <code>apply</code> on macros (instead of function-names) I don't see an obvious solution. Did someone had experience with such kind of situations?</p>
  
  <p>And when accomplished wrapping an s-expression in a macro by another s-expression <em>and let it be evaluated</em>, the next question would be, how to process the list to let the code to expand to the desired code and then be evaluated? I just tried hours and didn't came far. </p>
  
  <p>I need help from someone who has experience to write such kind of macros ...</p>