* unhandled constant? @ 2020-01-28 23:08 Han-Wen Nienhuys 2020-01-29 15:06 ` Ricardo Wurmus ` (2 more replies) 0 siblings, 3 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-28 23:08 UTC (permalink / raw) To: guile-devel 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? -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-28 23:08 unhandled constant? Han-Wen Nienhuys @ 2020-01-29 15:06 ` Ricardo Wurmus 2020-01-30 8:05 ` Han-Wen Nienhuys 2020-01-31 14:57 ` Linus Björnstam 2020-02-01 21:55 ` Taylan Kammer 2 siblings, 1 reply; 25+ messages in thread From: Ricardo Wurmus @ 2020-01-29 15:06 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel Han-Wen Nienhuys <hanwenn@gmail.com> writes: > 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? Would it be feasible to use define-syntax-rule here? --8<---------------cut here---------------start------------->8--- (define decl '()) (define (make-var n v) (list "var" n v)) (define-syntax-rule (define-session name value) (let ((inner (lambda (n v) (set! decl (cons (make-var n v) decl))))) (inner 'name value))) (define-session foo 1) (display decl) (newline) --8<---------------cut here---------------end--------------->8--- -- Ricardo ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-29 15:06 ` Ricardo Wurmus @ 2020-01-30 8:05 ` Han-Wen Nienhuys 2020-01-31 10:49 ` Han-Wen Nienhuys ` (2 more replies) 0 siblings, 3 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-30 8:05 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: guile-devel [guile1.8]$ grep -ir define-syntax-rule . (empty) I need something that works in GUILE 1.8 too. this is what I got from David Kastrup: >Got any comments about macros being sooo yesterday compared to syntax forms? Syntax forms actually don't work in LilyPond: there was an incompatibility because the 1.8 implementation will balk if some symbol used in syntax forms already has a definition, and we have that. I forgot the exact symbol at fault. I think it was some music function name. Would there be a way that we can use our source code unchanged with GUILE 2.2? Can you explain why I get this error message? On Wed, Jan 29, 2020 at 4:06 PM Ricardo Wurmus <rekado@elephly.net> wrote: > > > Han-Wen Nienhuys <hanwenn@gmail.com> writes: > > > 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? > > Would it be feasible to use define-syntax-rule here? > > --8<---------------cut here---------------start------------->8--- > (define decl '()) > (define (make-var n v) (list "var" n v)) > (define-syntax-rule (define-session name value) > (let ((inner (lambda (n v) > (set! decl > (cons > (make-var n v) > decl))))) > (inner 'name value))) > (define-session foo 1) > (display decl) > (newline) > --8<---------------cut here---------------end--------------->8--- > > > -- > Ricardo -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-30 8:05 ` Han-Wen Nienhuys @ 2020-01-31 10:49 ` Han-Wen Nienhuys 2020-01-31 11:17 ` Ricardo Wurmus 2020-02-02 19:30 ` Jan Nieuwenhuizen 2 siblings, 0 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-31 10:49 UTC (permalink / raw) To: Ricardo Wurmus; +Cc: guile-devel On Thu, Jan 30, 2020 at 9:05 AM Han-Wen Nienhuys <hanwenn@gmail.com> wrote: > > [guile1.8]$ grep -ir define-syntax-rule . > > (empty) > > I need something that works in GUILE 1.8 too. > > this is what I got from David Kastrup: > > >Got any comments about macros being sooo yesterday compared to syntax > forms? Syntax forms actually don't work in LilyPond: there was an > incompatibility because the 1.8 implementation will balk if some symbol > used in syntax forms already has a definition, and we have that. I > forgot the exact symbol at fault. I think it was some music function > name. > > Would there be a way that we can use our source code unchanged with GUILE 2.2? > > Can you explain why I get this error message? Also, how is it possible that, when disabling auto-compilation, the whole thing works? $ GUILE_AUTO_COMPILE=0 guile2.2 q.scm ((var foo 1)) is there an evaluator in GUILE that is separate from the bytecode VM, and if so, is this evaluator guaranteed to be supported in upcoming versions of GUILE? Does the evalation without auto-compilation benefit from JIT treatment? If I want to explore this myself, how do I hack on GUILE itself? Compiling GUILE from scratch takes more than an hour for me. I assume there must be a faster way to experiment, but what is that? It looks like the HACKING file is out of date. -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-30 8:05 ` Han-Wen Nienhuys 2020-01-31 10:49 ` Han-Wen Nienhuys @ 2020-01-31 11:17 ` Ricardo Wurmus 2020-02-02 19:30 ` Jan Nieuwenhuizen 2 siblings, 0 replies; 25+ messages in thread From: Ricardo Wurmus @ 2020-01-31 11:17 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel Han-Wen Nienhuys <hanwenn@gmail.com> writes: > [guile1.8]$ grep -ir define-syntax-rule . > > (empty) > > I need something that works in GUILE 1.8 too. I suppose you could use (cond-expand (guile-2.2 …) …) to only use this with Guile 2 and fall back to the current code with Guile 1.8. > Would there be a way that we can use our source code unchanged with GUILE 2.2? > > Can you explain why I get this error message? I don’t know the answer. -- Ricardo ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-30 8:05 ` Han-Wen Nienhuys 2020-01-31 10:49 ` Han-Wen Nienhuys 2020-01-31 11:17 ` Ricardo Wurmus @ 2020-02-02 19:30 ` Jan Nieuwenhuizen 2 siblings, 0 replies; 25+ messages in thread From: Jan Nieuwenhuizen @ 2020-02-02 19:30 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel Han-Wen Nienhuys writes: > [guile1.8]$ grep -ir define-syntax-rule . > > (empty) > > I need something that works in GUILE 1.8 too. Guile 1.8 has syntax-rules after you include (ice-9 syncase). (define-syntax-rule foo ...) is just syntactic sugar for (define-syntax foo (syntax-rules () ...); see the manual. Combined with cond-expand, maybe that could work? janneke -- Jan Nieuwenhuizen <janneke@gnu.org> | GNU LilyPond http://lilypond.org Freelance IT http://JoyofSource.com | Avatar® http://AvatarAcademy.com ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-28 23:08 unhandled constant? Han-Wen Nienhuys 2020-01-29 15:06 ` Ricardo Wurmus @ 2020-01-31 14:57 ` Linus Björnstam 2020-01-31 15:16 ` Han-Wen Nienhuys ` (2 more replies) 2020-02-01 21:55 ` Taylan Kammer 2 siblings, 3 replies; 25+ messages in thread From: Linus Björnstam @ 2020-01-31 14:57 UTC (permalink / raw) To: Han-Wen Nienhuys, guile-devel Guile1.8's macros are run-time macros: they are executed directly and not transformed to output code that is then compiled. That is the reason why your code works: to newer guiles the (inner ...) is only available at expansion time. The macro output is trying to call code that does not exist at runtime! For this to be working code the (inner ...) function needs to be available in the macro expansion. I didn't read through exactly what you are trying to do, but try outputting a let: `(let ((inner (lambda (n v) (set ! ...)))) (inner ,name ,value)) I doubt you can make the old code work in newer guiles, since I doubt any scheme is a s lax about expansion time and macro time separation. -- Linus Björnstam On Wed, 29 Jan 2020, at 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? > -- > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 14:57 ` Linus Björnstam @ 2020-01-31 15:16 ` Han-Wen Nienhuys 2020-01-31 17:50 ` Han-Wen Nienhuys 2020-02-01 11:09 ` David Kastrup 2 siblings, 0 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-31 15:16 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel On Fri, Jan 31, 2020 at 3:58 PM Linus Björnstam <linus.bjornstam@veryfast.biz> wrote: > > Guile1.8's macros are run-time macros: they are executed directly and not transformed to output code that is then compiled. That is the reason why your code works: to newer guiles the (inner ...) is only available at expansion time. The macro output is trying to call code that does not exist at runtime! > > For this to be working code the (inner ...) function needs to be available in the macro expansion. I didn't read through exactly what you are trying to do, but try outputting a let: > > `(let ((inner (lambda (n v) (set ! ...)))) > (inner ,name ,value)) > > I doubt you can make the old code work in newer guiles, since I doubt any scheme is a s lax about expansion time and macro time separation. Thanks for the explanation. This makes sense. Is it possible to attach doc strings to (define-syntax .. ) declarations, and if so, where do they go? -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 14:57 ` Linus Björnstam 2020-01-31 15:16 ` Han-Wen Nienhuys @ 2020-01-31 17:50 ` Han-Wen Nienhuys 2020-01-31 18:19 ` Linus Björnstam 2020-02-01 11:09 ` David Kastrup 2 siblings, 1 reply; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-31 17:50 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel On Fri, Jan 31, 2020 at 3:58 PM Linus Björnstam <linus.bjornstam@veryfast.biz> wrote: > > Guile1.8's macros are run-time macros: they are executed directly and not transformed to output code that is then compiled. That is the reason why your code works: to newer guiles the (inner ...) is only available at expansion time. The macro output is trying to call code that does not exist at runtime! When is the code executed? If have complex set of macros to define a special type of functions (so called markup commands). Some of these refer to other markup commands through a macro. What I can observe that some of the functions involved are not called during the compilation, but others are. In particular, the function that registers a markup command using something like (module-define! (current-module) (string->symbol (format #f "~a-markup" name)) defn)) but this function is not called during the compile There is a convenience macro that is called within some function bodies, that does get called. Unfortunately, the latter convenience macro is expanded and then executed; the execution tries to then do (module-ref (current-module) (string->symbol (format #f "~a-markup" name) which fails. > For this to be working code the (inner ...) function needs to be available in the macro expansion. I didn't read through exactly what you are trying to do, but try outputting a let: > > `(let ((inner (lambda (n v) (set ! ...)))) > (inner ,name ,value)) > > I doubt you can make the old code work in newer guiles, since I doubt any scheme is a s lax about expansion time and macro time separation. > -- > Linus Björnstam > > On Wed, 29 Jan 2020, at 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? > > -- > > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > > > > -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 17:50 ` Han-Wen Nienhuys @ 2020-01-31 18:19 ` Linus Björnstam 2020-01-31 19:17 ` Han-Wen Nienhuys 0 siblings, 1 reply; 25+ messages in thread From: Linus Björnstam @ 2020-01-31 18:19 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel I'm not very familiar with how guile 1.8 works since my first guile version was 2.2, but I remember hearing Andy talk about how macro expansion was done at runtime, due to guile not being compiled. I just put one and one together and figured that the reason the macro you posted works in 1.8 must be because of what basically rounds down to no separation between runtime and expand time. Defmacro is expanded to a regular syntax case macro that first strips all syntax information and passes it to the defmacro body and the re-introduces the result. Regarding your other question: any literal string in the defmacro body is moved to the correct define-syntax placement. I don't really understand your question. With defmacro and syntax-case you can run arbitrary code. If you just output code that does module-define! that won't be run until runtime, and thus you cannot depend on the result of that module-define! during expansion. You can however wrap it in an eval-when to solve that issue. That allows you to specify when code gets run. With module-define! I personally find it all a bit icky, but I usually stay as far away from phasing as I can :) -- Linus Björnstam On Fri, 31 Jan 2020, at 18:50, Han-Wen Nienhuys wrote: > On Fri, Jan 31, 2020 at 3:58 PM Linus Björnstam > <linus.bjornstam@veryfast.biz> wrote: > > > > Guile1.8's macros are run-time macros: they are executed directly and not transformed to output code that is then compiled. That is the reason why your code works: to newer guiles the (inner ...) is only available at expansion time. The macro output is trying to call code that does not exist at runtime! > > When is the code executed? If have complex set of macros to define a > special type of functions (so called markup commands). Some of these > refer to other markup commands through a macro. > > What I can observe that some of the functions involved are not called > during the compilation, but others are. > > In particular, the function that registers a markup command using something like > > (module-define! (current-module) > (string->symbol (format #f "~a-markup" name)) defn)) > > but this function is not called during the compile > > There is a convenience macro that is called within some function > bodies, that does get called. Unfortunately, the latter convenience > macro is expanded and then executed; the execution tries to then do > > (module-ref (current-module) > (string->symbol (format #f "~a-markup" name) > > which fails. > > > > > For this to be working code the (inner ...) function needs to be available in the macro expansion. I didn't read through exactly what you are trying to do, but try outputting a let: > > > > `(let ((inner (lambda (n v) (set ! ...)))) > > (inner ,name ,value)) > > > > I doubt you can make the old code work in newer guiles, since I doubt any scheme is a s lax about expansion time and macro time separation. > > -- > > Linus Björnstam > > > > On Wed, 29 Jan 2020, at 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? > > > -- > > > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > > > > > > > > > > -- > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 18:19 ` Linus Björnstam @ 2020-01-31 19:17 ` Han-Wen Nienhuys 2020-01-31 19:52 ` Linus Björnstam 2020-01-31 20:01 ` Linus Björnstam 0 siblings, 2 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-01-31 19:17 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel On Fri, Jan 31, 2020 at 7:20 PM Linus Björnstam <linus.bjornstam@veryfast.biz> wrote: > I don't really understand your question. With defmacro and syntax-case you can run arbitrary code. If you just output code that does module-define! that won't be run until runtime, and thus you cannot depend on the result of that module-define! during expansion. You can however wrap it in an eval-when to solve that issue. That allows you to specify when code gets run. With module-define! I personally find it all a bit icky, but I usually stay as far away from phasing as I can :) eval-when looks like it might be a solution to the puzzle , but honestly, the doc at https://www.gnu.org/software/guile/manual/html_node/Eval-When.html has me mystified. When I run the example through guile 2.2 and display *compilation-date*, I get a different answer each time. Shouldn't it be a fixed timestamp (of when the compile happened?) [hanwen@localhost lilypond]$ guile2.2 e.scm ;;; note: source file /home/hanwen/vc/lilypond/e.scm ;;; newer than compiled /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument to disable. ;;; compiling /home/hanwen/vc/lilypond/e.scm ;;; compiled /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go Fri Jan 31 20:15:57+0100 2020 [hanwen@localhost lilypond]$ guile2.2 e.scm Fri Jan 31 20:15:58+0100 2020 [hanwen@localhost lilypond]$ guile2.2 e.scm Fri Jan 31 20:16:00+0100 2020 -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 19:17 ` Han-Wen Nienhuys @ 2020-01-31 19:52 ` Linus Björnstam 2020-01-31 20:01 ` Linus Björnstam 1 sibling, 0 replies; 25+ messages in thread From: Linus Björnstam @ 2020-01-31 19:52 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel On Fri, 31 Jan 2020, at 20:17, Han-Wen Nienhuys wrote: > > eval-when looks like it might be a solution to the puzzle , but > honestly, the doc at > > https://www.gnu.org/software/guile/manual/html_node/Eval-When.html > > has me mystified. When I run the example through guile 2.2 and > display *compilation-date*, > > I get a different answer each time. Shouldn't it be a fixed timestamp > (of when the compile happened?) Yup. At least from my understanding of the documentation, but whenever I try to do eval-when I become sad so I have just decided that I am too dumb for it. Try asking in the irc channel. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 19:17 ` Han-Wen Nienhuys 2020-01-31 19:52 ` Linus Björnstam @ 2020-01-31 20:01 ` Linus Björnstam 2020-02-01 9:54 ` Han-Wen Nienhuys 1 sibling, 1 reply; 25+ messages in thread From: Linus Björnstam @ 2020-01-31 20:01 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel Read the docs. That seems to be a documentation bug. Try fiddling with the arguments to eval when and see if you can make it work. -- Linus Björnstam On Fri, 31 Jan 2020, at 20:17, Han-Wen Nienhuys wrote: > On Fri, Jan 31, 2020 at 7:20 PM Linus Björnstam > <linus.bjornstam@veryfast.biz> wrote: > > I don't really understand your question. With defmacro and syntax-case you can run arbitrary code. If you just output code that does module-define! that won't be run until runtime, and thus you cannot depend on the result of that module-define! during expansion. You can however wrap it in an eval-when to solve that issue. That allows you to specify when code gets run. With module-define! I personally find it all a bit icky, but I usually stay as far away from phasing as I can :) > > eval-when looks like it might be a solution to the puzzle , but > honestly, the doc at > > https://www.gnu.org/software/guile/manual/html_node/Eval-When.html > > has me mystified. When I run the example through guile 2.2 and > display *compilation-date*, > > I get a different answer each time. Shouldn't it be a fixed timestamp > (of when the compile happened?) > > [hanwen@localhost lilypond]$ guile2.2 e.scm > ;;; note: source file /home/hanwen/vc/lilypond/e.scm > ;;; newer than compiled > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > ;;; or pass the --no-auto-compile argument to disable. > ;;; compiling /home/hanwen/vc/lilypond/e.scm > ;;; compiled > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > Fri Jan 31 20:15:57+0100 2020 > [hanwen@localhost lilypond]$ guile2.2 e.scm > Fri Jan 31 20:15:58+0100 2020 > [hanwen@localhost lilypond]$ guile2.2 e.scm > Fri Jan 31 20:16:00+0100 2020 > > -- > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 20:01 ` Linus Björnstam @ 2020-02-01 9:54 ` Han-Wen Nienhuys 2020-02-01 9:56 ` Han-Wen Nienhuys 2020-02-01 13:12 ` Linus Björnstam 0 siblings, 2 replies; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-02-01 9:54 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel Here is an example that shows better how things work, and what might be the cause of my problems. Is it right that programmatically set contents of "current-module" are not serialized into the compiled file? (define (run-at-compile-time cmd) (module-define! (current-module) (string->symbol cmd) #t) (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) (define (runtime-call cmd) (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) (format (current-error-port) "val ~a\n" (module-ref (current-module) (string->symbol cmd)))) (defmacro foo (cmd . rest) (run-at-compile-time cmd) `(runtime-call ,cmd)) (foo "xy") $ guile1.8 ew.scm I-am-called-at-compile-time xy I-am-called-at-runtime xy val #t this is compatible with 2.2 without compilation, $ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm I-am-called-at-compile-time xy I-am-called-at-runtime xy val #t but compilation fails $ GUILE_AUTO_COMPILE=1 guile2.2 ew.scm ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 ;;; or pass the --no-auto-compile argument to disable. ;;; compiling /home/hanwen/vc/lilypond/ew.scm ;;; WARNING: compilation of /home/hanwen/vc/lilypond/ew.scm failed: ;;; Unbound variable: run-at-compile-time $ guild2.2 compile ew.scm Backtrace: In system/base/target.scm: 57:6 19 (with-target _ _) In system/base/compile.scm: .. Unbound variable: run-at-compile-time If I encapsulate the run-at-compile-time definition with (eval-when (compile eval) it works if I remove the module manipulation, but the module-ref doesn't work. It looks like the settings from module-define! are not serialized into the byte code, so I can't have code that relies on correspondence between module-define driven from macros and module-ref during evaluation. [hanwen@localhost lilypond]$ guild2.2 compile ew.scm I-am-called-at-compile-time xy wrote `/home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/ew.scm.go' [hanwen@localhost lilypond]$ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm I-am-called-at-runtime xy Backtrace: 6 (apply-smob/1 #<catch-closure 56514b4c37a0>) In ice-9/boot-9.scm: 705:2 5 (call-with-prompt ("prompt") #<procedure 56514b4d5c60 …> …) In ice-9/eval.scm: 619:8 4 (_ #(#(#<directory (guile-user) 56514b591140>))) In ice-9/boot-9.scm: 2312:4 3 (save-module-excursion #<procedure 56514b54b330 at ice-…>) 3832:12 2 (_) In ew.scm: 10:10 1 (runtime-call "xy") In unknown file: 0 (scm-error misc-error #f "~A ~S ~S ~S" ("No variabl…" …) …) ERROR: In procedure scm-error: No variable named xy in #<directory (guile-user) 56514b591140> On Fri, Jan 31, 2020 at 9:01 PM Linus Björnstam <linus.bjornstam@veryfast.biz> wrote: > > Read the docs. That seems to be a documentation bug. Try fiddling with the arguments to eval when and see if you can make it work. > > -- > Linus Björnstam > > On Fri, 31 Jan 2020, at 20:17, Han-Wen Nienhuys wrote: > > On Fri, Jan 31, 2020 at 7:20 PM Linus Björnstam > > <linus.bjornstam@veryfast.biz> wrote: > > > I don't really understand your question. With defmacro and syntax-case you can run arbitrary code. If you just output code that does module-define! that won't be run until runtime, and thus you cannot depend on the result of that module-define! during expansion. You can however wrap it in an eval-when to solve that issue. That allows you to specify when code gets run. With module-define! I personally find it all a bit icky, but I usually stay as far away from phasing as I can :) > > > > eval-when looks like it might be a solution to the puzzle , but > > honestly, the doc at > > > > https://www.gnu.org/software/guile/manual/html_node/Eval-When.html > > > > has me mystified. When I run the example through guile 2.2 and > > display *compilation-date*, > > > > I get a different answer each time. Shouldn't it be a fixed timestamp > > (of when the compile happened?) > > > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > ;;; note: source file /home/hanwen/vc/lilypond/e.scm > > ;;; newer than compiled > > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > > ;;; or pass the --no-auto-compile argument to disable. > > ;;; compiling /home/hanwen/vc/lilypond/e.scm > > ;;; compiled > > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > > Fri Jan 31 20:15:57+0100 2020 > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > Fri Jan 31 20:15:58+0100 2020 > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > Fri Jan 31 20:16:00+0100 2020 > > > > -- > > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > > -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 9:54 ` Han-Wen Nienhuys @ 2020-02-01 9:56 ` Han-Wen Nienhuys 2020-02-01 10:10 ` David Kastrup 2020-02-01 13:12 ` Linus Björnstam 1 sibling, 1 reply; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-02-01 9:56 UTC (permalink / raw) To: Linus Björnstam; +Cc: lilypond-devel, guile-devel +lilypond-devel for visibility. On Sat, Feb 1, 2020 at 10:54 AM Han-Wen Nienhuys <hanwenn@gmail.com> wrote: > > Here is an example that shows better how things work, and what might > be the cause of my problems. Is it right that programmatically set > contents of "current-module" are not serialized into the compiled > file? > > (define (run-at-compile-time cmd) > (module-define! (current-module) (string->symbol cmd) #t) > (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) > > (define (runtime-call cmd) > (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) > (format (current-error-port) "val ~a\n" > (module-ref (current-module) (string->symbol cmd)))) > > (defmacro foo (cmd . rest) > (run-at-compile-time cmd) > `(runtime-call ,cmd)) > > (foo "xy") > > $ guile1.8 ew.scm > I-am-called-at-compile-time xy > I-am-called-at-runtime xy > val #t > > this is compatible with 2.2 without compilation, > > $ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm > I-am-called-at-compile-time xy > I-am-called-at-runtime xy > val #t > > but compilation fails > > $ GUILE_AUTO_COMPILE=1 guile2.2 ew.scm > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > ;;; or pass the --no-auto-compile argument to disable. > ;;; compiling /home/hanwen/vc/lilypond/ew.scm > ;;; WARNING: compilation of /home/hanwen/vc/lilypond/ew.scm failed: > ;;; Unbound variable: run-at-compile-time > > $ guild2.2 compile ew.scm > Backtrace: > In system/base/target.scm: > 57:6 19 (with-target _ _) > In system/base/compile.scm: > .. > Unbound variable: run-at-compile-time > > > If I encapsulate the run-at-compile-time definition with > > (eval-when > (compile eval) > > it works if I remove the module manipulation, but the module-ref > doesn't work. It looks like the settings from module-define! are not > serialized into the byte code, so I can't have code that relies on > correspondence between module-define driven from macros and module-ref > during evaluation. > > [hanwen@localhost lilypond]$ guild2.2 compile ew.scm > I-am-called-at-compile-time xy > wrote `/home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/ew.scm.go' > [hanwen@localhost lilypond]$ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm > I-am-called-at-runtime xy > Backtrace: > 6 (apply-smob/1 #<catch-closure 56514b4c37a0>) > In ice-9/boot-9.scm: > 705:2 5 (call-with-prompt ("prompt") #<procedure 56514b4d5c60 …> …) > In ice-9/eval.scm: > 619:8 4 (_ #(#(#<directory (guile-user) 56514b591140>))) > In ice-9/boot-9.scm: > 2312:4 3 (save-module-excursion #<procedure 56514b54b330 at ice-…>) > 3832:12 2 (_) > In ew.scm: > 10:10 1 (runtime-call "xy") > In unknown file: > 0 (scm-error misc-error #f "~A ~S ~S ~S" ("No variabl…" …) …) > > ERROR: In procedure scm-error: > No variable named xy in #<directory (guile-user) 56514b591140> > -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 9:56 ` Han-Wen Nienhuys @ 2020-02-01 10:10 ` David Kastrup 2020-02-01 11:23 ` Han-Wen Nienhuys 0 siblings, 1 reply; 25+ messages in thread From: David Kastrup @ 2020-02-01 10:10 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel, lilypond-devel Han-Wen Nienhuys <hanwenn@gmail.com> writes: > +lilypond-devel for visibility. > > On Sat, Feb 1, 2020 at 10:54 AM Han-Wen Nienhuys <hanwenn@gmail.com> wrote: >> >> Here is an example that shows better how things work, and what might >> be the cause of my problems. Is it right that programmatically set >> contents of "current-module" are not serialized into the compiled >> file? >> >> (define (run-at-compile-time cmd) >> (module-define! (current-module) (string->symbol cmd) #t) >> (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) >> >> (define (runtime-call cmd) >> (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) >> (format (current-error-port) "val ~a\n" >> (module-ref (current-module) (string->symbol cmd)))) >> >> (defmacro foo (cmd . rest) >> (run-at-compile-time cmd) >> `(runtime-call ,cmd)) >> >> (foo "xy") >> >> $ guile1.8 ew.scm >> I-am-called-at-compile-time xy >> I-am-called-at-runtime xy >> val #t >> >> this is compatible with 2.2 without compilation, >> >> $ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm >> I-am-called-at-compile-time xy >> I-am-called-at-runtime xy >> val #t >> >> but compilation fails >> >> $ GUILE_AUTO_COMPILE=1 guile2.2 ew.scm >> ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 >> ;;; or pass the --no-auto-compile argument to disable. >> ;;; compiling /home/hanwen/vc/lilypond/ew.scm >> ;;; WARNING: compilation of /home/hanwen/vc/lilypond/ew.scm failed: >> ;;; Unbound variable: run-at-compile-time >> >> $ guild2.2 compile ew.scm >> Backtrace: >> In system/base/target.scm: >> 57:6 19 (with-target _ _) >> In system/base/compile.scm: >> .. >> Unbound variable: run-at-compile-time >> >> >> If I encapsulate the run-at-compile-time definition with >> >> (eval-when >> (compile eval) >> >> it works if I remove the module manipulation, but the module-ref >> doesn't work. It looks like the settings from module-define! are not >> serialized into the byte code, so I can't have code that relies on >> correspondence between module-define driven from macros and module-ref >> during evaluation. >> >> [hanwen@localhost lilypond]$ guild2.2 compile ew.scm >> I-am-called-at-compile-time xy >> wrote `/home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/ew.scm.go' >> [hanwen@localhost lilypond]$ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm >> I-am-called-at-runtime xy >> Backtrace: >> 6 (apply-smob/1 #<catch-closure 56514b4c37a0>) >> In ice-9/boot-9.scm: >> 705:2 5 (call-with-prompt ("prompt") #<procedure 56514b4d5c60 …> …) >> In ice-9/eval.scm: >> 619:8 4 (_ #(#(#<directory (guile-user) 56514b591140>))) >> In ice-9/boot-9.scm: >> 2312:4 3 (save-module-excursion #<procedure 56514b54b330 at ice-…>) >> 3832:12 2 (_) >> In ew.scm: >> 10:10 1 (runtime-call "xy") >> In unknown file: >> 0 (scm-error misc-error #f "~A ~S ~S ~S" ("No variabl…" …) …) >> >> ERROR: In procedure scm-error: >> No variable named xy in #<directory (guile-user) 56514b591140> >> But that is not using a local define at all. Can you point out the actual code that failed for you? -- David Kastrup ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 10:10 ` David Kastrup @ 2020-02-01 11:23 ` Han-Wen Nienhuys 2020-02-01 11:36 ` David Kastrup 0 siblings, 1 reply; 25+ messages in thread From: Han-Wen Nienhuys @ 2020-02-01 11:23 UTC (permalink / raw) To: David Kastrup; +Cc: guile-devel, lilypond-devel On Sat, Feb 1, 2020 at 11:11 AM David Kastrup <dak@gnu.org> wrote: > >> Here is an example that shows better how things work, and what might > >> be the cause of my problems. Is it right that programmatically set > >> contents of "current-module" are not serialized into the compiled > >> file? > >> > >> (define (run-at-compile-time cmd) > >> (module-define! (current-module) (string->symbol cmd) #t) > >> (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) > >> > >> (define (runtime-call cmd) > >> (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) > >> (format (current-error-port) "val ~a\n" > >> (module-ref (current-module) (string->symbol cmd)))) > >> > >> (defmacro foo (cmd . rest) > >> (run-at-compile-time cmd) > >> `(runtime-call ,cmd)) > >> > >> (foo "xy") .. > >> ERROR: In procedure scm-error: > >> No variable named xy in #<directory (guile-user) 56514b591140> > >> > > But that is not using a local define at all. Can you point out the > actual code that failed for you? There are two independent problems. One is a problem with inner defines, which is addressed by https://codereview.appspot.com/553480044/ the symptom is compilation failing with "unhandled constant #<procedure ... > " The other is a problem you can reproduce if you check out https://github.com/hanwen/lilypond/tree/guile22-experiment with the symptom being: ;;; compiling /home/hanwen/vc/lilypond/out/share/lilypond/current/scm/define-markup-commands.scm fatal error: Not a markup command: line This is because the LilyPond macro "markup" doesn't recognize markup command and aborts in code that is executed at compile-time. The code that triggers this are definitions in scm/define-markup-commands.scm that use (mark #:blah .. ) in the function body. You can verify this by rewriting https://github.com/lilypond/lilypond/blob/c5ffa540fdbe52486b9575567ede70be575adb47/scm/define-markup-commands.scm#L305 and seeing how the error message changes. I still don't understand why some code is executed compile time (the expansion of the markup macro) while other is not (defining the make-x-markup function in (current-module)) Since we recognize markup commands by looking them up in (current-module), I believe the example I showed here shows that we can never make this work, and we will have to revisit the markup macros completely. -- Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 11:23 ` Han-Wen Nienhuys @ 2020-02-01 11:36 ` David Kastrup 0 siblings, 0 replies; 25+ messages in thread From: David Kastrup @ 2020-02-01 11:36 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel, lilypond-devel Han-Wen Nienhuys <hanwenn@gmail.com> writes: > On Sat, Feb 1, 2020 at 11:11 AM David Kastrup <dak@gnu.org> wrote: >> >> Here is an example that shows better how things work, and what might >> >> be the cause of my problems. Is it right that programmatically set >> >> contents of "current-module" are not serialized into the compiled >> >> file? >> >> >> >> (define (run-at-compile-time cmd) >> >> (module-define! (current-module) (string->symbol cmd) #t) >> >> (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) >> >> >> >> (define (runtime-call cmd) >> >> (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) >> >> (format (current-error-port) "val ~a\n" >> >> (module-ref (current-module) (string->symbol cmd)))) >> >> >> >> (defmacro foo (cmd . rest) >> >> (run-at-compile-time cmd) >> >> `(runtime-call ,cmd)) >> >> >> >> (foo "xy") > .. >> >> ERROR: In procedure scm-error: >> >> No variable named xy in #<directory (guile-user) 56514b591140> >> >> >> >> But that is not using a local define at all. Can you point out the >> actual code that failed for you? > > There are two independent problems. One is a problem with inner > defines, which is addressed by > > https://codereview.appspot.com/553480044/ > > the symptom is compilation failing with "unhandled constant > #<procedure ... > " Ah, ok. This appears not to signify that anything is wrong with the code in principle but rather that the byte compiler is not sufficiently capable for processing it. > The other is a problem you can reproduce if you check out > > https://github.com/hanwen/lilypond/tree/guile22-experiment > > with the symptom being: > > ;;; compiling > /home/hanwen/vc/lilypond/out/share/lilypond/current/scm/define-markup-commands.scm > fatal error: Not a markup command: line > > This is because the LilyPond macro "markup" doesn't recognize markup > command and aborts in code that is executed at compile-time. The code > that triggers this are definitions in scm/define-markup-commands.scm > that use (mark #:blah .. ) in the function body. The LilyPond macro "markup" is something I would not mind getting rid of sooner rather than later. It's sick. It is not completely clear to me why it needs the actual definitions to work with, but it may have something to do with its partly workable support of markup list commands. The make-...-markup convenience functions are quite more sane. Stacking a lot of them together may incur a bit of runtime overhead since they do argument checking that the results from markup macro expansion don't. But markup command processing times are likely quite negligible in the total scheme of things even if we end up rechecking large markup lists as they are passed from one function to another. > You can verify this by rewriting > https://github.com/lilypond/lilypond/blob/c5ffa540fdbe52486b9575567ede70be575adb47/scm/define-markup-commands.scm#L305 > and seeing how the error message changes. > > I still don't understand why some code is executed compile time (the > expansion of the markup macro) while other is not (defining the > make-x-markup function in (current-module)) > > Since we recognize markup commands by looking them up in > (current-module), I believe the example I showed here shows that we > can never make this work, and we will have to revisit the markup > macros completely. My vote is on throwing them out. But that would affect a whole bunch of user-level programs. We could add a macro _function_ that does the hard work at execution time rather than at expansion time as a backwards compatibility measure, and discourage using it for new code. -- David Kastrup ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 9:54 ` Han-Wen Nienhuys 2020-02-01 9:56 ` Han-Wen Nienhuys @ 2020-02-01 13:12 ` Linus Björnstam 1 sibling, 0 replies; 25+ messages in thread From: Linus Björnstam @ 2020-02-01 13:12 UTC (permalink / raw) To: Han-Wen Nienhuys; +Cc: guile-devel Did you try just expanding it to a define? Or just output a module-define! at runtime and run a module-define! at compile time. -- Linus Björnstam On Sat, 1 Feb 2020, at 10:54, Han-Wen Nienhuys wrote: > Here is an example that shows better how things work, and what might > be the cause of my problems. Is it right that programmatically set > contents of "current-module" are not serialized into the compiled > file? > > (define (run-at-compile-time cmd) > (module-define! (current-module) (string->symbol cmd) #t) > (format (current-error-port) "I-am-called-at-compile-time ~a\n" cmd)) > > (define (runtime-call cmd) > (format (current-error-port) "I-am-called-at-runtime ~a\n" cmd) > (format (current-error-port) "val ~a\n" > (module-ref (current-module) (string->symbol cmd)))) > > (defmacro foo (cmd . rest) > (run-at-compile-time cmd) > `(runtime-call ,cmd)) > > (foo "xy") > > $ guile1.8 ew.scm > I-am-called-at-compile-time xy > I-am-called-at-runtime xy > val #t > > this is compatible with 2.2 without compilation, > > $ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm > I-am-called-at-compile-time xy > I-am-called-at-runtime xy > val #t > > but compilation fails > > $ GUILE_AUTO_COMPILE=1 guile2.2 ew.scm > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > ;;; or pass the --no-auto-compile argument to disable. > ;;; compiling /home/hanwen/vc/lilypond/ew.scm > ;;; WARNING: compilation of /home/hanwen/vc/lilypond/ew.scm failed: > ;;; Unbound variable: run-at-compile-time > > $ guild2.2 compile ew.scm > Backtrace: > In system/base/target.scm: > 57:6 19 (with-target _ _) > In system/base/compile.scm: > .. > Unbound variable: run-at-compile-time > > > If I encapsulate the run-at-compile-time definition with > > (eval-when > (compile eval) > > it works if I remove the module manipulation, but the module-ref > doesn't work. It looks like the settings from module-define! are not > serialized into the byte code, so I can't have code that relies on > correspondence between module-define driven from macros and module-ref > during evaluation. > > [hanwen@localhost lilypond]$ guild2.2 compile ew.scm > I-am-called-at-compile-time xy > wrote > `/home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/ew.scm.go' > [hanwen@localhost lilypond]$ GUILE_AUTO_COMPILE=0 guile2.2 ew.scm > I-am-called-at-runtime xy > Backtrace: > 6 (apply-smob/1 #<catch-closure 56514b4c37a0>) > In ice-9/boot-9.scm: > 705:2 5 (call-with-prompt ("prompt") #<procedure 56514b4d5c60 …> …) > In ice-9/eval.scm: > 619:8 4 (_ #(#(#<directory (guile-user) 56514b591140>))) > In ice-9/boot-9.scm: > 2312:4 3 (save-module-excursion #<procedure 56514b54b330 at ice-…>) > 3832:12 2 (_) > In ew.scm: > 10:10 1 (runtime-call "xy") > In unknown file: > 0 (scm-error misc-error #f "~A ~S ~S ~S" ("No variabl…" …) …) > > ERROR: In procedure scm-error: > No variable named xy in #<directory (guile-user) 56514b591140> > > On Fri, Jan 31, 2020 at 9:01 PM Linus Björnstam > <linus.bjornstam@veryfast.biz> wrote: > > > > Read the docs. That seems to be a documentation bug. Try fiddling with the arguments to eval when and see if you can make it work. > > > > -- > > Linus Björnstam > > > > On Fri, 31 Jan 2020, at 20:17, Han-Wen Nienhuys wrote: > > > On Fri, Jan 31, 2020 at 7:20 PM Linus Björnstam > > > <linus.bjornstam@veryfast.biz> wrote: > > > > I don't really understand your question. With defmacro and syntax-case you can run arbitrary code. If you just output code that does module-define! that won't be run until runtime, and thus you cannot depend on the result of that module-define! during expansion. You can however wrap it in an eval-when to solve that issue. That allows you to specify when code gets run. With module-define! I personally find it all a bit icky, but I usually stay as far away from phasing as I can :) > > > > > > eval-when looks like it might be a solution to the puzzle , but > > > honestly, the doc at > > > > > > https://www.gnu.org/software/guile/manual/html_node/Eval-When.html > > > > > > has me mystified. When I run the example through guile 2.2 and > > > display *compilation-date*, > > > > > > I get a different answer each time. Shouldn't it be a fixed timestamp > > > (of when the compile happened?) > > > > > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > > ;;; note: source file /home/hanwen/vc/lilypond/e.scm > > > ;;; newer than compiled > > > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > > > ;;; note: auto-compilation is enabled, set GUILE_AUTO_COMPILE=0 > > > ;;; or pass the --no-auto-compile argument to disable. > > > ;;; compiling /home/hanwen/vc/lilypond/e.scm > > > ;;; compiled > > > /home/hanwen/.cache/guile/ccache/2.2-LE-8-3.A/home/hanwen/vc/lilypond/e.scm.go > > > Fri Jan 31 20:15:57+0100 2020 > > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > > Fri Jan 31 20:15:58+0100 2020 > > > [hanwen@localhost lilypond]$ guile2.2 e.scm > > > Fri Jan 31 20:16:00+0100 2020 > > > > > > -- > > > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > > > > > > > -- > Han-Wen Nienhuys - hanwenn@gmail.com - http://www.xs4all.nl/~hanwen > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-31 14:57 ` Linus Björnstam 2020-01-31 15:16 ` Han-Wen Nienhuys 2020-01-31 17:50 ` Han-Wen Nienhuys @ 2020-02-01 11:09 ` David Kastrup 2020-02-01 13:16 ` Linus Björnstam 2 siblings, 1 reply; 25+ messages in thread From: David Kastrup @ 2020-02-01 11:09 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel, Han-Wen Nienhuys Linus Björnstam <linus.bjornstam@veryfast.biz> writes: > Guile1.8's macros are run-time macros: they are executed directly and > not transformed to output code that is then compiled. That is the > reason why your code works: to newer guiles the (inner ...) is only > available at expansion time. The macro output is trying to call code > that does not exist at runtime! > > For this to be working code the (inner ...) function needs to be > available in the macro expansion. I didn't read through exactly what > you are trying to do, but try outputting a let: > > `(let ((inner (lambda (n v) (set ! ...)))) > (inner ,name ,value)) > > I doubt you can make the old code work in newer guiles, since I doubt > any scheme is a s lax about expansion time and macro time separation. Can you expand about the "expansion time and macro time separation"? If we have (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) as stated, the local function "inner" is defined at macro time, but the form `(,inner ',name ,value) does not export the _name_ inner but rather the defined function. That part naively appears to me like it should work; an "expansion time and macro time" issue appears rather to be that inner calls make-var (and accesses decl) which is only being defined at expansion time. The error message, however, rather appears to complain about inner being undefined rather than the definition of inner referring to undefined entities. Can you clarify? -- David Kastrup ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 11:09 ` David Kastrup @ 2020-02-01 13:16 ` Linus Björnstam 2020-02-01 14:23 ` David Kastrup 0 siblings, 1 reply; 25+ messages in thread From: Linus Björnstam @ 2020-02-01 13:16 UTC (permalink / raw) To: David Kastrup; +Cc: guile-devel, Han-Wen Nienhuys On Sat, 1 Feb 2020, at 12:09, David Kastrup wrote: > > Can you expand about the "expansion time and macro time separation"? > > If we have > > (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) > > as stated, the local function "inner" is defined at macro time, but the > form > `(,inner ',name ,value) > does not export the _name_ inner but rather the defined function. That > part naively appears to me like it should work; an "expansion time and > macro time" issue appears rather to be that inner calls make-var (and > accesses decl) which is only being defined at expansion time. > > The error message, however, rather appears to complain about inner being > undefined rather than the definition of inner referring to undefined > entities. I am not sure what is really the problem. Either the inner function is not present at runtime due to separation of compile time and runtime, or it is a result of how defmacro re-introduces the result of the macro into the syntactic context of the macro usage (where inner is not visible). Either way, having the inner definition in the macro output will solve the problem of it not being visible. ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 13:16 ` Linus Björnstam @ 2020-02-01 14:23 ` David Kastrup 2020-02-01 15:21 ` Linus Björnstam 0 siblings, 1 reply; 25+ messages in thread From: David Kastrup @ 2020-02-01 14:23 UTC (permalink / raw) To: Linus Björnstam; +Cc: guile-devel, Han-Wen Nienhuys Linus Björnstam <linus.bjornstam@veryfast.biz> writes: > On Sat, 1 Feb 2020, at 12:09, David Kastrup wrote: >> >> Can you expand about the "expansion time and macro time separation"? >> >> If we have >> >> (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) >> >> as stated, the local function "inner" is defined at macro time, but the >> form >> `(,inner ',name ,value) >> does not export the _name_ inner but rather the defined function. That >> part naively appears to me like it should work; an "expansion time and >> macro time" issue appears rather to be that inner calls make-var (and >> accesses decl) which is only being defined at expansion time. >> >> The error message, however, rather appears to complain about inner being >> undefined rather than the definition of inner referring to undefined >> entities. > > > I am not sure what is really the problem. Either the inner function is > not present at runtime due to separation of compile time and runtime, > or it is a result of how defmacro re-introduces the result of the > macro into the syntactic context of the macro usage (where inner is > not visible). Either way, having the inner definition in the macro > output will solve the problem of it not being visible. This fails when byte-compiling, so it would appear that the equivalent of (defmacro ... (define local-fun ... `(,local-fun ...))) is not able to represent the local (and thus ultimately anonymous) function here. Whether this is a general shortcoming or is conditioned on local-fun calling functions not available at byte-compile time (in which case those would need to get wrapped in eval-and-expand) I haven't checked yet. -- David Kastrup ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-02-01 14:23 ` David Kastrup @ 2020-02-01 15:21 ` Linus Björnstam 0 siblings, 0 replies; 25+ messages in thread From: Linus Björnstam @ 2020-02-01 15:21 UTC (permalink / raw) To: David Kastrup; +Cc: guile-devel, Han-Wen Nienhuys tried it in a couple of syntax-case-enabled schemes (defmacro is implemented using syntax-case in guile) and it doesn't work anywhere. The procedure ends up undefined everywhere. The #<procedure> object ,inner points to doesn't exist at runtime because it is not defined anywhere in any meaningful way to the compiler. One work-around would be to output the literal lambda in place of ,inner but by then you should just output a (let ...) With the lambda in it and let the inliner take care of it. -- Linus Björnstam On Sat, 1 Feb 2020, at 15:23, David Kastrup wrote: > Linus Björnstam <linus.bjornstam@veryfast.biz> writes: > > > On Sat, 1 Feb 2020, at 12:09, David Kastrup wrote: > >> > >> Can you expand about the "expansion time and macro time separation"? > >> > >> If we have > >> > >> (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) > >> > >> as stated, the local function "inner" is defined at macro time, but the > >> form > >> `(,inner ',name ,value) > >> does not export the _name_ inner but rather the defined function. That > >> part naively appears to me like it should work; an "expansion time and > >> macro time" issue appears rather to be that inner calls make-var (and > >> accesses decl) which is only being defined at expansion time. > >> > >> The error message, however, rather appears to complain about inner being > >> undefined rather than the definition of inner referring to undefined > >> entities. > > > > > > I am not sure what is really the problem. Either the inner function is > > not present at runtime due to separation of compile time and runtime, > > or it is a result of how defmacro re-introduces the result of the > > macro into the syntactic context of the macro usage (where inner is > > not visible). Either way, having the inner definition in the macro > > output will solve the problem of it not being visible. > > This fails when byte-compiling, so it would appear that the equivalent > of > > (defmacro ... > (define local-fun ... > `(,local-fun ...))) > > is not able to represent the local (and thus ultimately anonymous) > function here. Whether this is a general shortcoming or is conditioned > on local-fun calling functions not available at byte-compile time (in > which case those would need to get wrapped in eval-and-expand) I haven't > checked yet. > > -- > David Kastrup > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: unhandled constant? 2020-01-28 23:08 unhandled constant? Han-Wen Nienhuys 2020-01-29 15:06 ` Ricardo Wurmus 2020-01-31 14:57 ` Linus Björnstam @ 2020-02-01 21:55 ` Taylan Kammer 2020-02-01 21:58 ` Fwd: " Taylan Kammer 2 siblings, 1 reply; 25+ messages in thread From: Taylan Kammer @ 2020-02-01 21:55 UTC (permalink / raw) To: guile-devel > (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? > ^ permalink raw reply [flat|nested] 25+ messages in thread
* Fwd: Re: unhandled constant? 2020-02-01 21:55 ` Taylan Kammer @ 2020-02-01 21:58 ` Taylan Kammer 0 siblings, 0 replies; 25+ messages in thread From: Taylan Kammer @ 2020-02-01 21:58 UTC (permalink / raw) To: hanwenn; +Cc: guile-devel (Duplicate of the mail I sent to guile-devel before realizing you're not on the list.) > (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? > ^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2020-02-02 19:30 UTC | newest] Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-01-28 23:08 unhandled constant? Han-Wen Nienhuys 2020-01-29 15:06 ` Ricardo Wurmus 2020-01-30 8:05 ` Han-Wen Nienhuys 2020-01-31 10:49 ` Han-Wen Nienhuys 2020-01-31 11:17 ` Ricardo Wurmus 2020-02-02 19:30 ` Jan Nieuwenhuizen 2020-01-31 14:57 ` Linus Björnstam 2020-01-31 15:16 ` Han-Wen Nienhuys 2020-01-31 17:50 ` Han-Wen Nienhuys 2020-01-31 18:19 ` Linus Björnstam 2020-01-31 19:17 ` Han-Wen Nienhuys 2020-01-31 19:52 ` Linus Björnstam 2020-01-31 20:01 ` Linus Björnstam 2020-02-01 9:54 ` Han-Wen Nienhuys 2020-02-01 9:56 ` Han-Wen Nienhuys 2020-02-01 10:10 ` David Kastrup 2020-02-01 11:23 ` Han-Wen Nienhuys 2020-02-01 11:36 ` David Kastrup 2020-02-01 13:12 ` Linus Björnstam 2020-02-01 11:09 ` David Kastrup 2020-02-01 13:16 ` Linus Björnstam 2020-02-01 14:23 ` David Kastrup 2020-02-01 15:21 ` Linus Björnstam 2020-02-01 21:55 ` Taylan Kammer 2020-02-01 21:58 ` Fwd: " Taylan Kammer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).