有啥方法可以首先获取参数,最后在球拍中的函数中获取名称?

Posted

技术标签:

【中文标题】有啥方法可以首先获取参数,最后在球拍中的函数中获取名称?【英文标题】:Is there any way to take at first the arguments and at last the name in a function in racket?有什么方法可以首先获取参数,最后在球拍中的函数中获取名称? 【发布时间】:2021-05-10 15:18:38 【问题描述】:

我被要求在球拍中编写一个程序,以便将算术运算符的行为从前缀更改为后缀。更确切地说: 我希望这段代码:(a b +) 的行为类似于:(+ a b)

我想使用define-syntax-rule 来改变+ 运算符的行为,但我有一个问题,在使用define-syntax-rule 时,我们首先编写宏的名称,然后编写参数。 我的问题:有没有办法在球拍函数中写出开头的参数和最后的名字?

【问题讨论】:

【参考方案1】:

完成此操作的最简单方法是创建自己的#%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 ...))

使用.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 变成了一种惰性语言。

【讨论】:

非常感谢,这工作得很好。你能简单解释一下 lang.rkt 中的代码吗? 当然!我编辑了帖子以添加解释。 @LeifAndersen, IIRC, #lang s-exp 不需要,对吧?你可以require它。 这基本上是正确的。我不使用require 的原因是因为你会遇到#%app 高于要求(原始球拍#%app,低于要求(新的#%app)的情况。我找到了线索可能会混淆代码。

以上是关于有啥方法可以首先获取参数,最后在球拍中的函数中获取名称?的主要内容,如果未能解决你的问题,请参考以下文章

球拍中的make-hash make-weak-hash有啥区别?

有啥方法可以在不使用 Nest.js 中的 async/await 的情况下从数据库中获取数据?

在js中获取作成者

js怎样获取某个特殊字符最后出现的位置

js怎样获取某个特殊字符最后出现的位置

有啥方法可以通过 Python 中的 id 获取对象的大小?