My first thought was much like your second point! If we have lazy operations on collections, we’re 90% of the way to `seq` & similar lazy structures.
Edit: in fact, probably 99%. You just need to define the data structures as an initial operation that materializes values for subsequent operations on demand.
Yeah, years ago I got deep into this stuff and managed to implement a lot of it for fun, thinking I was doing something original, before discovering it’s not original (in my case, discovering Seq in OCaml). I think treating everything as lazy and potential infinite makes the implementation of operations much simpler than this article’s implementation.
I think for most usage, you’re right. There are places where it probably has more overhead than you’d want in a tight loop, and you’d be better off with the “bad” imperative version. E.g. “If a tree falls in the woods, does it make a sound?
If a pure function mutates some local data in order to produce an immutable return value, is that ok?”
I’m coming from a perspective where I now work primarily in JS/TS, prefer FP by default and with it were more accessible in the ecosystem, and even prefer `reduce` over a loop nine times out of ten. But there’s still a bail point where performance is key or “this feels incredibly awkward in this environment”.
Oh yeah, for sure there could be performance implications to lazy sequences, but ideally the compiler or interpreter could figure out some nice optimizations.
Comments
My first thought was much like your second point! If we have lazy operations on collections, we’re 90% of the way to `seq` & similar lazy structures.
Edit: in fact, probably 99%. You just need to define the data structures as an initial operation that materializes values for subsequent operations on demand.
Yeah, years ago I got deep into this stuff and managed to implement a lot of it for fun, thinking I was doing something original, before discovering it’s not original (in my case, discovering Seq in OCaml). I think treating everything as lazy and potential infinite makes the implementation of operations much simpler than this article’s implementation.
I think for most usage, you’re right. There are places where it probably has more overhead than you’d want in a tight loop, and you’d be better off with the “bad” imperative version. E.g. “If a tree falls in the woods, does it make a sound? If a pure function mutates some local data in order to produce an immutable return value, is that ok?”
I’m coming from a perspective where I now work primarily in JS/TS, prefer FP by default and with it were more accessible in the ecosystem, and even prefer `reduce` over a loop nine times out of ten. But there’s still a bail point where performance is key or “this feels incredibly awkward in this environment”.
Oh yeah, for sure there could be performance implications to lazy sequences, but ideally the compiler or interpreter could figure out some nice optimizations.