简体   繁体   English

不存在的 hy 宏运行断言,但其他一切都失败了

[英]Non-existent hy macros runs assertions, but fails appropriately with everything else

In the following code:在以下代码中:

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

Similarly, any functions or macros depending on the missing macro errors out in the same way, and if, for example, I'm importing or requiring a function or macro that depends on the missing macro, the same thing happens;同样,任何依赖于缺失宏的函数或宏都会以同样的方式出错,例如,如果我正在导入或需要依赖于缺失宏的函数或宏,也会发生同样的事情; basically, I have to import or require a function or macro as well as its dependencies manually.基本上,我必须手动导入或需要函数或宏及其依赖项。

Is this a bug, or am I missing something about the order of Python / Hy assertions?这是一个错误,还是我错过了关于 Python / Hy 断言顺序的一些东西? I expected the first case to fail with a NameError as well.我预计第一个案例也会因NameError而失败。

This is a documented quirk :这是一个记录在案的怪癖

Like many programming languages, but unlike Python, Hy doesn't guarantee in all cases the order in which function arguments are evaluated.与许多编程语言一样,但与 Python 不同的是,Hy 并不保证在所有情况下计算函数参数的顺序。 More generally, the evaluation order of the child models of a hy.models.Sequence is unspecified.更一般地,未指定hy.models.Sequence的子模型的评估顺序。 For example, (f (g) (h)) might evaluate (part of) (h) before (g) , particularly if f is a function whereas h is a macro that produces Python-level statements.例如, (f (g) (h))可能在(g)之前评估 (part of) (h) ,特别是如果f是一个函数而h是一个产生 Python 级语句的宏。 So if you need to be sure that g is called first, call it before f .因此,如果您需要确保首先调用g ,请在f之前调用它。

In this case, the assert statement has gotten pulled out of the function call ( (with-cmd …) being a function call, since there is no macro named with-cmd ) and evaluated before the symbol with-cmd itself.在这种情况下, assert语句已从函数调用中提取出来( (with-cmd …)是一个函数调用,因为没有名为with-cmd宏)并在符号with-cmd本身之前进行评估。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM