【问题标题】:Hygienic macros: function parameter names?卫生宏:功能参数名称?
【发布时间】:2013-04-02 19:35:14
【问题描述】:

我有一个产生函数的宏。我知道最好的做法是使用 gensyms 来确保不会发生命名冲突。所以我想知道宏将定义的函数的参数名称是否需要遵循这个原则?

这是我的宏供参考:

(defmacro defroute
  [routename uri meths handler]
  `(defn ~routename
    [~'req]
    (let [req-meth# (:request-method ~'req)
          bad-meth# (nil? (some #(= req-meth# %) ~meths))
          any-meth# (= ~meths [:any])]
      (if (:uri ~'req)
        (if (and (route-matches ~uri ~'req) (and bad-meth# (not any-meth#)))
          (method-not-allowed req-meth# (get-allowed ~meths))
          (let [params# (route-matches ~uri ~'req)]
            (if (nil? params#)
              ~'req
              (~handler (assoc ~'req :route-params params#)))))
        ~'req))))

如您所见,我目前没有为 req 参数使用 gensym。我最初然后想知道是否有必要。无论如何,感谢您的阅读。

【问题讨论】:

    标签: macros clojure


    【解决方案1】:

    在这种情况下,使用req 相对安全,因为它建立了一个本地范围。作为函数参数,它将隐藏调用命名空间中与符号 req 的任何现有绑定,而不会损坏它们。这样做的代价是,如果有人试图将名称 req 用于任何其他参数,例如 handler,他们可能会感到有点意外。在我看来,这段代码并没有错,尽管它在某些情况下确实改变了最低限度的原则。考虑到这只是添加一对#s 的工作,我认为没有任何理由不为req 使用自动生成符号。

    【讨论】:

    • 太好了,感谢您的解释!你是对的:添加 # 肯定不会有额外的努力。
    猜你喜欢
    • 2020-06-20
    • 1970-01-01
    • 2015-08-05
    • 1970-01-01
    • 2022-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-11
    相关资源
    最近更新 更多