chicken-users
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]