Summary

Include multiple times in a row 'interrupts' definitions

Metadata

Description

Given file `include.scm`:

 (define (foo)
   (print that))

and a file "include2.scm" with arbitrary contents (including an empty file), the following code works (interpreted and compiled):

 #!/usr/bin/csi -s
 (define (main #!optional args)
   (include "include.scm")
   (define that "hey")
   (foo))
 
 (main)

whereas this does not (interpreted or compiled):

 #!/usr/bin/csi -s
 (define (main #!optional args)
   (include "include.scm")
   (include "include2.scm")
   (define that "hey")
   (foo))
 
 (main)

The latter throws an error about `that` being unbound.

Changes and comments

[2019-07-24 06:33:36 UTC] dieggsy wrote:

there's a typo here - both of the last code snippets should be using `csi -s` on top

[2019-07-24 09:23:19 UTC] sjamaan set difficulty to hard

[2019-07-24 09:23:19 UTC] sjamaan changed component from unknown to expander

[2019-07-24 09:23:19 UTC] sjamaan wrote:

This won't be easy. The issue is that when `##sys#canonicalize-body` encounters a `##core#include`, it will hand back to the compiler and passes the remaining body along with it. The compiler then calls `canonicalize-body/ln` (which is basically `##sys#canonicalize-body`) with the forms from the file and the remaining ones appended. This extra call is unaware of what came before and starts a new `letrec`.

See 0be9d247a57da082bb2126b2e91958ea191c5513, which made this work at all (before, the include would be processed at toplevel, which is strictly much worse than what we have now).

Changing this probably requires restructuring how the canonicalization works (again). Maybe we'd have to introduce a new compiler form that allows canonicalize-body to be run in two steps, or something like it.

[2019-07-24 13:20:40 UTC] sjamaan changed description