如何解决定义球拍的子集
由于Racket以创建新编程语言的能力而闻名,因此以下内容应该不会太难。
我想为教育目的创建一个Racket子集(将其命名为min
),以重命名某些功能(tail
而不是cdr
)并忽略其他功能(例如{ {1}}和string=?
只有=
)。
我要做的第一步是使用equal?
启动min
文件,但是我仍然处于扩展阶段。
解决方法
以下模块是Racket的最小子集的示例,该子集允许使用+
和*
进行顶级定义,常量和算术运算:
;; min.rkt
#lang racket/base
(provide #%module-begin #%top-interaction
#%app #%datum #%top
define + *)
以下是提供的含义:
-
模块必须提供
-
#%module-begin
,该模块才能被视为“语言”;它确定模块主体的含义。您可以重复使用Racket的module-begin宏。 (#%module-begin
导出为您提供了实现非本地约束或转换的钩子。例如,如果您想添加类型检查器或检查是否按字母顺序定义了变量,则可以在模块开头的钩子中执行此操作。) -
#%top-level
对于交互式语言是必需的。如果不加说明,则不能为您的语言使用REPL(例如,使用racket -t "min.rkt" -i
)。 -
#%app
和#%datum
使函数应用程序和自评估常量(例如数字和布尔值)起作用。 -
#%top
使前向引用在REPL上起作用,就像在相互递归函数中一样。当然,在评估对该名称的引用之前,您仍然必须定义一个名称。 - 其余的导出内容是您要包括在语言中的特殊形式和功能。
这是一种使用"min.rkt"
语言的程序:
#lang s-exp "min.rkt"
(define x 2)
(define y (+ x 5))
(* y 7)
(define (f x) (+ x x 1))
(f 8)
请注意,由于该语言包含Racket的define
,因此即使该语言不包含lambda
,它也允许函数定义。如果您想要受限制的define
版本,则必须定义自己的宏,并将其作为您语言的define
,例如(provide (rename-out [my-define define]))
。
您还可以使用rename-out
以cdr
的形式提供Racket的tail
,但是该过程仍将打印为#<procedure:cdr>
,并且如果出现错误,则错误消息仍然会说cdr
。要更改此设置,您需要定义自己的包装函数,该函数执行自己的错误检查。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。