TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

Clojure Don’ts: Lazy Effects (2015)

108 pointsby lshabout 7 years ago

8 comments

taneqabout 7 years ago
This isn&#x27;t just a Clojure &quot;Don&#x27;t&quot;. It&#x27;s a general programming &quot;don&#x27;t&quot;.<p>In my old team we had a semi-serious production bug result from this (it didn&#x27;t actually kill anyone but stopped the system from being used) because we had an expression with a side effect inside a debug logging statement. The code worked perfectly in a debug build, but in release the DEBUG_PRINTF() equivalent was removed by the C++ preprocessor (so logically equivalent to &quot;!debug &amp;&amp; &quot; in front of every line) and a crucial value didn&#x27;t get updated. It took some tense minutes debugging it on site in front of the client before we figured it out... lesson learned!
评论 #16509601 未加载
djtangoabout 7 years ago
This is a sound article - Clojure&#x27;s laziness is often a source of common gotchas for new users of the language.<p>It&#x27;s often not clear what is lazy and what isn&#x27;t - concat is lazy for instance. It isn&#x27;t externally obvious which of the very common operations are lazy, filter being lazy has bitten me in CLJS a few times too.<p>Adding to the source of the confusion is that the REPL will often realize your side-effects which then won&#x27;t get evaluated in your runtime environment.<p>One of the errors I used to make earlier on was:<p><pre><code> (map insert-into-db table-rows)</code></pre>
评论 #16511996 未加载
noelwelshabout 7 years ago
This is part of the reason for monads: they specify the order of operation, which is necessary in a lazy language like Haskell. The `bind` or `flatMap` operation in a monad specifies &quot;what happens next&quot;. Once you have defined order of operations you can start to reason about effects.
评论 #16513337 未加载
setzer22about 7 years ago
Something that is specially dangerous is mixing laziness and dynamic vars. If you bind a dynamic var to then return a lazy seq, and the dynamic var is used to generate the seq&#x27;s elements (e.g. `binding` over `map`, and use the bound var inside the map&#x27;s `fn`), you may get different results depending on when the seq is evaluated (which is not determined)<p>This made me waste a whole afternoon once. I was even ready to submit a compiler bug!
nathellabout 7 years ago
&gt; In my opinion, the presence of doall, dorun, or even “unchunk” is almost always a sign that something never should have been a lazy sequence in the first place.<p>I’d say it’s a good rule of thumb, but it’s sometimes justified. For example, `line-seq` returns a lazy seq of lines read from a given Reader; the appeal being you can process them one by one, without keeping them in memory all at once. But if you just want them all, you wrap the `line-seq` in a `doall` in a `with-open`.<p>My scraping library, Skyscraper [1], has a similar justification for laziness around side-effects: scraping a site returns a lazy sequence of elements, each corresponding to one page. It&#x27;s terrifically useful to have that sequence be lazy, and there&#x27;s unchunking code on Skyscraper to enforce full laziness. Incidentally, I&#x27;m rewriting it to be based on core.async, but it has a less functional feel to it.<p>[1]: <a href="https:&#x2F;&#x2F;github.com&#x2F;nathell&#x2F;skyscraper" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;nathell&#x2F;skyscraper</a>
zdklabout 7 years ago
Does mapv not do exactly what the author needs? Ie an unlazy map? <a href="https:&#x2F;&#x2F;clojuredocs.org&#x2F;clojure.core&#x2F;mapv" rel="nofollow">https:&#x2F;&#x2F;clojuredocs.org&#x2F;clojure.core&#x2F;mapv</a>
评论 #16510535 未加载
dustingetzabout 7 years ago
This problem is magnified in ClojureScript doing React.js rendering. React.js renders breadth-first in stratas (compared to a call stack which is depth first). Everyone gets bitten by it once.
grzmabout 7 years ago
(2015)
评论 #16509491 未加载
评论 #16510270 未加载