[plt-scheme] conditional module inclusion and compilation

From: Eli Barzilay (eli at barzilay.org)
Date: Wed Sep 2 19:20:06 EDT 2009

On Sep  2, Lee Spector wrote:
> On Sep 2, 2009, at 5:59 PM, Eli Barzilay wrote:
> > Not in that way.  More than that, the fact that there is no direct
> > equivalent of this is an intnetional way of avoiding the mess you
> > can easily get into with CL: `*features*' is a description of the
> > "currently running system" but it is used for three separate
> > roles: reading, compiling, and running.  For example, if you were
> > using
> I'm going to get myself into needless trouble by saying this, and
> it's not even directly related to my question here, but one of the
> things I've always liked about CL is that I can decide when it's
> worth it to me to risk getting into such messes...

Well, in PLT you can *decide* when to get into a mess -- in CL it's
easy to get into it by accident -- and that's where the problems
start.  [To avoid potential flames: I'm saying this because the
default mode in CL is to have almost everything available at almost
any phase, whereas the default in PLT is to have protection against
accidental bugs.  Also relevant:

In fact, by using the conditional syntax approach, you demonstrate
nicely how to get (a part of) this mess.

> > A much better idea is to delay the decision to where it belongs
> > more naturally -- in the runtime.  But this runs into the problem
> > you've seen: `require' is not an expression, so you can't put it
> > in an `if'.  The reason you can't do that is that `require' is
> > used at compile-time to tell the compiler how to compile and link
> > the code (think about requiring a module that provides some macro
> > that you're using: you *need* it at compile time then).
> Actually, I think that everything I want to do here belongs most
> naturally at compile time. I have a single source file that I want
> to be able to compile and run in two different environments.
> [...]
> (define-syntax (in-unix stx)
>    (if (eq? 'unix (system-type))
>       (syntax-case stx ()
>         ((_ form)
>          #`form))
>       #`(void)))

Just in case it wasn't clear:

1. By doing this, you *must* be careful to copy only source files
   between the machines -- if you copy the whole directory with the
   .zo files, you will get to use the wrong version of the code since
   it was compiled on OSX.

2. Again, I recommend the `dynamic-require' solution -- it is a
   *function* rather than a declaration like `require', so by using it
   inside a function as the code below, you have no runtime overhead,
   but now it doesn't matter where you compile the code (IOW, your .zo
   file will be portable with this).

     (define plot-data
       (if (eq 'unix (system-type))
         (lambda (data x-label y-label)
           ((dynamic-require 'plot 'plot)
            (points (for/list ((i (number-list (length data))))
                      (vector i (list-ref data i)))
                    #:sym 'oplus)
            #:x-min 0
            #:x-max (length data)
            #:y-min 0
            #:y-max (+ 1 (apply max data))
            #:x-label x-label
            #:y-label y-label))))

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the users mailing list.