为什么对 `defmacro` 的调用计算结果为 None?
Why are calls to `defmacro` evaluating to None?
我正在编写以下代码:
(require [hy.contrib.walk [let]])
(defn maybe? [command-text]
(let [splitted (.split command-text " ")]
(= (get splitted 0) "maybe")))
(defn if? [command-text]
(let [splitted (.split command-text " ")]
(+ (get splitted 0) "if")))
...直到我意识到我在做一些重复的事情,所以我想分解出模式:
(import [hy [HySymbol]])
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(let [splitted (.split command-text " ")]
(= (get splitted 0) ~command-type))))
但是,如果我在 HyREPL 中计算 (command-dispatcher "maybe")
,我会得到 None
。
=> (command-dispatcher "maybe")
def is_maybe(command_text):
_hyx_letXUffffX3 = {}
_hyx_letXUffffX3['splitted'] = command_text.split(' ')
return _hyx_letXUffffX3['splitted'][0] == 'maybe'
None
这很奇怪,因为宏应该 return 一个 HyExpression
,而不是 None
。我错过了什么?
你的宏不会return任何东西,但会定义一个函数,正如你在这里看到的那样
(assert (not (in "is_maybe" (dir))))
(command-dispatcher "maybe")
(assert (in "is_maybe" (dir)))
您的代码中的一个问题是您正在使用 let
,根据 documentation, here is a possible way to rewrite it using setv
,它不再可用:
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(setv splitted (.split command-text " "))
(= (get splitted 0) ~command-type)))
然后您可以使用is_maybe
(或maybe?
,这是语法糖)调用此函数,例如
(command-dispatcher "maybe")
(print (maybe? "foo"))
(print (maybe? "maybe foo"))
将打印
False
True
我正在编写以下代码:
(require [hy.contrib.walk [let]])
(defn maybe? [command-text]
(let [splitted (.split command-text " ")]
(= (get splitted 0) "maybe")))
(defn if? [command-text]
(let [splitted (.split command-text " ")]
(+ (get splitted 0) "if")))
...直到我意识到我在做一些重复的事情,所以我想分解出模式:
(import [hy [HySymbol]])
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(let [splitted (.split command-text " ")]
(= (get splitted 0) ~command-type))))
但是,如果我在 HyREPL 中计算 (command-dispatcher "maybe")
,我会得到 None
。
=> (command-dispatcher "maybe")
def is_maybe(command_text):
_hyx_letXUffffX3 = {}
_hyx_letXUffffX3['splitted'] = command_text.split(' ')
return _hyx_letXUffffX3['splitted'][0] == 'maybe'
None
这很奇怪,因为宏应该 return 一个 HyExpression
,而不是 None
。我错过了什么?
你的宏不会return任何东西,但会定义一个函数,正如你在这里看到的那样
(assert (not (in "is_maybe" (dir))))
(command-dispatcher "maybe")
(assert (in "is_maybe" (dir)))
您的代码中的一个问题是您正在使用 let
,根据 documentation, here is a possible way to rewrite it using setv
,它不再可用:
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(setv splitted (.split command-text " "))
(= (get splitted 0) ~command-type)))
然后您可以使用is_maybe
(或maybe?
,这是语法糖)调用此函数,例如
(command-dispatcher "maybe")
(print (maybe? "foo"))
(print (maybe? "maybe foo"))
将打印
False
True