Problem with passing a vector as a binding to the for macro

后端 未结 4 1032
野性不改
野性不改 2021-02-20 06:13

I have an arbitrary number of lists which I would like to process using the for macro. I want to create a function that passes a vector as the binding since the number of lists

4条回答
  •  隐瞒了意图╮
    2021-02-20 06:37

    You can try to force the evaluation of the binding vector. Instead of trying to define a macro that will wrap the for macro, wrap it in a function, e.g.

    (defn for-fn [bindings expr]
      (eval `(for ~bindings ~expr))) 
    

    Then you can actually build a binding vector with a few additional constraints since all s-expressions inside the binding vector need to be valid and contain a verb as the first element.

    (let [bindings '[a (list 1 2) b (list 3 4) c (range 10 12)
                     :when (> (+ a b c) 15)]
          expr '(str a "-" b "-" c)]
      (for-fn bindings expr)) 
    

    And with your example :

    (def list1 '("pink" "green"))
    (def list2 '("dog" "cat"))
    (def testvector (vector 'A (cons 'list  list1) 'B (cons 'list list2)))
    
    (for-fn testvector '(str A "-" B))
    => ("pink-dog" "pink-cat" "green-dog" "green-cat")
    

    Note : since for-fn is function, you need to quote the expression (str A "-" B) to prevent an early evaluation (before A & B are bound).

提交回复
热议问题