exercise 1, racket school 2018

39 views
Skip to first unread message

Robert Girault

unread,
Jun 17, 2019, 10:20:44 AM6/17/19
to Racket
I was able to do the first half of exercise 1 (see sources at the end
of this message) --- write a macro computing some information at
run-time. The second half is to write the same macro, but computing
some information at compile-time --- I couldn't do this one. I'm
looking for some directions on how to achieve this.

(*) Context

; Syntax -> Syntax
; (define-world* name ...) defines all name ... to stand for a string
(define-syntax (define-world* stx)
(syntax-parse stx
((_ x:id ...)
#'(define-values (x ...) (values (begin 'x "world") ...)))))

(*) Exercise 1

Exercise 1. Modify define-world* so that it binds each given
identifier to its place in the sequence. We start counting at 0 so
that

(define-world* x y z)

binds x to 0, y to 1, and so on.

Consider two variants: one that compiles the values at compile time
and another one that computes them at run time. The second one might
be a bit easier, but do try your hands at both.

(*) My first solution

; Syntax -> Syntax
; (define-naturals-runtime* ...) defines all names ... each to natural
; number beginning at 0 (we use a counter computed at runtime).
(define-syntax (define-naturals-runtime* stx)
(syntax-parse stx
((_ x:id ...)
#'(begin
(define n -1)
(begin
(set! n (add1 n))
(define x n)) ...))))

(*) Compile-time version

That's my trouble. Here's what I wrote.

(define-syntax (define-naturals* stx)
(define n -1)
(syntax-parse stx
((_ x:id ...)
#`(begin
(begin
#,(set! n (add1 n))
(define x #,n)) ...))))

> (syntax->datum (expand-once '(define-naturals* a b c)))
'(begin
(begin #<void> (define a 0))
(begin #<void> (define b 0))
(begin #<void> (define c 0)))

I see (set! n (add1 n)) took place once --- at compile-time. I
expected something like:

'(begin
(begin #<void> (define a 0) (set! n 1))
(begin #<void> (define b 1) (set! n 2))
(begin #<void> (define c 2) (set! n 3)))

I think I don't understand the real definition of "...".

Thank you.

Sources:
https://summer-school.racket-lang.org/2018/plan/mon-mor-lecture.html
https://summer-school.racket-lang.org/2018/plan/mon-mor-lab.html

Ryan Culpepper

unread,
Jun 17, 2019, 11:06:30 AM6/17/19
to Robert Girault, Racket
On 6/17/19 4:20 PM, Robert Girault wrote:
> I was able to do the first half of exercise 1 (see sources at the end
> of this message) --- write a macro computing some information at
> run-time. The second half is to write the same macro, but computing
> some information at compile-time --- I couldn't do this one. I'm
> looking for some directions on how to achieve this.
>
> (*) Context
>
> ; Syntax -> Syntax
> ; (define-world* name ...) defines all name ... to stand for a string
> (define-syntax (define-world* stx)
> (syntax-parse stx
> ((_ x:id ...)
> #'(define-values (x ...) (values (begin 'x "world") ...)))))
>
> (*) Exercise 1
>
> Exercise 1. Modify define-world* so that it binds each given
> identifier to its place in the sequence. We start counting at 0 so
> that
>
> (define-world* x y z)
>
> binds x to 0, y to 1, and so on.

Hint 1: If you were going to translate this one example by hand, here's
one way to do it:

(define-values (x y z) (values 0 1 2))

Hint 2: Here's another way to do it:

(begin (define x 0) (define y 1) (define z 2))

Why might the first version be "better" than the second version (from a
macro-writer's point of view, at least)?

Ryan
Reply all
Reply to author
Forward
0 new messages