【问题标题】:Scheme allow uppercase define方案允许大写定义
【发布时间】:2021-04-26 20:29:00
【问题描述】:

要在方案中定义square,我可以执行以下操作:

(define (square x) (* x x)

但是,如果我使用大写字母 DEFINE,我会得到一个无效的标识符:

(DEFINE (square x) (* x x)

有没有办法做如下的事情?

#lang sicp
; using DrRacket
(define (DEFINE) define) ; sort of a macro where DEFINE expands to define

【问题讨论】:

  • 由于DEFINE是语法,你不能用define定义它。您需要将其定义为宏。
  • @Barmar 对,用宏怎么做?
  • 您可以做的另一件事是将#ci(begin ...) 包裹在模块的整个主体周围。 #ci 前缀将 Racket 的阅读器切换到不区分大小写的模式(这实际上意味着它将读取的任何符号小写)以用于下一个 S 表达式。
  • @RyanCulpepper 哦,太好了,谢谢!

标签: scheme lisp racket


【解决方案1】:

您需要使用宏来创建使用define 语法的语法,并且该宏需要能够以define 可以采用的所有方式接受参数。

对于 R6RS 方案,R6RS says:

(define <variable> <expression>)‌‌           syntax 
(define <variable>)‌‌                        syntax 
(define (<variable> <formals>) <body>)‌‌     syntax 
(define (<variable> . <formal>) <body>)‌‌    syntax

由于 R6RS Scheme define 语法至少需要一个参数,因此该宏至少需要一个参数,并且它允许上述所有用途。请注意,(_ e1 e2 ...) 模式匹配 _DEFINE,然后是 一个 或多个表达式:

(define-syntax DEFINE
  (syntax-rules ()
    ((_ e1 e2 ...)
     (define e1 e2 ...))))

Racket 的define 语法至少需要两个 参数,R5RS 和R7RS 方案中的define 也是如此。 sicp 语言遵循 R5RS,因此 #lang sicp 中的 define 也应该需要两个参数。 Racket 有一个方便的define-syntax-rule 形式,它比define-syntax 更简洁,尽管两者都可以在这里工作。请注意,模式 (DEFINE e1 e2 e3 ...) 匹配 DEFINE 然后是 两个 或更多表达式:

#lang racket

(define-syntax-rule (DEFINE e1 e2 e3 ...) (define e1 e2 e3 ...))

但是,sicp 语言没有 define-syntax-rule,所以我们将不得不满足于 define-syntax,使用 R5RS 中的模式匹配:

#lang sicp

(define-syntax DEFINE
  (syntax-rules ()
    ((_ e1 e2 e3 ...)
     (define e1 e2 e3 ...))))

最终#lang sicp 定义的一些示例用法:

> (DEFINE x 42)
> x
42
> (DEFINE (my-add x y) (+ x y))
> (my-add 1 2)
3
> (DEFINE (my-list . xs) xs)
> (my-list 1 2 3)
(1 2 3)
> (DEFINE (my-args a b . c) (cons (list a b) c))
> (my-args 1 2 3 4 5)
((1 2) 3 4 5)

这两个中的第一个在 R6RS 方案中是合法的,但在 R5RS 或 R7RS 方案中不合法,#lang racket#lang sicp

> (DEFINE x)
; define-uppercase.rkt:56:0: DEFINE: bad syntax
;   in: {DEFINE x}
> (DEFINE)
; define-uppercase.rkt:57:0: DEFINE: bad syntax
;   in: {DEFINE}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-26
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    相关资源
    最近更新 更多