Re: streams and lazy evaluation

Pierre Weis (weis@pauillac.inria.fr)
Mon, 16 Oct 1995 19:31:05 +0100 (MET)

From: Pierre Weis <weis@pauillac.inria.fr>
Message-Id: <199510161831.TAA02405@pauillac.inria.fr>
Subject: Re: streams and lazy evaluation
To: cheno@micronet.fr (Laurent CHENO)
Date: Mon, 16 Oct 1995 19:31:05 +0100 (MET)
In-Reply-To: <v01520c01aca679354179@[194.51.75.135]> from "Laurent CHENO" at Oct 15, 95 10:41:14 am

> #let rec from n = [< 'n ; from (n+1) >] ;;
> from : int -> int stream = <fun>
> #let rec version2 flot = match flot with
> [< 'n ; version2 reste >] -> [< '(2*n) ; reste >] ;;
> version2 : int stream -> int stream = <fun>
> #version2 (from 0) ;;
> Uncaught exception: Out_of_memory

This is due to the evaluation strategy. You force the evaluation of
the lazy thunk by your pattern matching, since to prove that your
stream can be matched by the pattern:

[< 'n ; version2 reste >]

the compiler must generate code to call version2 on the tail of the
stream. This falls in an infinite loop.

In contrast, in your first version, the recursive call to version is
in the right hand-side of the clause, when you build the final
result. This way it can be left unevaluated, until some piece of code
has to do some pattern matching on this stream result.

> #let rec version1 flot = match flot with
> [< 'n >] -> [< '(2*n) ; version1 flot >] ;;
> version1 : int stream -> int stream = <fun>

To sumarize: stream construction leads to lazyness, while stream
pattern matching leads to unfrozing.

Pierre Weis
----------------------------------------------------------------------------
WWW Home Page: http://pauillac.inria.fr/~weis
Projet Cristal
INRIA, BP 105, F-78153 Le Chesnay Cedex (France)
E-mail: Pierre.Weis@inria.fr
Telephone: +33 1 39 63 55 98
Fax: +33 1 39 63 53 30
----------------------------------------------------------------------------