问题标签 [hygiene]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
macros - 将变量注入引用的表达式
我有一个引用的表达式,例如:
CompileError
我希望在表达式中注入一个变量,以便 x 有一个值,并且当像这样评估时,由于 x
未定义,表达式不会引发 a :
此 AST 已传递给我,我无法更改生成它的代码。不过,我可以在通过 AST 后修改它。
我想这样做我可以将 AST 转换为类似于这个引用的表达式:
在尝试这个之后,我的 AST 看起来像这样:
这行不通。我认为这可能是由于var!
.
解决方案:我现在意识到变量的范围不正确,我需要这样的 AST:
macros - 为什么这个 Julia 宏_not_需要`esc`?
我在 Julia 中找到了一个unless
宏示例,如下所示:
但是,当我尝试使用它时,它会失败(显然存在卫生问题,但我无法准确弄清楚)。这是我使用的测试:
现在我可以通过只转义分支而不是测试来完成这项工作:
我的问题是:为什么只逃避分支而不是测试就足够了?现在我确实尝试了宏扩展。在第一种情况下,没有esc
,我得到这个:
现在,即使没有一个宏参数被转义,只有y
gensymed !谁能解释为什么会这样?(我知道第二个版本有效,因为当我逃离分支时, y 没有得到 gensymed 并且宏y = 3
按预期扩展。但我完全不知道为什么x
即使没有 gensymed 也没有使用esc
。)
macros - Macro call vs macro definition environment in Julia
I am trying to make sense out of a statement in the Julia's Metaprogramming documentation on macro hygiene. The documentation claims that
Julia’s macro expander solves these problems in the following way. First, variables within a macro result are classified as either local or global. A variable is considered local if it is assigned to (and not declared global), declared local, or used as a function argument name. Otherwise, it is considered global. Local variables are then renamed to be unique (using the gensym() function, which generates new symbols), and global variables are resolved within the macro definition environment. Therefore both of the above concerns are handled; the macro’s locals will not conflict with any user variables, and time and println will refer to the standard library definitions.
I wrote a small program to see whether global variables were indeed resolved in the macro definition environment. I wrote the following:
If I am to understand the Julia docs correctly, part of macro hygiene is to make sure whichever functions are called in the macro's returned expression don't get hijacked by functions of the same name inside the caller's environment. But this is exactly what happens here, the function f
that was used was the one that was defined locally.
I would have thought I would have to use esc
in order to use the f
in scope at the point of call. But this is not so, why?
And in addition, I noticed that the the variable x
inside the macro result is considered local, so a new gensymed variable name should have been generated for it, so as not to clash with the x
in the macro call environment. But this did not happen either!
How am I to read the documentation to make any sense out the reason that esc
need not be used here?
EDIT (CLARIFICATION)
When I claim
f
is global andx
is local, according to the docs, I do so because I see thatx
is used as a function argument. I understandx
is not being written to nor declared local, and it certainly looks global, but those docs claim function arguments should be global too!I know the usual part of hygiene where the gensymming of locals ensures that variables of the same name in the macro caller's context are not inadvertently plastered. However, the docs claim that for functions, the ones that are seen in the macro definition's context are protected from the caller using their own. This is the part that makes no sense to me, because my experiment shows otherwise.
macros - 宏观卫生是否只在不同的模块中保护您?
至于 Julia 0.4.2
我原以为结果会是(1, 1, 2)
。
但是,如果我在不同的模块中定义宏,它会按预期工作。
似乎卫生只是在模块名称空间的符号前加上前缀。因此,宏扩展器不可能在第一种情况下区分不同的范围。
这是预期的行为吗?
java - 创建很多私人课程是不是很糟糕?
我正在用 Java 做一个项目,它有很多需要多个返回对象的方法。为此,我必须继续创建封装返回对象的私有类。这些对象是有意义的,因为我的代码中的 FontResult 将返回字体名称和字体大小,例如,但不断为我需要的每种返回类型创建新对象感觉是错误的,并且不知何故就像我试图规避 Java 的编写方式一样。这是错误的还是这样做可以吗?我应该以更多的方式来构建我的代码吗?
一个例子如下:
macros - 指向语法模式变量的语法参数?
通常syntax-parameterize
与 结合使用,make-rename-transformer
以便语法参数p
表现为另一个标识符的别名:
上面的代码运行良好,由 .tmp
绑定的标识符也是如此let
。但是,如果我尝试为由 绑定p
的模式变量创建别名,则它不会按预期工作:tmp
with-syntax
相反,如果我声明一个p-unhygienic
语法,并将其绑定到(make-rename-transformer #'tmp)
,那么它可以正常工作:
如何使用 为模式变量创建卫生别名syntax-parameterize
?
c++ - 如何标记错误代码
我想标记错误代码(按照 GSL 的建议),最好的方法是什么?例如,给定下面的函数 foo (不是我自己可以轻松解决这个问题的最佳示例)。
我确实想到了三个想法。这个标志的优点(缺点)是什么?
1. 仅评论 2.宏+静态断言 3. 编译器警告c - 使用可变参数宏动态地为宏名称添加前缀
背景
我使用了另一个问题中的一组预处理器宏,这些宏允许我在源代码中为符号名称(枚举、函数名称、结构名称等)添加前缀,即:
问题
这按预期工作,输出如下:i is 123 in func_3.
编辑
我想要这段代码:
扩展至:
我意识到宏不应该以数字开头。在最终代码中,我将使用LIB_A_
和LIB_B_
作为前缀。
/编辑
但是,如果我尝试将宏作为可变参数宏的参数执行相同的操作NAME
,则会失败,如下所示:
重用NAME
宏:
代码
输出
手动粘贴前缀:
代码:
输出:
问题
如何为所有宏创建具有共同前缀的简单宏定义(名称 + 值)?目标是能够制作源文件的多个副本并使用不同的标志编译它们,这样所有版本都可以链接到同一个最终二进制文件中,而不会发生符号/宏名称冲突(宏稍后将被移动到头文件中)。最终文件太大而无法用 M4 或模板语言编写。理想情况下,解决方案将涉及能够为所有用例使用单个宏函数/可变参数宏,但我可以使用一个宏作为符号前缀,另一个宏作为宏名称前缀。
macros - 球拍宏不起作用
我以前从未使用过Racket的宏系统,所以请原谅我的无知。我正在尝试在 Racket 的 Datalog 系统中动态定义规则,基本上是这样的:
如果我直接将这样的内容放入代码中,一切都很好。但是,我想动态生成这些规则。使用常规功能,我会做这样的事情:
但是datalog
,!
和:-
都是宏,这使得这不可能。
我的解决方案是编写这个宏:
然后这样调用:
然而,虽然这确实运行,但当两者都为真时,查询 Datalog 数据库不会呈现任何a
内容b
。
我尝试对语法对象进行双引号,这样我就可以看到正在输出的内容,它是这样的:
所以......如果我直接在我的代码中输入它应该和确实有效!这里发生了什么?这是某种卫生的宏观事物吗?我真的不知道。
谢谢!
编辑:这是该问题的完整可运行示例。