[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Chicken-users] Re: interpreter/compile mismatch
From: |
Felix Winkelmann |
Subject: |
Re: [Chicken-users] Re: interpreter/compile mismatch |
Date: |
Thu, 26 Feb 2004 10:13:23 +0100 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113 |
address@hidden wrote:
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!
Ok. So what do others think? Should we change csi to _not_ link with
all the extra stuff? It's definitely possible, and I would be willing
to fix it. But if that's going to make life harder for others, I would
like to know about it.
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)
To prefix names from std-libs on import is currently not possible (or too
much overhead), AFAICT. Or better: it's probably not much less work than
a module system.
(Actually, I have a (very experimental) module system. I have to test it a
little
more, and there are one or two issues with it. If someone wants to take a peek,
please tell).
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! :-(
Agreed.
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 ;)
Absolutely.
(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
(eval-when
(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)
$ ./rtm
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
place
but still it didn't worked with a cryptic error message. I see now that the
problem
was with the "load" option. Why it is so? I thought the "load" option meant
"execute
this part at load time" when the script is loaded by another program.
No, "load" means that the code should execute at run-time (either in the
interpreter
or compiler). "compile" means during compiling + interpreting. "eval" means only
in the interpreter.
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
are enabled.
Very true. I will try to make it clearer.
cheers,
felix