Reputation: 306
I was writing the following pieces of code:
(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")))
... until I realized I was doing something repetitive, so I wanted to factor out the pattern:
(import [hy [HySymbol]])
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(let [splitted (.split command-text " ")]
(= (get splitted 0) ~command-type))))
However, if I evaluate (command-dispatcher "maybe")
in HyREPL, I get a None
.
=> (command-dispatcher "maybe")
def is_maybe(command_text):
_hyx_letXUffffX3 = {}
_hyx_letXUffffX3['splitted'] = command_text.split(' ')
return _hyx_letXUffffX3['splitted'][0] == 'maybe'
None
This is weird, because a macro should return a HyExpression
, not None
. What am I missing?
Upvotes: 0
Views: 82
Reputation: 2385
Your macro will not return anything but will define a function, as you can see here
(assert (not (in "is_maybe" (dir))))
(command-dispatcher "maybe")
(assert (in "is_maybe" (dir)))
An issue in your code is that you are using let
, which is not available anymore according to documentation, here is a possible way to rewrite it using setv
instead:
(defmacro command-dispatcher [command-type]
`(defn ~(HySymbol (+ command-type "?")) [command-text]
(setv splitted (.split command-text " "))
(= (get splitted 0) ~command-type)))
You can then call this function using is_maybe
(or maybe?
, that's syntactic sugar), eg.
(command-dispatcher "maybe")
(print (maybe? "foo"))
(print (maybe? "maybe foo"))
Will print
False
True
Upvotes: 1