[Haskell-cafe] Lazy series [was : Preventing sharing]

Sat Jan 9 15:11:34 UTC 2016

Sharing a private conversation, with the permission of Jerzy.

On Sat, Jan 09, 2016 at 11:45:00AM +0100, Jerzy Karczmarczuk wrote:
> Again: *exps = 1 + integral exps*
>
> I said that if RHS exps is evaluated, it cannot work.
>
> >>>But if it evaluates to a thunk ...
> >>Then, on which premises you call the language "strict"?
>
> >Why not?
> >
> >A thunk could either be a delayed function call, or it could be a memoised
> >thunk, such as OCaml (a strict language) provides
> >
> >    http://caml.inria.fr/pub/docs/manual-ocaml/libref/Lazy.html
[...]
> But in the original expression with exps, you don't delay anything.
> You don't construct *exps()*, or equivalent. This variable is just
> variable, lexical atom, and either you evaluate it or not. If not,
> don't call the language strict. If there is a delay form introduced
> by the compiler, the language is not strict.
>
> If you don't agree, I suggest that instead of asking "why this
> doesn't work, it should!" , simply implement it.

Oleg has already provided most of the solution

http://okmij.org/ftp/ML/powser.ml

The aim is

exps = 1 + integral exps

In Oleg's framework the answer is

let exps = I.fix (fun e -> int 1 +% integ e)

In a hypothetical OCaml with typeclasses, this becomes

let exps = I.fix (fun e -> 1 + integ e)

The remaining objection is the presence of the fix.  The solution here is to
allow the language to support recursive bindings of lazy values[1], not just
of function values.  The we could write

let rec exps = 1 + integ exps

If you still do not agree I would appreciate it if you could explain why
such a language

a) could not exist, or

b) would not be called "strict"

If you're still not convinced, consider a lazy language, Haskell--, which
doesn't allow recursive bindings of non-function types.  In Haskell-- you
*cannot* write

exps = 1 + integral exps

but you have to write

exps = I.fix (\e -> 1 + integral e)

So we see that the nice syntax "exps = 1 + integral exps" is not due to
laziness (since Haskell-- is lazy, but you cannot write that).  Instead the
nice syntax is due to lazy recursive bindings, and this sugar can exist as
well in a strict language as it can in a lazy one.

Tom

[1] Note that recursive bindings are anyway just syntactic sugar for a fixed
point.  The definition

sum = \x -> case x of
[]     -> 0
(x:xs) = x + sum xs

is (essentially) sugar for

sum = fix (\sum' x ->
case x of
[]     -> 0
(x:xs) = x + sum' xs)

anything.