Macros 为什么对'defmacro'的调用的计算结果为None?

Macros 为什么对'defmacro'的调用的计算结果为None?,macros,hy,Macros,Hy,我正在编写以下代码: (需要[hy.contrib.walk[let]] (定义可能?[命令文本] (让[splited(.split命令文本“”)] (=(拆分为0)“可能”)) (如果定义?[命令文本] (让[splited(.split命令文本“”)] (+(拆分为0)“如果”)) 。。。直到我意识到我在做一些重复的事情,所以我想找出模式: (导入[hy[HySymbol]] (defmacro命令分派器[命令类型] `(defn~(HySymbol(+命令类型“?”)))[命令文本]

我正在编写以下代码:

(需要[hy.contrib.walk[let]]
(定义可能?[命令文本]
(让[splited(.split命令文本“”)]
(=(拆分为0)“可能”))
(如果定义?[命令文本]
(让[splited(.split命令文本“”)]
(+(拆分为0)“如果”))
。。。直到我意识到我在做一些重复的事情,所以我想找出模式:

(导入[hy[HySymbol]]
(defmacro命令分派器[命令类型]
`(defn~(HySymbol(+命令类型“?”)))[命令文本]
(让[splited(.split命令文本“”)]
(=(拆分为0)~命令类型)))
但是,如果我在HyREPL中计算
(command dispatcher“maybay”)
,我会得到一个
None

=>(命令调度器“可能”)
def可能是(命令文本):
_hyx_Letxuffx3={}
_hyx_letxufffx3['splitted']=命令_text.split(“”)
return\u hyx\u letxufffx3['splitted'][0]=='maybe'
没有一个

这很奇怪,因为宏应该返回
HyExpression
,而不是
None
。我遗漏了什么?

您的宏将不返回任何内容,而是定义一个函数,如您在此处所见

(断言(不在“is_maybe”(dir)中)
(命令调度员“可能”)
(assert(在“is_maybe”(dir)中)
代码中的一个问题是您使用的是
let
,根据,该选项不再可用,以下是一种可能的重写方法:

(defmacro命令分派器[命令类型]
`(defn~(HySymbol(+命令类型“?”)))[命令文本]
(setv已拆分(.split命令文本“”)
(=(拆分为0)~命令类型)))
然后,您可以使用
is\u maybe
(或者
maybe?
,这是语法糖)调用此函数,例如

(命令调度器“可能”)
(打印(可能是“foo”))
(打印(可能是?“可能是福”))
将打印

False
真的

因此,
命令调度程序
是一个有效的函数,它只是将一个符号绑定到生成的函数上,并且不返回任何有用的内容。但是,这种行为与其他Lisp不同。好吧,他们的宏实际上返回一段代码,而不是产生绑定效果。
let
已在
hy.contrib.walk
@Kodiologist中重新实现,我在测试代码时忘了导入它,感谢它的精确性。