guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: unhandled constant?


From: Taylan Kammer
Subject: Re: unhandled constant?
Date: Sat, 1 Feb 2020 22:55:15 +0100
User-agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.4.1

> (defmacro define-session (name value)
>   (define (inner n v)
>     (set! decl
>         (cons
>          (make-var n v)
>          decl))
>     )
>   `(,inner ',name ,value))

The problem here is that the macro output

  `(,inner ',name ,value)

would include a #<procedure> object, because it evaluates 'inner', which
has been defined as a procedure.  The raw output would look something
like this:

  (#<procedure inner (a b)> 'foo "bar)

And the compiler tries to put that into a file.  But procedure objects
cannot be put into a file.

(They cannot be "serialized" i.e. turned back into text.  Hence the
clumsy "#<procedure ...>" thing which tells us a bit about the procedure
like its name and the number of arguments it takes but doesn't actually
include its code.)

That's why the compiler chokes.  It could put a constant like the number
982346 or the string "foo" or the vector #(x 4 "blah") into the output
it generates, because all those objects can be serialized, but a
procedure object cannot be truly serialized.

Note that something like (lambda () ...) is NOT a procedure; it's a
list.  Such a list can be evaluated as Scheme code, within a larger
context (an "environment"), which then yields a procedure object, but
that resulting procedure object cannot be turned back into text, because
it might be relying on the environment in which it was defined.

Like others pointed out, there's a couple of ways to rewrite that code
to avoid putting a procedure object straight into the macro output.  For
instance, you could put the definition of the procedure into the output,
so it will be evaluated (turned into a procedure) at run-time:

  (defmacro define-session (name value)
    `(begin
       (define (inner n v)
         (set! decl
             (cons
              (make-var n v)
              decl))
         )
       (inner ',name ,value)))

I'm not sure if this code will work verbatim in 1.8 and 2.2, but you get
the idea: don't put procedures into macro output.

- Taylan


On 29.01.2020 00:08, Han-Wen Nienhuys wrote:
> Some of the lilypond Scheme files do the following:
> 
> 
> (define decl '())
> (define (make-var n v) (list "var" n v))
> (defmacro define-session (name value)
>   (define (inner n v)
>     (set! decl
>         (cons
>          (make-var n v)
>          decl))
>     )
>   `(,inner ',name ,value))
> (define-session foo 1)
> (display decl)
> (newline)
> 
> In GUILE 2.2, this yields
> 
> ;;; WARNING: compilation of /home/hanwen/vc/lilypond/q.scm failed:
> ;;; unhandled constant #<procedure inner (a b)>
> 
> What does this error message mean, and what should I do to address the 
> problem?
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]