在以下代码中:
(eval-and-compile (import os hy))
(eval-and-compile (import pathlib [Path]))
; (defmacro with-cwd [dir #* body]
; (setv cwd (hy.gensym))
; `(let [ ~cwd (.cwd Path) ]
; (try (.chdir os ~dir)
; ~@body
; (finally (.chdir os ~cwd)))))
(setv cookies (/ (.cwd Path) "cookies"))
; This fails with an `AssertionError'
(with-cwd cookies (assert (= (.cwd Path) cookies)))
; This fails with a `NameError'
(with-cwd cookies (.cwd Path))
同样,任何依赖于缺失宏的函数或宏都会以同样的方式出错,如果,例如,我正在导入或需要依赖于缺失宏的函数或宏,也会发生同样的事情;基本上,我必须手动导入或要求函数或宏及其依赖项。
这是一个bug,还是我错过了Python/Hy断言的顺序?我预计第一个案例的NameError
也会失败。
这是一个有记录的怪癖:
像许多编程语言一样,但与Python不同的是,Hy并不能保证在所有情况下函数参数的求值顺序。一般来说,
hy.models.Sequence
的子模型的求值顺序是不确定的。例如,(f (g) (h))
可能会在(g)
之前计算(h)
(部分),特别是如果f
是一个函数,而h
是一个生成python级语句的宏。因此,如果您需要确保首先调用g
,则在f
之前调用它。
在这种情况下,assert
语句已经从函数调用中取出((with-cmd …)
是一个函数调用,因为没有名为with-cmd
的宏),并在符号with-cmd
本身之前求值。