方案允许大写定义
Scheme allow uppercase define
要在方案中定义 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
可以采用的所有方式接受参数。
对于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 Scheme 中的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}
要在方案中定义 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
可以采用的所有方式接受参数。
对于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 Scheme 中的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}