0

我正在编写以下代码:

(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))))

但是,如果我(command-dispatcher "maybe")在 HyREPL 中进行评估,我会得到一个None.

=> (command-dispatcher "maybe")
def is_maybe(command_text):
    _hyx_letXUffffX3 = {}
    _hyx_letXUffffX3['splitted'] = command_text.split(' ')
    return _hyx_letXUffffX3['splitted'][0] == 'maybe'


None

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

4

1 回答 1

1

您的宏不会返回任何内容,但会定义一个函数,如您在此处看到的

(assert (not (in "is_maybe" (dir))))
(command-dispatcher "maybe")
(assert (in "is_maybe" (dir)))

您的代码中的一个问题是您正在使用,根据文档let,它不再可用,这是一种可能的方法来改写它: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
于 2021-03-14T08:13:57.087 回答