Welcome! Please see the About page for a little more info on how this works.

0 votes
in Clojure by

`
user> (for [y [2 3 4]

        :let [x 1]]
    [x y])

([1 2] [1 3] [1 4])
user> (for [:let [x 1]

        y [2 3 4]]
    [x y])

IllegalStateException Can't pop empty vector clojure.lang.PersistentVector.pop (PersistentVector.java:380)
`

Cause:

Solution:

Patch:
Screened by:

6 Answers

0 votes
by

Comment made by: jafingerhut

Related (perhaps identical?) ticket CLJ-207 was declined.

0 votes
by

Comment made by: jaycfields

It does look like a duplicate. I find it surprising that this doesn't work, but it does work for doseq:

main=> (doseq [:let [x 1] y [2 3 4]] (println x y)) 1 2 1 3 1 4 nil

I think you'll keep getting this bug report as long as that inconsistency exists.

0 votes
by

Comment made by: jaycfields

for completeness, I think it's worth mentioning that I can't simply change the ordering (like Alex's example above), due to the cost of the value I'm calculating. I only want it to occur once, and I have to use a separate 'let (as Rich recommended)

0 votes
by

Comment made by: gfredericks

Brandon Bloom pointed out that one difference between {{for}} and {{doseq}} is that {{for}} is lazy, and so for an initial {{:let}} it's not clear whether it should be evaluated immediately or after the first item is requested. {{doseq}} doesn't have that ambiguity.

0 votes
by

Comment made by: jaycfields

@Gary, I think that's a good question, but either choice would be better than the current inconsistency. If you made it lazy, I can't really think of a downside. Even if it wasn't lazy, that would match the current performance characteristics of code that's already wrapping the for in a let.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJ-1316 (reported by jaycfields)
...