简体   繁体   中英

How to emulate laziness

I was watching an interview with John Hughes and he was asked if he missed laziness when he switched from Haskell to Erlang. As an answer he said yes and he used tools to "emulate" it. My question is: How does one emulate laziness in a strict language? It Would be nice to see cools examples in mainstream languages.

The usual trick is to use a lambda (I guess that would be fun in Erlang).

Here is an example using Ruby:

Monad equivalent in Ruby

The basic idea is pretty simple... You take whatever expression you want to make lazy, wrap it in a zero-argument anonymous function, then evaluate that function when you want to force it.

If you only want to emulate non-strictness, then all you need is to wrap an expression into a function and invoke it when needed.

If you actually want to emulate laziness (ie, non-strictness with memoization), then you need to wrap that function into a mutable reference. Sketch in OCaml (ignoring exceptions):

type 'a lazy = 'a thunk ref
and 'a thunk = Lazy of unit -> 'a | Memo of 'a

let lazy f = ref (Lazy f)
let force l = match !l with
  | Lazy f -> let x = f () in l := Memo x; x
  | Memo x -> x

Except that OCaml already has this predefined in its library (in a way that also handles exceptions from f).

You may want to look at python generators in detail.

In short, these are objects which have a __next__ message, which allows them to yield one item. As such, they can be composed, so that processing at each step pulls an item from the next-composed generator.

In that way, python programmers can easily work with infinite sequences (or sequences of length one).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM