On Tue, Sep 25, 2018 at 3:46 PM 'Paulo Matos' via Racket Users <
racket-users@googlegroups.com> wrote:

> OK, so I understand now that what I want is an unimplemented feature,
> but in most compilers these days and certainly those based in LLVM and
> GCC there's a feature called whole-program optimization or link time
> optimization. Basically the compiler will get the whole program in
> memory after compiling each module/file and run the optimizations on the
> whole thing again therefore being able to optimize things it wasn't able
> to optimize before when it only had a module/file view.
>

I know that `raco demodularize` can flatten a whole program (
https://docs.racket-lang.org/raco/demod.html). I think I remember reading a
paper that looked at using this as the basis for whole-program
optimization, but I don't remember the results of the paper, much less
anything about doing this in practice.


> >> My software has several compile time options that use environment
> >> variables to be read (since I can't think of another way to do it) so I
> >> define a compile time variable as:
> >>
> >> (define-for-syntax enable-contracts?
> >> (and (getenv "S10_ENABLE_CONTRACTS") #true))
> >>
> >> And then I create a macro to move this compile-time variable to runtime:
> >> (define-syntax (compiled-with-contracts? stx)
> >> (datum->syntax stx enable-contracts?))
> >>
> >> I have a few of these so when I create a distribution, I first create an
> >> executable with (I use create-embedding-executable but for simplicity,
> >> lets say I am using raco):
> >> S10_ENABLE_CONTRACTS=1 raco exe ...
>

More broadly, the thing that first struck me is that most Racket programs
don't seem to use this sort of build process. I do think they should be
*able* to, and there may be good reasons to do that in your case, but I've
been trying to think about what it is about this that strikes me as
un-Racket-ey and what alternatives might be.

I think one part of it is that compiling differently based on environment
variables seems to go against the principle that "Racket internalizes
extra-linguistic mechanisms" (
http://felleisen.org/matthias/manifesto/sec_intern.html). For a practical
example, environment variables are vexing on Mac OS for GUI programs.

Another issue is that this approach means that only one compiled
configuration exists at a time. In some cases maybe that's right: I've had
files in which I manually switch the definition of a macro to, say, add
some `printf`s that I only want when I'm actively working on that specific
file. But more often, if it makes sense for multiple versions of a program
to exist—say, your example of different architectures—I think it also makes
sense for them to be able to exist simultaneously.

Most seriously, depending on exactly how you use these compile-time
environment variables, it seems like you could negate some of the benefits
of the "separate compilation guarantee," particularly if you are assuming
that all of your modules are compiled at the same time.

In terms of an alternative, I will pass on an approach suggested to me by
Jack Firth, Tony Garnock-Jones, and others on this list (
https://groups.google.com/d/msg/racket-users/ftr4GDy7LG0/Qcm2LaNQDAAJ):
instead of having one "main module" that is your program, define each
variant of your program as a module that declares its configuration. I have
been doing this myself, and I'm very happy with the approach. In my case
the configuration consists of using `parameterize` at runtime, but I expect
you could find a way to express whatever you need to.

-Philip


> >>
> >> I have a bunch of other options that don't matter for the moment.
> >>
> >> One of the things I noticed is that in some cases when I run my
> >> executable, compile time code living inside begin-for-syntax to check if
> >> a variable has been defined during compilation or not is triggered. At a
> >> point, which I didn't expect any more syntax expansion to occur.
> >>
> >> I can't really reproduce the issue with a small example yet but I
> >> noticed something:
> >>
> >> main.rkt:
> >>
> >> #lang racket
> >>
> >> (require (file "arch-choice.rkt"))
> >>
> >> (module+ main
> >> (printf "arch: ~a~n" (get-path)))
> >>
> >> arch-choice.rkt:
> >>
> >> #lang racket
> >>
> >> (provide get-path)
> >>
> >> (begin-for-syntax
> >>
> >> (define arch-path (getenv "ARCH"))
> >>
> >> (unless arch-path
> >>   (raise-user-error 'driver "Please define ARCH with a suitable path")))
> >>
> >> (define-syntax (get-path stx)
> >> (datum->syntax stx arch-path))
> >>
> >> Then just to make sure nothing is compiled I remove my zos:
> >> $ find . -type f -name '*.zo' -exec \{\} \;
> >>
> >> Then compile it:
> >> $ ARCH=foo raco exe main.rkt
> >>
> >> In this case if you run ./main you'll get 'arch: foo' back which is fine
> >> so I can't reproduce what I see in my software which is with some
> >> combinations of compile time options, I see:
> >> 'driver: Please define ARCH environment variable'
> >>
> >> which should even be part of the executable because it's a compile time
> >> string (or so I thought).
> >>
> >> So I did on the above example:
> >> $ strings main | grep ARCH
> >> PLANET-ARCHIVE-FILTER
> >> ARCH"
> >> ''Please define ARCH with a suitable path
> >>
> >>
> >> OK, so, this agrees with what I see in my program: compile-time error
> >> strings still exist in the code. Why is that? I thought that only fully
> >> expanded code (compiled-code) would make it to the executable file.
> >>
> >> Another thing that might help me understand what's going on, is there a
> >> way to extract the bytecode from the executable and decompile it?
> >>
> >> Thanks,
> >>
> >>
> >> --
> >> Paulo Matos
> >
>
> --
> Paulo Matos
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to