core.async

Taking from channels in anonymous functions inside go-loops does not work

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Environment:
    latest core.async release, latest core.async built from source

Description

This seems to be related/comparable to the issue posted on this mailing-list thread:
https://groups.google.com/forum/#!topic/clojure/vtvk7warLE4

Minimal testcases to reproduce:

(def ch (chan))

(go-loop []
(>! ch "test"))

(go-loop []
(println (<! ch))) ;;prints "test"

(future (println (<!! ch))) ;;prints "test"

(future (println (#(<!! ch)))) ;;prints "test"

(go-loop []
(println (#(<! ch)))) ;;CompilerExpection java.lang.IllegalArgumentException:
;; No method in multimethod '-item-to-ssa' for dispatch
;; value :fn

Activity

Hide
Joel Knighton added a comment -

It appears the go-loop isn't even necessary -
(go (println (#(<! ch)))) reproduces the issue.

Show
Joel Knighton added a comment - It appears the go-loop isn't even necessary - (go (println (#(<! ch)))) reproduces the issue.
Hide
Kevin Downey added a comment -

I think this is expected behaviour, the go transformation macro doesn't attempt to descending in to called functions to transform their bodies, since their bodies are not transformed the <! and >! operators, which do not work in untransformed code, do not work.

the following which explicitly transforms the body of the inner function using the go macro should work:

(go (println (#(go (<! ch)))))

it will print out a channel though, because the result of (go ...) is a channel that will contain the result of ...

Show
Kevin Downey added a comment - I think this is expected behaviour, the go transformation macro doesn't attempt to descending in to called functions to transform their bodies, since their bodies are not transformed the <! and >! operators, which do not work in untransformed code, do not work. the following which explicitly transforms the body of the inner function using the go macro should work:
(go (println (#(go (<! ch)))))
it will print out a channel though, because the result of (go ...) is a channel that will contain the result of ...
Hide
Joel Knighton added a comment -

Okay - thanks for the feedback. This doesn't cause an issue for me, and your explanation makes sense.

Show
Joel Knighton added a comment - Okay - thanks for the feedback. This doesn't cause an issue for me, and your explanation makes sense.
Hide
Alex Miller added a comment -

Agreed that go macro does not descend into function creation (fn or #() forms). The error could be better in this case but that's logged in a separate ticket.

Show
Alex Miller added a comment - Agreed that go macro does not descend into function creation (fn or #() forms). The error could be better in this case but that's logged in a separate ticket.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: