Strange 3d value problem

113 views
Skip to first unread message

Jay McCarthy

unread,
Jul 27, 2017, 3:41:29 PM7/27/17
to Racket Developers
I don't understand why the last macro invocation here fails, given
that m4 shows you can store hasheqs and m5 shows you can store
identifiers and m1 shows you can store foos.

#lang racket/base
(require (for-syntax racket/base))
(begin-for-syntax
(struct foo (x y) #:prefab))

(define-syntax e1 (foo #'e1 2))

(define-syntax (m1 stx)
(syntax-case stx ()
[(_ x)
(quasisyntax (define-syntax x #,(foo #'x 2)))]))

(define-syntax e7 (make-hasheq))

(define-syntax (m4 stx)
(syntax-case stx ()
[(_ x)
(let ([ht (make-hasheq)])
(quasisyntax (define-syntax x #,ht)))]))
(m4 e8)

(define-syntax (m5 stx)
(syntax-case stx ()
[(_ x)
(quasisyntax (define-syntax x #,(foo #'x #'x)))]))
(m5 e9)

(define-syntax (m6 stx)
(syntax-case stx ()
[(_ x)
(let ([ht (make-hasheq)])
(hash-set! ht 'y #'x)
(quasisyntax (define-syntax x #,(foo #'x ht))))]))
(m6 e10)

--
-=[ Jay McCarthy http://jeapostrophe.github.io ]=-
-=[ Associate Professor PLT @ CS @ UMass Lowell ]=-
-=[ Moses 1:33: And worlds without number have I created; ]=-

Matthew Flatt

unread,
Jul 27, 2017, 3:59:36 PM7/27/17
to Jay McCarthy, Racket Developers
What failure do you see? When I run the program, it seems to compile
and run ok.
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-dev+...@googlegroups.com.
> To post to this group, send email to racke...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-dev/CAJYbDa%3D2arSqhvknnG1JGPg7aXDALUQ
> DvUEV%3DJSBTMR6CD8psA%40mail.gmail.com.
> For more options, visit https://groups.google.com/d/optout.

Jay McCarthy

unread,
Jul 27, 2017, 4:49:17 PM7/27/17
to Matthew Flatt, Racket Developers
write: cannot marshal value that is embedded in compiled code
value: #<syntax:/tmp/t.rkt:34:4 e10>
context...:
/Users/jay/Dev/scm/plt/racket/collects/compiler/../racket/private/more-scheme.rkt:261:28
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:455:6
/Users/jay/Dev/scm/plt/racket/collects/racket/private/more-scheme.rkt:148:2:
call-with-break-parameterization
/Users/jay/Dev/scm/plt/racket/collects/racket/file.rkt:220:5
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:363:0: compile-zo*
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:572:26
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:675:14: build
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:635:0: compile-root
/Users/jay/Dev/scm/plt/racket/collects/compiler/cm.rkt:737:4
/Users/jay/Dev/scm/plt/pkgs/compiler-lib/compiler/commands/make.rkt:81:8:
for-loop
/Users/jay/Dev/scm/plt/pkgs/compiler-lib/compiler/commands/make.rkt:
[running body]
/Users/jay/Dev/scm/plt/racket/collects/raco/raco.rkt: [running body]
/Users/jay/Dev/scm/plt/racket/collects/raco/main.rkt: [running body]

This is when running "raco make" on the file

Jay

Matthew Flatt

unread,
Jul 27, 2017, 5:00:43 PM7/27/17
to Jay McCarthy, Racket Developers
At Thu, 27 Jul 2017 16:49:15 -0400, Jay McCarthy wrote:
> write: cannot marshal value that is embedded in compiled code
> value: #<syntax:/tmp/t.rkt:34:4 e10>
> context...:
> [...]
>
> This is when running "raco make" on the file

Ah, ok. To be clear, `raco make` generally doesn't work with 3-D
syntax, but certain things will happen to work, anyway.

In your example, the difference between `e10` and everything else is
that `e10` is the first example to put an identifier into a value that
cannot be in a syntax literal.

It's strange that a mutable hash table is otherwise ok. The mutable
hash table in that case is getting coerced to an immutable hash table
as a convenience for some internal data in a bytecode form. Whatever
that use of a hash table, though, it's not supposed to have syntax
objects inside.

Jay McCarthy

unread,
Jul 27, 2017, 6:55:58 PM7/27/17
to Matthew Flatt, Racket Developers
On Thu, Jul 27, 2017 at 5:00 PM, Matthew Flatt <mfl...@cs.utah.edu> wrote:
> It's strange that a mutable hash table is otherwise ok. The mutable
> hash table in that case is getting coerced to an immutable hash table
> as a convenience for some internal data in a bytecode form. Whatever
> that use of a hash table, though, it's not supposed to have syntax
> objects inside.

That's strange to me because

(define-syntax (m6 stx)
(syntax-case stx ()
[(_ x)
(let ([ht (hasheq 'y #'x)])
(quasisyntax (define-syntax x #,(foo #'x ht))))]))
(m6 e10)

works for me. (I expected the mutable thing to be coerced into an
immutable thing. In the real code, the hash can only be modified
during the initial construction.)

Should I consider the answer to be that I need to stick to things that
can be syntax literals without conversion?

Matthew Flatt

unread,
Jul 27, 2017, 7:35:34 PM7/27/17
to Jay McCarthy, Racket Developers
At Thu, 27 Jul 2017 18:55:56 -0400, Jay McCarthy wrote:
> On Thu, Jul 27, 2017 at 5:00 PM, Matthew Flatt <mfl...@cs.utah.edu> wrote:
> > It's strange that a mutable hash table is otherwise ok. The mutable
> > hash table in that case is getting coerced to an immutable hash table
> > as a convenience for some internal data in a bytecode form. Whatever
> > that use of a hash table, though, it's not supposed to have syntax
> > objects inside.
>
> That's strange to me because
>
> (define-syntax (m6 stx)
> (syntax-case stx ()
> [(_ x)
> (let ([ht (hasheq 'y #'x)])
> (quasisyntax (define-syntax x #,(foo #'x ht))))]))
> (m6 e10)
>
> works for me. (I expected the mutable thing to be coerced into an
> immutable thing. In the real code, the hash can only be modified
> during the initial construction.)
>
> Should I consider the answer to be that I need to stick to things that
> can be syntax literals without conversion?

I wonder whether that one (and some of the earlier examples) work the
way you're expecting. You'll get a symbol back if you later extract the
first field of the `foo` struct that's bound to `e10` --- not an
identifier.

In this example, the `foo` instance is being coerced to a syntax object
by `unsyntax`. The resulting syntax object is the same as

#'#s(foo x #hasheq((y . x)))

which, as an expression, self-quotes as a prefab struct containing a
symbol and a hash table mapping a symbol to a symbol.

So, that one is not 3-D code. Among your original examples, `m4` does
bind `e8` as 3-D code, but it (accidentally) gets converted to a
non-3-D code in the process of marshaling. None of the other working
examples are 3-D.

Jay McCarthy

unread,
Sep 4, 2017, 12:16:08 PM9/4/17
to Matthew Flatt, Racket Developers
When we talked in person about this, I proposed having some way of
knowing that a `datum->syntax` would fail were it to be done by the
compiler and you said that the printer has something like this...
`print-unreadable`? What was that and what did you think would be an
okay way to help me catch errors like this in a different place?
Reply all
Reply to author
Forward
0 new messages