unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
From: Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de>
Cc: guile-devel@gnu.org
Subject: Re: memoization and conditional defines
Date: Sat, 9 Nov 2002 10:00:49 +0100 (CET)	[thread overview]
Message-ID: <Pine.GSO.4.05.10211090930520.22059-100000@sallust.ida.ing.tu-bs.de> (raw)
In-Reply-To: <87vg387o2y.fsf@raven.i.defaultvalue.org>

On Thu, 7 Nov 2002, Rob Browning wrote:

> I'm not entirely clear on the issues involved here, but I'd like to
> be, so please bear with me.  Would it be possible (and make any sense)
> to arrange for something like like "just in time" memoization for
> top-level forms (as I think Clinton may have suggested), or would that
> overly complicate the code?  i.e. don't memoize top-level expressions
> until you're ready to execute them.  Such an approach might prevent
> those bits from being compiled efficiently, but I suppose the user
> could choose whether or not to write things that way.

On-the-fly memoization is what guile currently does.  This does, however,
slow down evaluation, it complicates the evaluator and it does not allow
us to write out pre-compiled code in order to speed up startup time.

> There's still the question of whether or not we should even allow
> non-top-level defines like this, although I can understand the
> impulse, esp for configuration related decisions.  I'd say if
> supporting them leads to really nasty semantic or implementational
> complexities, especially if given suitable alternatives, then perhaps
> we shouldn't.

As has been said in previous mails, there are suitable alternatives for
conditional defines.
* For the general case
    (if <test> (define <foo> <bar>))
  one can use eval:
    (if <test> (eval '(define <foo> <bar>) (current-module)))
* The special case
    (if (not (defined? <foo>)) (define <foo> <bar>))
  which is probably very common when dealing with configuration issues can
  be replaced by the following pattern:
    (define foo-was-defined-before? (defined? '<foo>))
    (define <foo> (if foo-was-defined-before? <foo> <bar>)
  Note that the helper-variable foo-was-defined-before? is necessary
  because within a define form the symbol is already bound to a location
  (according to R5RS), that is we have to remember whether it had been
  defined before outside of the define form itself.

It took me quite some time to understand the issues involved with
conditional definitions.  My current effort to separate memoization and
execution made it clearer to me, because it reflects itself in the code
for the evaluator if you want to do things right.  This made me see one
thing:  The design decisions hidden in R5RS are typically based on very
thorough investigations of potential problems.  Implementations have to be
very careful to deviate from these decisions.

I favor to force users to use 'eval when trying to realize conditional
definitions.  The use of eval does not solve the theoretical problem of
how in the following code
  (begin
    (if some-condition (eval '(define => #t) (current-module)))
    (define (foo x)
      (cond (x => some-function))))
the cond-expression should be memoized.  However, for eval it is IMO 
easier to communicate the problems involved when distinguishing
compilation and interpretation:  When using eval, people typically
understand that the evaluated expression can not be pre-compiled.  In
contrast, conditional definitions seem so natural that people will
probably not be aware of the problems that are involved.

> Also, would eval-when based defines still be OK?  I would presume so,
> since they're essentially a conditionally included "begin block".
> 
>   (eval-when (compile)
>     (define => bar))

Since I assume that eval-when uses 'eval to execute the definition, then
everything would be OK here.

> >  b) complicate the memoization process in order to get things right.  An
> >     option that we have here is the following:  Top-level forms are not
> >     memoized but interpreted.  Memoization is only done whenever a
> >     non-top-level scope is entered, like a let-form, or a
> >     lambda-expression. The cost of this solution is that in addition to
> >     the memoizer and the executor we would need an interpreter.
> 
> Why are let forms and lambda expressions excluded?

Because definitions within a let form and a lambda expression are not
top-level.  Internal definitions are re-written into a letrec form:
  (lambda foo
    (define => #t)
    (cond (#t => 'ok)))
is transformed into
  (lambda foo
    (letrec ((=> #t))
      (cond (#t => 'ok))))
and it is clear to the memoizer that the cond-expression is OK.

It should be noted that internal definitions may also only occur at a
restricted set of places.  For example, even the current guile (which
allows conditional defines on the top level) does not support the
following:
  (lambda foo
    (if <condition> (define <foo> <bar>)))

Best regards,
Dirk Herrmann



_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://mail.gnu.org/mailman/listinfo/guile-devel


  reply	other threads:[~2002-11-09  9:00 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-11-07 17:52 memoization and conditional defines Dirk Herrmann
2002-11-07 19:08 ` Bruce Korb
2002-11-07 20:54   ` Clinton Ebadi
2002-11-07 23:22   ` Lynn Winebarger
2002-11-08  0:46     ` Bruce Korb
2002-11-08  1:24       ` Lynn Winebarger
2002-11-09  8:19         ` Dirk Herrmann
2002-11-09 22:39           ` Bruce Korb
2002-11-08  3:11 ` Rob Browning
2002-11-09  9:00   ` Dirk Herrmann [this message]
2002-11-09  9:41     ` tomas
2002-11-09 17:08     ` Rob Browning
2002-11-17 20:41 ` Marius Vollmer
2002-11-17 21:42   ` Bruce Korb

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=Pine.GSO.4.05.10211090930520.22059-100000@sallust.ida.ing.tu-bs.de \
    --to=dirk@sallust.ida.ing.tu-bs.de \
    --cc=guile-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).