Scheme允许大写定义



要在方案中定义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表示:

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

由于R6RS Schemedefine语法至少需要一个参数,因此此宏至少需要一个子参数,并且它将允许以上所有用途。请注意,模式(_ 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}

相关内容

  • 没有找到相关文章

最新更新