标签: define-syntax

了解Scheme宏的来源:define-syntax和syntax-rules

我已经阅读了JRM的非常偏心的语法规则入门,它帮助我理解了语法规则以及它与common-lisp的define-macro的不同之处.syntax-rules只是在define-syntax中实现语法转换器的一种方法.

我正在寻找两件事,第一件是语法规则的更多示例和解释,第二件是学习使用define-syntax的其他方法的好资料.你推荐什么资源?

lisp macros scheme syntax-rules define-syntax

10
推荐指数
2
解决办法
5687
查看次数

如何在语法规则中使用矢量模式?

我一直在编写Common Lisp宏,所以Scheme的R5Rs宏对我来说有点不自然.我我有了这个想法,除了我不明白如何在语法规则中使用矢量模式:

(define-syntax mac
  (syntax-rules ()
    ((mac #(a b c d))
     (let ()
       (display a)
       (newline)
       (display d)
       (newline)))))

(expand '(mac #(1 2 3 4)))  ;; Chicken's expand-full extension shows macroexpansion

=> (let746 () (display747 1) (newline748) (display747 4) (newline748))
Run Code Online (Sandbox Code Playgroud)

我不知道我是如何使用一个需要将其参数写成向量的宏:

(mac #(1 2 3 4))
=>
1
4
Run Code Online (Sandbox Code Playgroud)

是否有某种技术使用这些模式?

谢谢!

lisp macros scheme syntax-rules define-syntax

6
推荐指数
1
解决办法
195
查看次数

在Scheme中捕获宏

使用define-syntaxdefine-syntax-rule在Racket中定义捕获宏的最简单方法是什么?

作为一个具体的例子,这里aif是CL风格的宏系统中的微不足道的.

(defmacro aif (test if-true &optional if-false)
    `(let ((it ,test))
        (if it ,if-true ,if-false)))
Run Code Online (Sandbox Code Playgroud)

这个想法是,it将被绑定到的结果testif-trueif-false条款.天真的音译(减去可选的替代方案)是

(define-syntax-rule (aif test if-true if-false)
    (let ((it test))
       (if it if-true if-false)))
Run Code Online (Sandbox Code Playgroud)

在没有投诉的情况下进行评估,但如果您尝试it在子句中使用则会出错:

> (aif "Something" (displayln it) (displayln "Nope")))
reference to undefined identifier: it
Run Code Online (Sandbox Code Playgroud)

anaphora实现aif

(define-syntax aif
  (ir-macro-transformer
   (lambda (form inject compare?)
     (let ((it (inject 'it)))
       (let ((test (cadr form))
         (consequent (caddr …
Run Code Online (Sandbox Code Playgroud)

macros scheme define-syntax racket

6
推荐指数
1
解决办法
754
查看次数

嵌套表达式的Scheme宏

是否可以在Scheme中编写一个宏(define-syntax例如),它将采用这样的表达式:

(op a b c d e f g h i j)
Run Code Online (Sandbox Code Playgroud)

并将这样的表达式作为输出?

(op (op (op (op (op (op (op (op (op a b) c) d) e) f) g) h) i) j) 
Run Code Online (Sandbox Code Playgroud)

当然,任意长度.考虑到这样的一些模板,我想不出办法来做到这一点:

(define-syntax op
  (syntax-rules ()
    [(_) 'base-case]
    [(v1 v2 ...) 'nested-case??]))
Run Code Online (Sandbox Code Playgroud)

macros scheme nested define-syntax

5
推荐指数
1
解决办法
663
查看次数

如果有的话,这个方案中letrec的定义有什么问题?

R5RS为库语法形式提供了建议的宏定义:

http://schemers.org/Documents/Standards/R5RS/HTML/r5rs-ZH-10.html#%_sec_7.3

其中也以一种非常复杂的方式定义了letrec,当然不是我如何定义它,我会简单地使用:

(define-syntax letrec2
  (syntax-rules ()
    ((letrec2 ((name val) ...) body bodies ...)
     ((lambda ()
       (define name val) ...
       body bodies ...)))))
Run Code Online (Sandbox Code Playgroud)

据我所知,letrec的语义,我经常使用它作为命名let.它的工作原理这样,但是我有我与谁认为他们可以否定了狭义相对论或建立语音理论哲学家争论的公平份额,我知道,当你认为你有一个简单的解决一个复杂的问题,它可能错误.必须要有一点,这个宏不能满足letrec的语义,否则他们可能已经使用过了.

在这个定义中,定义是letrec主体的局部定义,它们可以相互引用相互递归,我不太确定是什么(如果有的话)是错误的.

macros scheme define-syntax

5
推荐指数
2
解决办法
920
查看次数

这个定义语法宏在方案中有什么问题?

我正在为SICP工作,并希望尝试一些诡计的例子.我正在尝试流示例,并想要一个cons-stream的实现,我从这个StackOverflow问题得到了.然而当我把它打成诡计时,我得到:

guile> (define-syntax cons-stream
  (syntax-rules ()
  [(cons-stream x y) (cons x (delay y))]))
ERROR: invalid syntax ()
ABORT: (misc-error)
Run Code Online (Sandbox Code Playgroud)

我不知道这有什么问题 - 我尝试用'()替换(),删除[],但它仍然不起作用,即使它似乎是有效的R5RS.我目前正在使用guile 1.8.7,我看不到GNU文档提到的v2.0.1的包,这可能就是为什么它不能为我工作?

macros scheme guile define-syntax

5
推荐指数
1
解决办法
920
查看次数

可以使用"call/cc"实现"if"吗?

我被告知"call/cc"可用于实现任意控制流构造,所以我试图使用"call/cc"来实现所有这样的构造,但是我遇到了麻烦.假设我没有"if",我将如何使用"define-syntax"和"call/cc"来实现它?有可能或者我被误导了吗?我知道如何使用"call/cc"实现无条件跳转,但在机器级别使用分支指令执行条件执行,分支指令的执行取决于处理器的状态位.如果没有这种类型的结构,我看不出它是如何完成的.

scheme functional-programming callcc define-syntax control-flow

5
推荐指数
1
解决办法
293
查看次数

使用宏在Scheme中柯里化函数

我正在学习Scheme 中的宏系统,我认为实现柯里化函数将是一个好的开始。这是我煮的:

(define-syntax function
    (syntax-rules ()
        ((_ () body ...) (lambda () body ...))
        ((_ (param) body ...) (lambda (param) body ...))
        ((_ (param_1 param_2 params ...) body ...) (lambda (param_1 . rest)
            (let ((k (function (param_2 params ...) body ...)))
                (if (null? rest) k (apply k rest)))))
        ((_ name params body ...) (define name (function params body ...)))))
Run Code Online (Sandbox Code Playgroud)

这段代码按预期工作。例如我可以定义一个add函数如下:

(function add (x y) (+ x y))
Run Code Online (Sandbox Code Playgroud)

然后我就可以正常调用它了:

(add 2 3) ; => 5
Run Code Online (Sandbox Code Playgroud)

此外,我可以轻松地部分应用它:

(map (add 10) …
Run Code Online (Sandbox Code Playgroud)

lisp macros scheme define-syntax currying

5
推荐指数
1
解决办法
900
查看次数

有没有办法在Racket或任何其他Scheme中定义编译时(扩展时)宏变量?

举个简单的例子:

(define-macro-variable _iota 0) ; define-macro-variable does not really exist

(define-syntax (iota stx)
  (syntax-case stx ()
    ((iota)
     (let ((i _iota))
       (set! _iota (+ i 1))
       #`#,i))))
Run Code Online (Sandbox Code Playgroud)

这样给出:

(define zero (iota))
(define one-two-three (list (iota) (iota) (iota)))
(define (four) (iota))
Run Code Online (Sandbox Code Playgroud)

以下都应评估为#t:

(equal? zero 0)
(equal? one-two-three '(1 2 3)) ; possibly in a different order
(equal? (four) 4)
(equal? (four) 4)
(equal? (four) 4)
Run Code Online (Sandbox Code Playgroud)

是否有任何真正的球拍功能define-macro-variable可以完成上述示例中应该执行的操作?

编辑:

我找到了解决办法:

(define-syntaxes (macro-names ...)
  (let (macro-vars-and-vals ...)
    (values macro-bodies-that-nead-the-macro-vars ...)))
Run Code Online (Sandbox Code Playgroud)

但我更喜欢一种解决方案,它不需要使用宏变量的所有宏都在一个表达式中.

macros scheme define-syntax racket

5
推荐指数
1
解决办法
292
查看次数

定义多个顶级表单的球拍宏?

我发现自己使用相同的定义来定义语法参数,除了它们的名称,所以我决定编写一个宏来使这更简单:

(define-syntax (test-case-parameter stx)
  (syntax-parse stx
    [(_ parameter:id)
     #'(define-syntax-parameter parameter
         (lambda (stx)
           (raise-syntax-error stx "Can only be used inside test-case.")))]))

(test-case-parameter a)
(test-case-parameter b)
(test-case-parameter c)
Run Code Online (Sandbox Code Playgroud)

然而,我不想重复宏名称,我希望能够写:

(test-case-parameter a b c)
Run Code Online (Sandbox Code Playgroud)

但是我没有看到如何使用普通的省略号语法来实现这一点,因为我需要将所有内容包装在一个begin可以创建新范围的内容中,并且我希望所有的语法参数就好像我已经为每个顶部写了一样水平.什么是正确的方法来实现这一目标?

macros define-syntax variadic racket toplevel

5
推荐指数
1
解决办法
160
查看次数