【问题标题】:Locally rebinding `+`本地重新绑定 `+`
【发布时间】:2022-11-19 23:14:37
【问题描述】:

如何将此 Clojure 代码翻译成 Hy,以便打印 2?
它不需要像 Clojure 那样,我只是想在本地环境中隐藏 + 并用 - 替换它。

(defmacro q [expr]
  `(let ~'[+ (fn [x y] (- x y))]
     ~expr))

(print (q (+ 3 1)))

Clojure 中打印2(让我们创建一个本地环境)。
Hy 中它打印4

如何通过将 + 替换为 - 来制作 Hy print 2

我需要那些本地环境,因为我正在制作 DSL。

【问题讨论】:

    标签: hy


    【解决方案1】:

    这不会执行您在 Hy 中所期望的,因为 + 是一个宏,并且宏调用优先于函数调用:

    (defmacro x [] 1)
    (defn x [] 2)
    (print (x))   ; => 1
    

    您的选择是:

    1. 使用与核心宏不同名的名称代替 +,例如 my++2

    2. 只在 Expression 的头部以外的上下文中使用你的新 +(这是 Hy 扩展宏调用的唯一地方),例如 (map + (range 10))

    3. q中,替换输入中的符号+而不是仅仅设置变量+,就像这样

      (defmacro q [expr]
        (import hyrule [coll?])
        (defn f [x]
          (cond
            (= x '+)   '-
            (coll? x)  ((type x) (map f x))
            True       x))
        (f expr))
      
      (print (q (+ 3 1)))
      
    4. 使用defmacro 定义一个名为+ 的新宏。这是一个坏主意,因为您无法访问此模块中的原始 +,包括在您未编写的期望 + 具有其通常含义的宏扩展中。本地宏尚未实现 (#900)。

    【讨论】:

      猜你喜欢
      • 2021-05-03
      • 1970-01-01
      • 2021-06-21
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 2010-09-14
      • 2015-01-26
      • 2011-03-14
      相关资源
      最近更新 更多