unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* Eval, tail calls, (current-module), and backward compatibility
@ 2012-01-17  3:28 Mark H Weaver
  2012-01-17 11:02 ` David Kastrup
                   ` (3 more replies)
  0 siblings, 4 replies; 17+ messages in thread
From: Mark H Weaver @ 2012-01-17  3:28 UTC (permalink / raw)
  To: guile-devel

Hello all,

There's a problem with Guile's `eval'.  It doesn't do proper tail
recursion as mandated by R5RS et al, and unfortunately we can't fix this
without changing its behavior in a potentially incompatible way.

The problem is that `eval' uses dynamic-wind to temporarily set
(current-module) during the dynamic extent of the expansion and
evaluation of its form.  Ideally, it should set (current-module) only
during expansion, _not_ during evaluation.

It is worthwhile to consider what (current-module) is for, and how it
should be used.  This seems to be an area of great confusion.

(current-module) should be relevant only at the beginning of
macro-expansion: before any program transformations are performed,
(current-module) is "baked" into every symbol of the top-level form.
(psyntax actually does this lazily, but the effect is the same).

After that, (current-module) should be completely irrelevant to the rest
of compilation and evaluation.  After expansion has begun, the expanded
code is in general a patchwork of code fragments from many different
modules, and thus it no longer makes sense to talk about "the current
module".

Instead, the compiler looks at the modules that were baked into the
identifier.  For example, each top-level variable reference refers to
the module that was baked into its corresponding source identifier
before macro expansion.

It sometimes makes sense for the user to (set-current-module <module>).
This can be done within an REPL for example.  It can also be done in a
compiled file within (eval-when (compile) ...), which will cause
subsequent top-level forms to be expanded within the newly changed
(current-module).  This is implicitly done by `define-module'.

Pretty much the only proper use of (current-module) is to implement
REPLs and things of that sort.  It has nothing to do with the code that
is currently running.  It doesn't even really have to do with the code
that is currently being expanded, so it's almost never the right thing
to look at within procedural macros.

* * * * *

Can we fix this?

Ideally, I think that `eval' should set (current-module) during
expansion, but _not_ during evaluation.  Then it can be properly tail
recursive.  However, some code out there might depend on the existing
behavior, so I guess we can't change this, at least not in 2.0.  Bummer.

  (BTW, `local-eval' accepts a module as its second argument, and
   conforms to the R5RS requirements of `eval', so it can serve as a
   proper replacement for Guile's broken `eval')

Similarly, (compile '<expr> #:env <module>) should set (current-module)
during expansion but _not_ during evaluation.  Then it can be properly
tail recursive and have cleaner semantics.  It might not be too late to
fix this in 2.0.

  (Note that `local-compile' also conforms to the R5RS requirements of
   `eval', so can also serve as a proper `eval' replacement)

What do other people think?

    Best,
     Mark



^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2012-01-23 10:41 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-01-17  3:28 Eval, tail calls, (current-module), and backward compatibility Mark H Weaver
2012-01-17 11:02 ` David Kastrup
2012-01-17 21:02   ` Mark H Weaver
2012-01-18  9:36     ` Andy Wingo
2012-01-18 19:58       ` Mark H Weaver
2012-01-18 21:52         ` Andy Wingo
2012-01-18 21:18 ` Ludovic Courtès
2012-01-18 22:01   ` Andy Wingo
2012-01-18 22:21     ` Ludovic Courtès
2012-01-18 22:27       ` Andy Wingo
2012-01-18 22:47         ` Ludovic Courtès
2012-01-18 22:56           ` Andy Wingo
2012-01-21 15:59 ` David Kastrup
2012-01-21 18:28   ` Mark H Weaver
2012-01-21 18:33     ` David Kastrup
2012-01-21 19:06       ` Mark H Weaver
2012-01-23 10:41 ` Andy Wingo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).