18 ms·
Quite different. To achieve the effects of "Incremental" you would need lazy evaluation coupled with a caching layer, so that successive calls to pure functions
by hebdo 11y ago
Quite different. To achieve the effects of "Incremental" you would need lazy evaluation coupled with a caching layer, so that successive calls to pure functions with same arguments are not re-computed. This optimization technique is in a sense similar to Common Subexpression Elimination.
- loosescrews 11y agoDoesn't Haskell already do this? What is the advantage of OCaml + Incremental over Haskell?
- jmct 11y agoHaskell does not do this. Haskell is lazy (computed results are shared), but Haskell does not memoize by default. To illustrate: func y = let z = y + y in (add 1 z) * (add 1 z) in `func` the result of computing `y + y` is shared because it has been given a name: `z`. However, the result of `add 1 z` is _not_ given a name and therefore has to be computed twice. Because Haskell is pure, they will result return the same result, however the result is not saved. This avoids needing to save the results of _all_ function calls.
- art-w 11y agoThat's a bad example, since GHC will perform common expressions elimination, which effectively give the same name to the two `add 1 z` (unless you specifically ask it not to, with `-O0`.) Furthermore, Incremental isn't memoizing every function calls. It just keeps the intermediate results of the latest computation in memory, so that when the inputs change, it can determine exactly which subresults need a recomputation, and which can be reused. It's like Excel, but with dynamic dependencies. (But yes, Haskell definitively does not do this. You could say that Haskell is about doing the least amount of work to compute something fresh, while Incremental is about working the least to recompute something we (almost) already computed just before.)
- tome 11y agoA better example might have been func (f (add 1 z), f (add z 1)) Since f is not memoized it will be evaluated once for each component of the tuple.
- mercurial 11y agoBut this is possible to do trivially using a hash keyed by the input variables. It seems to me that SAC offers an interest only in the case where: - the input variables of the DAG are updated at a different rate - and the result of complex subgraphs depend on only a few of these variables (and thus avoiding to recompute their result is a win) I don't know if it's enough to get excited about.