postpone function evaluation

2 views
Skip to first unread message

max.wolf

unread,
Jan 22, 2010, 3:28:40 PM1/22/10
to pure-lang
Hi

Albert explained in a previous post, that the way to postpone function
evaluation is to use a closure with a dummy argument:
let x = (\_->foo bar);
and to evaluate it later with
x dummy;

He also explained that quote/eval is much slower, because the compiler
is used to evaluate.
However currently i use quote/eval in my code, since it is much easier
to write and even more to read.
let x = 'foo bar;
eval x;

I was trying to achieve the performance of the closure style with the
syntax of quote/eval.
-Laziness is one approach, but works only once.
-A macro like
def postpone x y = (\_->x y);
works fine but can only be written for a given arity.

I would appreciate some syntactic sugar for "zero argument closures",
or any other way to achieve the desired effect with a prefix syntax
like quote.


Max

Albert Graef

unread,
Jan 23, 2010, 1:22:34 AM1/23/10
to pure...@googlegroups.com
max.wolf wrote:
> He also explained that quote/eval is much slower, because the compiler
> is used to evaluate.

Yes, that needs to be done so that macros and special forms are handled
correctly.

> -A macro like
> def postpone x y = (\_->x y);
> works fine but can only be written for a given arity.

Just define it like this:

def postpone x = \_->x;
doitnow x = x ();

Example:

> using system;
> let x = postpone (puts "Howdy!"); x;
#<closure 0x7f2629c39458>
> doitnow x;
Howdy!
7
> doitnow x;
Howdy!
7

Is that what you want?

Albert

--
Dr. Albert Gr"af
Dept. of Music-Informatics, University of Mainz, Germany
Email: Dr.G...@t-online.de, a...@muwiinfa.geschichte.uni-mainz.de
WWW: http://www.musikinformatik.uni-mainz.de/ag

max.wolf

unread,
Jan 23, 2010, 7:39:40 AM1/23/10
to pure-lang
Hi

Exactly what i wanted. I was just surprised that it works.
It shows, that I did not understand macros.
For some reason i thought that this way the argument to postpone would
get rewritten only once and that doitnow would return the result.
But that is obviously wrong.
That was an eye opener.


Thx,

Max

Albert Graef

unread,
Jan 23, 2010, 9:45:07 AM1/23/10
to pure...@googlegroups.com
max.wolf wrote:
> Exactly what i wanted. I was just surprised that it works.
> It shows, that I did not understand macros.
> For some reason i thought that this way the argument to postpone would
> get rewritten only once and that doitnow would return the result.

No, macros get rewritten in an extra preprocessing stage before
compilation happens, so nothing gets executed before the resulting code
is actually run.

Here's a little trick that I find useful to see what's going on in such
situations. Just create a function with the code you want to evaluate in
the body, and then use the 'show' command which displays what exactly
was substituted:

> def postpone x = \_->x;

> foo = postpone (puts "Howdy!");
> show foo
foo = \_ -> puts "Howdy!";

There you have it. 'postpone (puts "Howdy!")' was rewritten to '\_ ->
puts "Howdy!"' by the macro evaluator even before the compiler sees the
definition of 'foo'.

So, when you type 'let x = postpone (puts "Howdy!")', it's exactly the
same as if you had written 'let x = \_ -> puts "Howdy!"'. The 'puts'
there is inside the lambda body, so nothing gets evaluated at this
point. That happens when you run 'doitnow x', which just applies the
lambda to a dummy argument, causing the lambda body to be executed.

> That was an eye opener.

Ok, glad that I could help. :)

Cheers,

Reply all
Reply to author
Forward
0 new messages