[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Chicken-users] Re: interpreter/compile mismatch
[Chicken-users] Re: interpreter/compile mismatch
Thu, 26 Feb 2004 09:39:33 +0100
> That the interpreter includes some functionality that has to be explicitly
> loaded in compiled code is something that bothers me as well, but I haven't
> found any fully satisfying solution for this. Depending on a user's .csirc
> isn't too good: If one wants to write scripts, it is important that the amount
> of work to add the required stuff is kept to a minmum, and scripts are
> (and should be) self-contained (`-script' implies `-no-init').
The fact that scripts have to be self-contained means that the developer has
to include the desired libraries by hand. Period.
This also has the advantage that the script can be compiled without
including everything by default.
A different situation is when I use the interpreter for quick and dirty
checks (for instance if I am unsure about the right syntax for a given
command, and I try a few experiments on the repl): in this case including
everything makes sense, and this can be done by tweaking .csirc, if you
want to. This is the situation I was thinking about.
Having everything included by default is a bad idea and I have already
been bitten by that. The problem is that srfi-1 uses very generic names
such as break, span, delete, etc. Suppose now that I am debugging a
program with an escape continuation called "break". I am in a section of
my code where "break" should not be defined, but Chicken sees the "break"
from srfi-1 and gives me a very misleading error message. What happens?
I spend precious time to figure out that "break" is already defined
somewhere. Knowing by heart all predefined names is not a solution:
maybe I am expected to know all SRFI's, but I am not expected to know
all Chicken's libraries, *even the libraries I do not use*, just to
prevent name collisions!
The lack of a module system is not a big issue for code written by me, since
I always wrap it in a lexical scope and import identifiers with various tricks;
however I would welcome some way to prevent names imported from the standard
library to pollute my namespace. It would be enough to have the ability of
importing them with a prefix on demand. Writing a good module system is a
serious task and we don't need it for the moment; but we need *right now*
a way to protect our namespace! (IMO, of course)
> A possible option would be to add all the default stuff to compiled code,
> but that is unwieldy, for example for code that is to be embedded in another
> application. Incidentally, compiling scripts with a "#!/.../csi -script'
> header does exactly the right thing and includes all necessary units.
So you also include stuff you don't need. Uhmmph! :-(
> Hm. I don't know - removing dynamism from the interpreter sounds like
> a step back to me. Again, I'm aware of the problem, but I think any attempt
> to "solve" it, will reduce functionality.
> A (hypothetical) implementation would mean, that at macro-expansion time,
> all code executing inside macro-expanders uses a pristine, minimal
> environment, right? Unfortunately doing this will IMHO make the
> macro-expansion (and the eval-when semantics) rather complicated, for
> little gain.
This is a valid concern. I would take this approach: ideally, one should try
to make the interpreter as close to the compiler as possible. However, if
this is too much work, the one should document the differences in a section
of the manual. A documented bug is not more a bug, it is just a wart ;)
> (eval-when (compile eval)
> (define (make-macro name)
> (eval `(define-macro (,name x) x))) ; define make-macro at compile-time
> (make-macro 'identity-macro) ) ; and define another macro with it.
> (display (identity-macro 1))
Aha! It is the "load" option! I originally wrote
(load compile eval)
(define (make-macro name)
(eval `(define-macro (,name x) x)))
(make-macro 'identity-macro) )
(display (identity-macro 2))
and I got (in the compiler)
Error: unbound variable: x
rtm.scm: 12 make-macro
rtm.scm: 10 eval
I was (and still I am) puzzled because I thought I wrote eval-when in right
but still it didn't worked with a cryptic error message. I see now that the
was with the "load" option. Why it is so? I thought the "load" option meant
this part at load time" when the script is loaded by another program. I didn't
expect the "load" option to be somewhat "dangerous", i.e. making my program not
working if given.
> Yes, this is annoying sometimes (I have the same problem myself from
> time to time). Low-level macros are very easy to implement, and the
> implications of the when, what and how of macro-expansion in a system
> that provides both a batch-compiler and interpreter are, well, complicated...
> How do other implementations handle it?
> - PLT: executes macro expanders in a clean, separate environment (with the
> help of a powerful module system)
Yeah, but it is cumbersome to use and I am forced to put all the helper
functions for my macros in a separate module. I liked Chicken because
it is simpler. Yes, there is this confusion with eval-when which is required
in the compiler and not in the interpreter, but apart from that eval-when
makes sense and it is easier to use than PLT module system. Even if I
do not contest that PLT approach is probably better in the long run.
> - Scheme48, Guile, ...: interpreters only
> - Larceny, Chez: compile "in-core", no batch-compilers (so no real difference
> an interpreter)
> - Gambit, Bigloo: they probably have the exactly the same problems as Chicken
> (but I'm not sure - if someone knows more about this, I'd be happy to hear it)
> A valid point of view. And I definitely agree with you that it's a problem.
> I will think about separate macro-expansion environments, perhaps it's not
> going to be too hard to do...
> (But be sure that _when_ it is possible, there will be a command-line option
> to disable it. ;-)
I am not sure if this is worth the effort. Wouldn't be simpler to
expand the eval-when documentation, which currently is restricted
to the following (somewhat cryptic) paragraph?
[syntax] (eval-when (SITUATION ...) EXP ...)
Controls evaluation/compilation of subforms. SITUATION should be
one of the symbols eval, compile or load. When encountered in the
evaluator, and the situation specifier eval is not given, then this
form is not evaluated and an unspecified value is returned. When
encountered while compiling code, and the situation specifier compile
is given, then this form is evaluated at compile-time. When encountered
while compiling code, and the situation specifier load is not given,
then this form is ignored and an expression resulting into an unspecified
value is compiled instead. Note: It is currently not possible to use
define-syntax or define inside eval-when forms when hygienic macros
- [Chicken-users] Re: interpreter/compile mismatch,