有没有办法首先在球拍的函数中获取参数,最后获取名称?
Is there any way to take at first the arguments and at last the name in a function in racket?
我被要求在球拍中编写一个程序,以便将算术运算符的行为从前缀更改为后缀。更确切地说:
我希望这段代码:(a b +)
表现得像:(+ a b)
我想使用 define-syntax-rule
来改变 + 运算符的行为,但我有一个问题,在使用 define-syntax-rule
时我们首先写了宏的名称,然后我们写的论据。
我的问题:有没有什么办法可以在球拍函数中把参数写在开头,最后写名字?
完成此操作的最简单方法是创建您自己的 #%app
宏。由于您实际上是在此处创建一种新语言,因此您需要两个模块:一个定义您的语言的 'lang' 模块,以及一个用于您要用该语言编写的程序的 'use' 模块。这可以用两个文件或一个文件使用子模块来完成。
在这里,我将使用两个文件向您展示:
lang.rkt
#lang racket
(provide (except-out (all-from-out racket)
#%app)
(rename-out [-app #%app]))
(require syntax/parse/define)
(define-syntax-parse-rule (-app args ... proc)
(#%app proc args ...))
use.rkt
#lang s-exp "lang.rkt"
(3 2 +) ; => 5
请注意,这只会更改函数调用,不会更改其他形式。所以:
use2.rkt
#lang s-exp "lang.rkt"
(define x 42)
(2 x *) ; => 84
编辑:
解释 lang.rkt
中发生的事情。它采用 racket
语言,并重新导出除 #%app
宏之外的所有语言。 (作为参考,球拍(f args ...)
中的所有功能应用都扩展为(#%app f args ...)
。)
对于#%app
宏,我们定义了另一个宏-app
,将函数调用从末尾移动到开头,并使用了Racket的#%app
宏。然后我们在导出时将 -app
重命名为 #%app
。
this paper 的第 5.1 节为您提供了相同内容的概述,但是将 Racket 变成了一种惰性语言。
我被要求在球拍中编写一个程序,以便将算术运算符的行为从前缀更改为后缀。更确切地说:
我希望这段代码:(a b +)
表现得像:(+ a b)
我想使用 define-syntax-rule
来改变 + 运算符的行为,但我有一个问题,在使用 define-syntax-rule
时我们首先写了宏的名称,然后我们写的论据。
我的问题:有没有什么办法可以在球拍函数中把参数写在开头,最后写名字?
完成此操作的最简单方法是创建您自己的 #%app
宏。由于您实际上是在此处创建一种新语言,因此您需要两个模块:一个定义您的语言的 'lang' 模块,以及一个用于您要用该语言编写的程序的 'use' 模块。这可以用两个文件或一个文件使用子模块来完成。
在这里,我将使用两个文件向您展示:
lang.rkt
#lang racket
(provide (except-out (all-from-out racket)
#%app)
(rename-out [-app #%app]))
(require syntax/parse/define)
(define-syntax-parse-rule (-app args ... proc)
(#%app proc args ...))
use.rkt
#lang s-exp "lang.rkt"
(3 2 +) ; => 5
请注意,这只会更改函数调用,不会更改其他形式。所以:
use2.rkt
#lang s-exp "lang.rkt"
(define x 42)
(2 x *) ; => 84
编辑:
解释 lang.rkt
中发生的事情。它采用 racket
语言,并重新导出除 #%app
宏之外的所有语言。 (作为参考,球拍(f args ...)
中的所有功能应用都扩展为(#%app f args ...)
。)
对于#%app
宏,我们定义了另一个宏-app
,将函数调用从末尾移动到开头,并使用了Racket的#%app
宏。然后我们在导出时将 -app
重命名为 #%app
。
this paper 的第 5.1 节为您提供了相同内容的概述,但是将 Racket 变成了一种惰性语言。