4 ms·
I understood Haskell once I internalized the actual purpose of non-strict semantics. Abstractly your program is a tree rooted at main. In a language like C you
by jjaredsimpson 11y ago
I understood Haskell once I internalized the actual purpose of non-strict semantics.
Abstractly your program is a tree rooted at main. In a language like C you concentrate on building trees knowing that you are going to touch every node. So you are trying to design small trees that have good execution semantics as well as being correct in the problem solving domain. You have to address the problem at 2 levels. Because C is strict every function you call will be evaluated before it can return some result.
Haskell is different you can build any tree you like because a node will only be evaluated if its result is required for the current context. You are free to work with models of data like "the integers" or "all possible game states".
Concretely in C if you wanted to find the smallest positive integer that satisfies some property P you would write something like
for (int i=1; ; i++) if (P(i)) return i;
This is a single node in your program tree which modifies a variable until a condition is met.
In contrast in Haskell you might do something like
find P [1..]
I would interpret this as find operating on an infinite lazy tree and discarding the infinite tail list (which is an infinite computation) once the result is found.
Applying this simple example, in Haskell you aren't concern with limiting the shape of your program's tree. You build the correct model for your program regardless of constraints like infinite lists or terminating searches early. You just allow non-strict evaluation to process your input data because you will never have to strictly generate an infinite integer list before scanning it.
At root non-strict semantics is just a reversal of the order of reduction of expressions.
- agumonkey 11y agoAm I misguided to think that strict / lazy has some relation between push / pull effects in other systems (GUI, parsing) ? Beautiful comment btw.
- tome 11y agoThat sounds like a good intuition to me. Strict is like push, because it gives you the result as soon as it's ready. Lazy (or perhaps more precisely non-strict) is like pull because you have to go and ask for the result.
- agumonkey 11y agoYes, and after years of struggling to find which should prevail, I recently heard the term of backpressure (used in reactive GUI IIRC) to be able to reason about things in both direction. Is there a middle ground for evaluation strategies ? Right now one can for strictness (in Haskell) or lazyness (in ml) but I never found a 'theory' about both.
- jessaustin 11y ago...backpressure (used in reactive GUI IIRC)... And unix pipes, and node.js streams... Your intuition about a middle ground is interesting. Perhaps one of javascript's derivative languages could come up with some syntax to make using this more intuitive, because let's face it node.js streams would be easier to use if there were some way of plumbing them together that didn't look like Java from 1999.
- agumonkey 11y agoRight any streams. Also this https://github.com/dominictarr/pull-stream#transparent-backpressure--laziness https://github.com/dominictarr/pull-stream#transparent-backp... article says reducers are related too.
- buttproblem 11y agoI don't know node, but, conceptually, Arrows [1] map to the steam concept very well (as always in Haskell, they are more general). The sugar in Haskell to use them similar to do-notion is really a joy to use. I was exposed to them in the Haskell music library Euterpea in the Haskell School of Music [2]. The signal processing API uses arrows. [1] Generalizing Monads to Arrows. John Hughes. http://www.cse.chalmers.se/~rjmh/Papers/arrows.pdf http://www.cse.chalmers.se/~rjmh/Papers/arrows.pdf [2] http://haskell.cs.yale.edu/?post_type=publication&p=112 http://haskell.cs.yale.edu/?post_type=publication&p=112
- codygman 11y ago> Perhaps one of javascript's derivative languages could come up with some syntax to make using this more intuitive You might want to checkout purescript, which I'm pretty sure uses Monads to make stream interaction intuitive. No time for an example, but I believe there is one somewhere in the Purescript book[0]. 0: https://leanpub.com/purescript/read https://leanpub.com/purescript/read