unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* memoization and conditional defines
@ 2002-11-07 17:52 Dirk Herrmann
  2002-11-07 19:08 ` Bruce Korb
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Dirk Herrmann @ 2002-11-07 17:52 UTC (permalink / raw)


Hi folks,

I would again like to put your focus on the question, whether we should
support top level forms like the following:

  (if <condition> (define foo bar))

In the course of a former conversation on this list there was a consensus
that such commands should be supported.  However, I have now a better
understanding why allowing such a thing is problematic, and I would like
to make this obvious for everybody.  We should then rethink the decision,
and based on the extended knowledge either keep it (and know what this
will cost us) or redecide.


As an introduction, I would give an example of how memoization works, at 
least in principle.  Assume the following code:
  (if foo bar)
It is a list made of three symbols 'if, 'foo and 'bar.  The memoizer will
take the expression and try to pre-compute as much of it as possible.  
The result will be:
  (#@if #<variable: "foo"> #<variable: "bar"> #<unspecified>)
That is, the memoizer looks up 'if in the symbol table and finds that it
is bound to the corresponding builtin r5rs macro.  The memoizer then calls
the corresponding transformer function which is responsible to transform
if-expressions into the memoized format.  The transformer function for the
if-expression then recursively calls the memoizer to memoize the condition
form.  In this case, the memoizer finds that 'foo is bound on the top
level. It performs the corresponding variable lookup and returns the
variable object as the memoized code.  The transformer function for the
if-expression then calls the memoizer to memoize the then-part, and again
the corresponding variable object is returned.  Finally, the transformer
function for the if-expression adds the missing else-part, namely the
#<unspecified> value, which is exactly what guile returns for a missing
else-form.  The resulting memoized if-expression is prepended by the
immediate value #@if, which is a guile-internal value only used to
indicate a memoized if-expression to the executor.

For the later execution, this has the benefit, that a) the if-expression
is quickly recognizable because its first element is the immediate value
#@if, b) the executor does not have to distinguish between if-then and
if-then-else and c) the executor does not have to do any variable lookups
any more, since they are done once during memoization.


Now, getting one step closer to the problem:  Memoization for a
cond-expression is somewhat more tricky:  Assume the following code:
  (cond (#t => some-function))
will be memoized to:
  (#@cond (#t #@=> #<variable: "some-function">))
because in a typical environment there is no binding for the symbol '=>.
That means, during memoization it is detected that the '=> is used to
express the special syntactic form.  Since the memoized code contains the
immediate value #@=>, the executor will treat the cond-expression as
follows: The condition is found to be true, and that true value will be
passed as an argument to the value of 'some-function.

In contrast, if there was a binding for '=>, R5RS demands that the use of
the symbol '=> should indicate the use of the value to which '=> is bound.
That means, the memoizer should rather return code as follows:
  (#@cond (#t #<variable: "=>"> #<variable: "some-function">))
The executor will then treat the cond-expression as follows: The condition
is found to be true.  Then, the value of => is looked up.  Finally, the
value of some-function is looked up and returned as the result.  In other
words, the fact that there is a binding for '=> makes this cond-expression
look like
  (cond (#t some-expression some-function))
instead of
  (cond (#t => some-function))

This behaviour is demanded by R5RS for all kinds of macros.  Therefore,
the cond-macro is not a special case, but is used here only as an example
for a general rule:  The way syntax transformation is performed depends on
the set of bindings that are visible at the moment of the transformation.


Now, stepping directly into the problem:  How should the following
top-level form be memoized:
  (begin
    (if some-condition (define => #t))
    (define (foo x)
      (cond (x => some-function))))
There are two possibilities, what the memoized code could look like:
Variant a)
  (@#begin
    (#@if #<variable: "some-condition"> (#@define => #t) #<unspecified>)
    (#@define (foo x)
      (#@cond (#<local-ref: x> #@=> #<variable: "some-function">))))
Variant b)
  (@#begin
    (#@if #<variable: "some-condition"> (#@define => #t) #<unspecified>)
    (#@define (foo x)
      (#@cond (#<local-ref: x> #<variable: "=>"> #<variable: "some-function">))))
But: How should a memoizer that is performed _before_ execution know what
will be correct?  How should it know whether there will be a binding for
'=>?


R5RS simplifies this problem by only allowing definitions if they are
_really_ on the top-level.  The only thing allowed for top-level
definitions is to put them within 'begin forms.  But this is not actually
a problem, because it is easily possible to split up top-level 'begin
forms like the following
  (begin form1 form2 ...)
into the corresponding top level forms
  form1
  form2
  ...
and have each one of them separately memoized and executed.


The consequence of all the above is, that allowing things like
  (if <condition> (define foo bar))
makes it much more difficult to get memoization right.  That is, if we
really allow such forms, this means that we have the following choices:
 a) be incompatible with R5RS.  This will, however, require us to make it
    clear for users of guile where and how we deviate from R5RS.  Taking
    this option will also imply that our macros are not really hygienic.
    It also means that an interpreted system will behave different than a
    compiled or memoized system, even if there are no uses of eval or
    load.
 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.


Conclusion:  We should rethink the decision to allow expressions like
  (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


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

* Re: memoization and conditional defines
  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  3:11 ` Rob Browning
  2002-11-17 20:41 ` Marius Vollmer
  2 siblings, 2 replies; 14+ messages in thread
From: Bruce Korb @ 2002-11-07 19:08 UTC (permalink / raw)
  Cc: guile-devel

Dirk Herrmann wrote:
> 
> Hi folks,
> 
> I would again like to put your focus on the question, whether we should
> support top level forms like the following:
> 
>   (if <condition> (define foo bar))
> 
> In the course of a former conversation on this list there was a consensus
> that such commands should be supported.  However, I have now a better
> understanding why allowing such a thing is problematic,
....
> As an introduction, I would give an example of how memoization works, at
> least in principle.

I don't care how memoization works.  I understand there are
optimization issues.  Optimizing isn't important to me, or
I would not use an interpretive language as my "extension
language".  If you add a disabling mechanism, then you'll
have the best of all worlds.  You can memoize/optimize to
your heart's content, and I'll disable it for my purposes.
If that is not practical and Guile becomes, essentially,
an semi-compiled language with constraints on where
defines may happen, then my goose will be cooked.

BTW, my guess is that memoizing Guile will make it go much slower.
Generally, I just pass Guile a few bytes to process (mostly less
than 40), handle the result and go on.  In fact, the most common
expressions are:  (set! foo (....)) and (. foo).  *Sometimes*, however,
I have some complex stuff that queries the environment to determine
what is going on and from that has to define various different
things.  It's that "sometimes" that hurts.


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


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

* Re: memoization and conditional defines
  2002-11-07 19:08 ` Bruce Korb
@ 2002-11-07 20:54   ` Clinton Ebadi
  2002-11-07 23:22   ` Lynn Winebarger
  1 sibling, 0 replies; 14+ messages in thread
From: Clinton Ebadi @ 2002-11-07 20:54 UTC (permalink / raw)
  Cc: guile-devel

> I don't care how memoization works.  I understand there are
> optimization issues.  Optimizing isn't important to me, or
> I would not use an interpretive language as my "extension
> language".  If you add a disabling mechanism, then you'll
> have the best of all worlds.  You can memoize/optimize to
> your heart's content, and I'll disable it for my purposes.
> If that is not practical and Guile becomes, essentially,
> an semi-compiled language with constraints on where
> defines may happen, then my goose will be cooked.

Not to mention how Guile wouldn't be Scheme anymore. Why can't code be 
memiozied and compiled incrementally?

-- 
http://unknownlamer.org
Truth lies in loneliness
When hope is long gone by


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


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

* Re: memoization and conditional defines
  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
  1 sibling, 1 reply; 14+ messages in thread
From: Lynn Winebarger @ 2002-11-07 23:22 UTC (permalink / raw)
  Cc: guile-devel

On Thursday 07 November 2002 14:08, Bruce Korb wrote:
> I don't care how memoization works.  I understand there are
> optimization issues.  Optimizing isn't important to me, or
> I would not use an interpretive language as my "extension
> language".
     It's really about correctness of macro expansion in a broader
sense than just the core macros ('lambda, 'define, etc).  The core
macros just transform the sexpression into a more explicit parse
tree.  If you didn't do that, you could never be sure whether your
function would actually be a function or not. The symbol 'lambda
can be redefined at will by code in R5RS.  There are no
reserved keywords.

> BTW, my guess is that memoizing Guile will make it go much slower.
      Guile has been memoizing since its creation (or rather, the creation
of SCM).
      If you're worried about (if <test> (define <foo> <bar>)), you
can always use
(if <test> (eval '(define <foo> <bar>)))
which will do what you want.  eval's always execute in a top-level environment,
no matter where the expression occurs in the code.  And that '(define <foo> <bar>)
would get re-expanded every time it got executed.

Lynn


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


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

* Re: memoization and conditional defines
  2002-11-07 23:22   ` Lynn Winebarger
@ 2002-11-08  0:46     ` Bruce Korb
  2002-11-08  1:24       ` Lynn Winebarger
  0 siblings, 1 reply; 14+ messages in thread
From: Bruce Korb @ 2002-11-08  0:46 UTC (permalink / raw)
  Cc: Dirk Herrmann, guile-devel

Lynn Winebarger wrote:

>       If you're worried about (if <test> (define <foo> <bar>)), you
> can always use
> (if <test> (eval '(define <foo> <bar>)))
> which will do what you want.  eval's always execute in a top-level environment,

Goes to show you how superficially I know Scheme/R4r5/Lisp/whatever.
I use it to accomplish a few tiny tasks and mostly live in the
land of C & kernel drivers.

It will be a bit of a nuisance when the (if <test> (define <foo> <bar>))
stuff chokes, but I would expect a sensible error message that will
lead me to wrapping that stuff in an eval once its encountered, yes?
With that, I'm fine with whatever you want to do....


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


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

* Re: memoization and conditional defines
  2002-11-08  0:46     ` Bruce Korb
@ 2002-11-08  1:24       ` Lynn Winebarger
  2002-11-09  8:19         ` Dirk Herrmann
  0 siblings, 1 reply; 14+ messages in thread
From: Lynn Winebarger @ 2002-11-08  1:24 UTC (permalink / raw)
  Cc: Dirk Herrmann, guile-devel

On Thursday 07 November 2002 19:46, Bruce Korb wrote:
> 
> It will be a bit of a nuisance when the (if <test> (define <foo> <bar>))
> stuff chokes, but I would expect a sensible error message that will
> lead me to wrapping that stuff in an eval once its encountered, yes?

     Depends on how it's implemented.  It doesn't have to be an error
per se, but the _binding_ (as opposed to the side-effecting) of the
variable would happen before the test was evaluated.  That's probably 
_not_ the behaviour you'd expect from that construct.  
     If it's made an error, I don't know what the actual error message 
would be.  There are only a few types of places defines are really
legitimate:  at the top level, at the head of a body, inside a begin
clause in any other legitimate location (recursively) - but only
before non-defines in a body occurence (following macro expansion).

Lynn


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


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

* Re: memoization and conditional defines
  2002-11-07 17:52 memoization and conditional defines Dirk Herrmann
  2002-11-07 19:08 ` Bruce Korb
@ 2002-11-08  3:11 ` Rob Browning
  2002-11-09  9:00   ` Dirk Herrmann
  2002-11-17 20:41 ` Marius Vollmer
  2 siblings, 1 reply; 14+ messages in thread
From: Rob Browning @ 2002-11-08  3:11 UTC (permalink / raw)
  Cc: guile-devel

Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> writes:

> But: How should a memoizer that is performed _before_ execution know what
> will be correct?  How should it know whether there will be a binding for
> '=>?

It seems like it can't in that case.

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.

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.

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))

>  a) be incompatible with R5RS.  This will, however, require us to make it
>     clear for users of guile where and how we deviate from R5RS.  Taking
>     this option will also imply that our macros are not really hygienic.
>     It also means that an interpreted system will behave different than a
>     compiled or memoized system, even if there are no uses of eval or
>     load.

Hope we can avoid that one.

>  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?

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu


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


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

* Re: memoization and conditional defines
  2002-11-08  1:24       ` Lynn Winebarger
@ 2002-11-09  8:19         ` Dirk Herrmann
  2002-11-09 22:39           ` Bruce Korb
  0 siblings, 1 reply; 14+ messages in thread
From: Dirk Herrmann @ 2002-11-09  8:19 UTC (permalink / raw)
  Cc: guile-devel

On Thu, 7 Nov 2002, Lynn Winebarger wrote:

> On Thursday 07 November 2002 19:46, Bruce Korb wrote:
> > 
> > It will be a bit of a nuisance when the (if <test> (define <foo> <bar>))
> > stuff chokes, but I would expect a sensible error message that will
> > lead me to wrapping that stuff in an eval once its encountered, yes?
> 
>      Depends on how it's implemented.  It doesn't have to be an error
> per se, but the _binding_ (as opposed to the side-effecting) of the
> variable would happen before the test was evaluated.  That's probably 
> _not_ the behaviour you'd expect from that construct.  
>      If it's made an error, I don't know what the actual error message 
> would be.  There are only a few types of places defines are really
> legitimate:  at the top level, at the head of a body, inside a begin
> clause in any other legitimate location (recursively) - but only
> before non-defines in a body occurence (following macro expansion).

If we are going to disallow defininitions except when on the real top
level, then it is easy to issue an error message when something like
  (if <test> (define <foo> <bar>))
is encountered.  Guile could, for example, issue an error message like
  "bad define placement"
or even
  "bad define placement.  Read guile's documentation about definitions to
understand why this is not allowed."
or something similar.  I hope this would be good enough for Bruce's
purposes.

Best regards,
Dirk Herrmann



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


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

* Re: memoization and conditional defines
  2002-11-08  3:11 ` Rob Browning
@ 2002-11-09  9:00   ` Dirk Herrmann
  2002-11-09  9:41     ` tomas
  2002-11-09 17:08     ` Rob Browning
  0 siblings, 2 replies; 14+ messages in thread
From: Dirk Herrmann @ 2002-11-09  9:00 UTC (permalink / raw)
  Cc: guile-devel

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


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

* Re: memoization and conditional defines
  2002-11-09  9:00   ` Dirk Herrmann
@ 2002-11-09  9:41     ` tomas
  2002-11-09 17:08     ` Rob Browning
  1 sibling, 0 replies; 14+ messages in thread
From: tomas @ 2002-11-09  9:41 UTC (permalink / raw)
  Cc: Rob Browning, guile-devel

On Sat, Nov 09, 2002 at 10:00:49AM +0100, Dirk Herrmann wrote:
> 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.

[...]

> 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.

Ah. This half-answers my previous post, but see below.

[...]

> 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>)

Hmmm. Sounds more or less like what I was proposing, but in my world, these
substitutions would happen automatically. Which might make the code more
readable. Which might open optimization possibilities. Which might as well,
as you point out, obscure the fact that those constructions cost quite a
bit of performance. Hmmm.

>   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.

You are in the middle of the rat's nest and have to cope with other's
mumblings. Tanks for your patience :-)

> 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.

Yep, but...

imagine that some-condition `becomes known', just because the lexical
environment provides a constant binding to a constant (such code might
come out as a result of a macro expansion). Then, this explicit `barrier'
with eval which you are proposing would make further optimizations more
difficult, I think.

Or am I talking total nonsense?

Regards
-- tomas


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


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

* Re: memoization and conditional defines
  2002-11-09  9:00   ` Dirk Herrmann
  2002-11-09  9:41     ` tomas
@ 2002-11-09 17:08     ` Rob Browning
  1 sibling, 0 replies; 14+ messages in thread
From: Rob Browning @ 2002-11-09 17:08 UTC (permalink / raw)
  Cc: guile-devel

Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> writes:

> 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.

OK, that's pretty much what I expected.

> 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.

No argument here.  That's my default assumption as well.

> 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.

Agreed.  I'd definitely like to err on the side of making complicated
things clearer, so I'd favor making eval explicit as you suggest, and
(as I've probably said elsewhere) I'd definitely like to avoid
clevernesses or conveniences that make it harder know when you're
writing code that can be optimized.

> 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>)))

Ahh, that's what was confusing me.  I took your "let's are ok" too
broadly and I was wondering why

  (let ()
    (if <condition> (define => #t))
    (cond (#t => 'ok)))

would be fine.  Since that's not fine, I'm not confused :>

Thanks for the explanations.

-- 
Rob Browning
rlb @defaultvalue.org, @linuxdevel.com, and @debian.org
Previously @cs.utexas.edu


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


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

* Re: memoization and conditional defines
  2002-11-09  8:19         ` Dirk Herrmann
@ 2002-11-09 22:39           ` Bruce Korb
  0 siblings, 0 replies; 14+ messages in thread
From: Bruce Korb @ 2002-11-09 22:39 UTC (permalink / raw)
  Cc: Lynn Winebarger, guile-devel

Dirk Herrmann wrote:
> an error message like
>   "bad define placement"
> or even
>   "bad define placement.  Read guile's documentation about definitions to
> understand why this is not allowed."
> or something similar.  I hope this would be good enough for Bruce's
> purposes.

It would be great.  It would tell me exactly where I
need to wrap it with: (eval '...)


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


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

* Re: memoization and conditional defines
  2002-11-07 17:52 memoization and conditional defines Dirk Herrmann
  2002-11-07 19:08 ` Bruce Korb
  2002-11-08  3:11 ` Rob Browning
@ 2002-11-17 20:41 ` Marius Vollmer
  2002-11-17 21:42   ` Bruce Korb
  2 siblings, 1 reply; 14+ messages in thread
From: Marius Vollmer @ 2002-11-17 20:41 UTC (permalink / raw)
  Cc: guile-devel

Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> writes:

> I would again like to put your focus on the question, whether we should
> support top level forms like the following:
> 
>   (if <condition> (define foo bar))

I'd say that we might want to allow this, but don't try to make it
behave especially nice.  We should provide a better alternative,
however: Conditional 'defines' should be decided at compile time, not
at run-time.  We might extend 'cond-expand' to allow running arbitrary
code, or something in that direction.

-- 
GPG: D5D4E405 - 2F9B BCCC 8527 692A 04E3  331E FAF8 226A D5D4 E405


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


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

* Re: memoization and conditional defines
  2002-11-17 20:41 ` Marius Vollmer
@ 2002-11-17 21:42   ` Bruce Korb
  0 siblings, 0 replies; 14+ messages in thread
From: Bruce Korb @ 2002-11-17 21:42 UTC (permalink / raw)
  Cc: Dirk Herrmann, guile-devel

Marius Vollmer wrote:
> 
> Dirk Herrmann <dirk@sallust.ida.ing.tu-bs.de> writes:
> 
> > I would again like to put your focus on the question, whether we should
> > support top level forms like the following:
> >
> >   (if <condition> (define foo bar))
> 
> I'd say that we might want to allow this, but don't try to make it
> behave especially nice.

viz:  (if <condition> (eval '(define foo bar)))
Yes?

> We should provide a better alternative,
> however: Conditional 'defines' should be decided at compile time, not
> at run-time.  We might extend 'cond-expand' to allow running arbitrary
> code, or something in that direction.

For me, either/anything is fine.  I just have to be able
to accomplish it in some fashion.  The required syntax
is less interesting.


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


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

end of thread, other threads:[~2002-11-17 21:42 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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

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).