Reputation: 110502
To define a square
in scheme I can do the following:
(define (square x) (* x x)
However, if I use a capital DEFINE
, I get an invalid identifier:
(DEFINE (square x) (* x x)
Is there a way to do something like the following?
#lang sicp
; using DrRacket
(define (DEFINE) define) ; sort of a macro where DEFINE expands to define
Upvotes: 1
Views: 84
Reputation: 21360
You need to use a macro to create syntax that uses the define
syntax, and the macro needs to be able to take arguments in all of the ways that define
can.
For R6RS Scheme, R6RS says:
(define <variable> <expression>) syntax
(define <variable>) syntax
(define (<variable> <formals>) <body>) syntax
(define (<variable> . <formal>) <body>) syntax
Since the R6RS Scheme define
syntax requires at least one argument, this macro requires at least one argument, and it will allow all of the above uses. Note that the pattern (_ e1 e2 ...)
matches _
with DEFINE
, and then one or more expressions:
(define-syntax DEFINE
(syntax-rules ()
((_ e1 e2 ...)
(define e1 e2 ...))))
Racket's define
syntax requires at least two arguments, and this is also true of define
in R5RS and R7RS Scheme. The sicp
language follows R5RS, so the define
in #lang sicp
should also require two arguments. Racket has a convenient define-syntax-rule
form that is more concise than define-syntax
, though either would work here. Note that the pattern (DEFINE e1 e2 e3 ...)
matches DEFINE
and then two or more expressions:
#lang racket
(define-syntax-rule (DEFINE e1 e2 e3 ...) (define e1 e2 e3 ...))
But, the sicp
language does not have define-syntax-rule
, so we will have to settle for define-syntax
, with pattern matching as in R5RS:
#lang sicp
(define-syntax DEFINE
(syntax-rules ()
((_ e1 e2 e3 ...)
(define e1 e2 e3 ...))))
Some example uses of the final #lang sicp
definition:
> (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)
The first of these two would be legal in R6RS Scheme, but not in R5RS or R7RS Scheme, #lang racket
, or #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}
Upvotes: 3