unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: ludo@gnu.org (Ludovic Courtès)
To: 15602@debbugs.gnu.org
Subject: bug#15602: Compiling several files in the same session [2.0.9]
Date: Sun, 13 Oct 2013 22:56:06 +0200	[thread overview]
Message-ID: <87siw47uvt.fsf@gnu.org> (raw)
In-Reply-To: <8761t19t4f.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Sun, 13 Oct 2013 15:51:12 +0200")

[-- Attachment #1: Type: text/plain, Size: 854 bytes --]

ludo@gnu.org (Ludovic Courtès) skribis:

> In the last case (one, three, two), the compiler:
>
>   1. compiles ‘one.scm’, which creates module (one) in the global name
>      space with just ‘expansion-time’ in its exported bindings;
>
>   2. when compiling ‘three.scm’, it loads ‘two.scm’; since (two) uses
>      (one), it does ‘(resolve-module '(one))’, and since (one) already
>      exists it is used;
>
>      however, the (one) we have comes from step 1, and lacks the
>      ‘run-time’ binding, hence the unbound variable failure.
>
> I think the right thing would be to use a separate module hierarchy in
> the dynamic extent of ‘compile-file’, somehow, such that all module side
> effects are isolated.

In Guix (the ‘guix pull’ command, which compiles all of Guix), I ended
up with this:


[-- Attachment #2: Type: text/x-scheme, Size: 1446 bytes --]

 (define* (compile-file* file #:key output-file (opts '()))
   ;; Like 'compile-file', but remove any (guix …) and (gnu …) modules
   ;; created during the process as an ugly workaround for
   ;; <http://bugs.gnu.org/15602> (FIXME).  This ensures correctness,
   ;; but is overly conservative and very slow.

   (define (module-directory+file module)
     ;; Return the directory for MODULE, like the 'dir-hint' in
     ;; boot-9.scm.
     (match (module-name module)
       ((beginning ... last)
        (values (string-concatenate
                 (map (lambda (elt)
                        (string-append (symbol->string elt)
                                       file-name-separator-string))
                      beginning))
                (symbol->string last)))))

   (define (clear-module-tree! root)
     ;; Delete all the modules under ROOT.
     (hash-for-each (lambda (name module)
                      (module-remove! root name)
                      (let-values (((dir name)
                                    (module-directory+file module)))
                        (set-autoloaded! dir name #f))
                      (clear-module-tree! module))
                    (module-submodules root))
     (hash-clear! (module-submodules root)))

   (compile-file file #:output-file output-file #:opts opts)

   (for-each (compose clear-module-tree! resolve-module)
             '((guix) (gnu))))

[-- Attachment #3: Type: text/plain, Size: 516 bytes --]


> Of course the above can be worked around by running ‘compile-file’ in a
> child process, but forking alone is more expensive than ‘compile-file’,
> so that’s not really a solution when there are many files.

As it turns out, the hack above is just as slow as forking: what takes
time is not forking, but reloading the same modules over and over again.

So we should have a way to keep modules that have been fully evaluated,
and to discard modules that have not.

Ideas welcome.

Ludo’.

  reply	other threads:[~2013-10-13 20:56 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-10-13 13:51 bug#15602: Compiling several files in the same session [2.0.9] Ludovic Courtès
2013-10-13 20:56 ` Ludovic Courtès [this message]
2015-11-06  8:26 ` bug#15602: Possible work-around Taylan Ulrich Bayırlı/Kammer
2016-06-21 11:22 ` bug#15602: Compiling several files in the same session [2.0.9] Andy Wingo
2016-06-21 12:01   ` Ludovic Courtès
2016-06-21 15:00     ` Andy Wingo
2016-06-21 15:17       ` Ludovic Courtès
2016-06-21 15:30         ` Andy Wingo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87siw47uvt.fsf@gnu.org \
    --to=ludo@gnu.org \
    --cc=15602@debbugs.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).