Clojure

for doesn't support :let binding as its first seq-expr

Details

  • Type: Enhancement Enhancement
  • Status: Open Open
  • Priority: Minor Minor
  • Resolution: Unresolved
  • Affects Version/s: Release 1.5
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    jvm clojure
  • Approval:
    Triaged

Description

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:

Activity

Hide
Andy Fingerhut added a comment -

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

Show
Andy Fingerhut added a comment - Related (perhaps identical?) ticket CLJ-207 was declined.
Hide
Jay Fields added a comment -

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.

Show
Jay Fields added a comment - 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.
Hide
Jay Fields added a comment -

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)

Show
Jay Fields added a comment - 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)
Hide
Gary Fredericks added a comment -

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.

Show
Gary Fredericks added a comment - 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.
Hide
Jay Fields added a comment -

@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.

Show
Jay Fields added a comment - @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.

People

Vote (0)
Watch (3)

Dates

  • Created:
    Updated: