- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试理解 Racket 环境中的宏。这个概念让我很感兴趣。
在 Dr. Racket 的定义窗口上写下这个定义后:
(define-syntax foo
(lambda (stx)
(syntax "I am foo")))
我使用 REPL 调用了以下表达式:
> foo
"I am foo"
> (foo)
"I am foo"
这些结果让我感到惊讶。对于 foo 的第一次调用,我期待类似 #procedure
的东西。
为什么 (foo) 和 foo 提供相同的输出?
通常,我在 Racket 中添加括号时非常小心。通常,它们会完全改变被调用表达式的含义。在这种情况下,显然没有任何区别。
提前致谢。
最佳答案
Usually, I am pretty careful about adding parenthesis in Racket.
是的,你要小心是对的。它通常会产生影响。
然而,在您的情况下,它似乎没有什么区别,因为您正在创建一个过于简单的宏,无论宏是作为常规转换器还是作为 identifier macro 调用,它的扩展方式都是一样的。 .
I was expecting something like a #procedure for the first call on foo.
我想先解决这个问题。宏在句法上改变你的程序。例如,我可以编写一个宏 flip
来翻转操作数,这样
(flip foo 1 (let) bar baz 2)
被扩展(不是评估)到:
(2 baz bar (let) 1 foo)
再次,我想强调的是,这是一种程序转换,就像您如何使用编辑器编辑代码一样。
现在,让我们编写一些实际的宏:
(define-syntax bar
(lambda (stx)
(cond
[(equal? (syntax->datum stx) '(bar abc def)) #'(+ 1 1)]
[else #'(+ 2 2)])))
(bar abc def) ;== expands => (+ 1 1) == evaluates => 2
(bar 42 (abc) qqq) ;== expands => (+ 2 2) == evaluates => 4
(bar) ;== expands => (+ 2 2) == evaluates => 4
在上面的宏中,它检查输入语法在句法上是否为(bar abc def)
。如果是,它将转换为 (+ 1 1)
。否则,它转换为 (+ 2 2)
。
所有这些都是为了向您表明,期望宏产生“#procedure”是不合理的(当然,除非宏扩展为 lambda),因为宏所做的是转换语法。它不会创建过程。
最后的谜团是裸露的 foo
发生了什么。让我们创建一个宏 baz
来理解这一点:
(define-syntax baz
(lambda (stx)
(cond
[(equal? (syntax->datum stx) 'baz) #'1]
[(equal? (syntax->datum stx) '(baz)) #'2]
[else #'3])))
baz ;== expands => 1
(baz) ;== expands => 2
(baz 10) ;== expands => 3
事实证明,一个裸标识符也可以是一个宏!
现在,考虑您的 foo
:
(define-syntax foo
(lambda (stx)
(syntax "I am foo")))
这是一个忽略其操作数的转换,并且总是扩展为 "I am foo"
。
所以:
(foo 1 2 3) ;== expands => "I am foo"
(foo x y z) ;== expands => "I am foo"
(foo) ;== expands => "I am foo"
foo ;== expands => "I am foo"
请注意,在大多数宏中,我们使用模式匹配来提取操作数。当输入语法不匹配任何模式时,模式匹配会引发语法错误。例如,这允许我们创建一个不允许将其用作标识符宏的宏。
(define-syntax food
(lambda (stx)
(syntax-case stx ()
;; match when there is a parenthesis around the macro
[(_ ...) #'1])))
(food) ;=> 1
food ;=> food: bad syntax
关于macros - 为什么 foo 与这个 Racket 宏中的 (foo) 具有相同的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66726427/
public class Foo : IFoo ... 和有什么区别 IFoo foo = new Foo(); 和 Foo foo = new Foo(); 最佳答案 区别仅在于变量的声明类型。每当
class Foo { public: explicit Foo() {} explicit Foo(Foo&) {} }; Foo d = Foo(); error: no matc
是 foo as? Foo完全等同于 foo as Foo? ? 如果是,那为什么两者都有? 如果不是,那么有什么区别? 最佳答案 as?是 safe cast operator . 通常,如果您尝试
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
这个问题在这里已经有了答案: Why is there an injected class name? (1 个回答) 关闭5年前。 一位同事不小心写了这样的代码: struct foo { fo
我遇到了这些关键字::foo、::foo、::bar/foo 和 :bar/foo 您能举例说明差异吗? 最佳答案 :foo 是一个非完全限定的关键字。它没有关联的命名空间。 (name :foo)
有人问我如何简化这个 lambda (Foo foo) -> foo.getName() 还有更好的写法吗? 最佳答案 Foo::getName。 假设getName是一个实例方法,其签名中的参数列表
编写此规则集的 CSS 组合器或简写是什么? foo bar, foo biz, foo gaz > boo, foo tar { ... } 我很确定我在 MDN 的某处读到过有一个。是不是: f
我有一个用这个字符串填充的输入文本 "foo foo"但插入后字符串看起来像这样 "foo foo" .我该如何解决?我想以第一种格式显示字符串! 最佳答案 你可能有这样的事情: " /> 更改 va
假设我有一个不可复制类Foo,它的构造函数之一恰好接收到对 Foo 的引用。 class Foo { public: Foo(Foo& parent) {...} private: v
class Artist @@song_count = [] attr_accessor :name, :songs def initialize(name) @name = name
请解释为什么这些 Perl 函数的调用方式在函数定义之上决定了它们是否运行。 print "Why does this bare call to foo not run?\n"; foo; print
文件名分为三种类型 首先( Root 于某种“当前工作目录”之下) ../foo ./foo bar/foo # really in this group? 和( Root 于绝对路径,独立于 CWD
我想自动连接 foo: @Autowired Foo foo 但我无法修改类 Foo 并将其标记为 @Component。 Autowiring foo 最干净的方法是什么? 顺便说一句,如果您需要使
我一直在使用 Python 的 ElementTree 创建 XML 文档,到目前为止一切顺利。然而我现在面临的问题是,由于项目要求,我需要生成一个 XML 文档,其中包含带有开始和结束标签的元素以及
class Foo { public: Foo(){} private: Foo(const Foo &); }; Foo f(); Foo f1 = Foo(); 我发现当我将 Fo
我有一个 jquery 对话框,上面有一个按钮(我的按钮,不是对话框按钮之一)。 设置对话框后,我有以下代码: $('#bar').click(foo('baz')); 当我加载页面并显示对话框时,f
我遇到了以下变量的情况: var foo: Foo | Foo | Foo; 动态生成(使用 keyof 和 stuff),这在代码的那个点是完全有意的。但是,我需要调用像这样定义的对象内部的方法:
clang 3.5.0 和 gcc 4.9.1 从代码生成的可执行文件 #include struct Foo { Foo() { std::cout << "Foo()" << std::e
对于声明为 Foo& foo = ...; 的 foo,lambdas 的按值捕获和按引用捕获语义之间有什么区别吗? 最佳答案 我认为你已经陷入了一个常见的误解......引用是对真实对象的别名。初始
我是一名优秀的程序员,十分优秀!