[nem-en] Questions about lazy evaluation

Kamil Skalski kamil.skalski at gmail.com
Sun Jun 11 21:30:39 CEST 2006


BTW, I just commited some changes in implicit operators for LazyValue,
so you can now write this code as:

>>>>>>>>>>>>>>>>>>
using System;
using System.Diagnostics;
using Nemerle;
using Nemerle.IO;

def tarai(x : int, y : int, z : LazyValue[int]) : int {
   if (x <= y) {
       y
   }
   else {
       tarai (
           tarai (x-1, y, z),
           tarai (y-1, z, x),
           lazy (tarai (z-1, x, y)))
   }
}

def x = 20;
def y = 10;
def z = 5;

def s = Stopwatch ();

s.Start ();
def a = tarai (x, y, z);
s.Stop ();

printf("tarai(%d, %d, %d) = %d - %ld\n", x, y, z, a, s.ElapsedMilliseconds);
>>>>>>>>>>>>>>

It is now clear where the lazy value needs to be used.


2006/6/11, Kamil Skalski <kamil.skalski at gmail.com>:
> Unfortunately with our implementation of lazy values as macros you
> need to explicitly give the correct delays to solve the problems.
> Those you specified did not do the work, since none of the three calls
> to tarai in second branch were not delayed.
> The delays which work for me are:
>
>  >>>>>>>>>>>>>>>>>>
> using System;
> using System.Diagnostics;
> using Nemerle;
> using Nemerle.IO;
>
> def tarai(x : int, y : int, z : LazyValue[int]) : int {
>    if (x <= y) {
>        y
>    }
>    else {
>        tarai (
>            tarai (x-1, lazy (y), z),
>            tarai (y-1, z, lazy (x)),
>            lazy (tarai (z-1, lazy (x), lazy (y))))
>    }
> }
>
> def x = 20;
> def y = 10;
> def z = 5;
>
> def s = Stopwatch ();
>
> s.Start ();
> def a = tarai (x, y, lazy(z));
> s.Stop ();
>
> printf("tarai(%d, %d, %d) = %d - %ld\n", x, y, z, a, s.ElapsedMilliseconds);
> >>>>>>>>>>>>>>>>>>>>>>>>>>>
>
> Haskell compiler did the stuff for you, but it just proves, that
> tracking how such programs are exactly computed is very hard. On the
> other hand if you have purely functional function, then you just don't
> care about evaluation order.
>
>
> 2006/6/11, mei <mei at work.email.ne.jp>:
> > Hi,
> >
> > There is a Haskell code.
> >
> > >| tarai.hs : Haskell sample
> > main = print (tarai 20 10 5)
> >
> > tarai :: Int -> Int -> Int -> Int
> > tarai x y z = if x <= y then y
> >                         else tarai (tarai (x-1) y z)
> >                                    (tarai (y-1) z x)
> >                                    (tarai (z-1) x y)
> > |<
> >
> > Run very fast above code. Because Haskell is lazy evaluation.  Then I
> > notice that Nemerle support lazy evaluation.  I try to convert it to
> > Nemerle.
> >
> > >| tarai.n : Nemerle sample
> > using System;
> > using System.Diagnostics;
> > using Nemerle;
> > using Nemerle.IO;
> >
> > def tarai(x : LazyValue[int], y : LazyValue[int], z : LazyValue[int]) :
> > LazyValue [int] {
> >     def a : int = x;
> >     if (a <= y) {
> >         y
> >     }
> >     else {
> >         tarai (
> >             tarai (lazy(x-1), y, z),
> >             tarai (lazy(y-1), z, x),
> >             tarai (lazy(z-1), x, y))
> >     }
> > }
> >
> > def x = 20;
> > def y = 10;
> > def z = 5;
> >
> > def s = Stopwatch ();
> >
> > s.Start ();
> > def a = tarai (lazy(x), lazy(y), lazy(z));
> > s.Stop ();
> >
> > printf("tarai(%d, %d, %d) = %d - %ld\n", x, y, z, a, s.ElapsedMilliseconds);
> >
> > |<
> >
> > But this is very slow.  Can I write faster code like Haskell ?
> >
> >
> > Thanks.
> >
> > --
> > mei <mei at work.email.ne.jp>
> >
> > _______________________________________________
> > https://nemerle.org/mailman/listinfo/devel-en
> >
>
>
> --
> Kamil Skalski
> http://nazgul.omega.pl
>


-- 
Kamil Skalski
http://nazgul.omega.pl



More information about the devel-en mailing list