<< Back to previous view

[ASYNC-16] Faulty rebinding of loop bindings in go macro Created: 01/Aug/13  Updated: 03/Aug/13  Resolved: 03/Aug/13

Status: Closed
Project: core.async
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Defect Priority: Major
Reporter: Ghadi Shayban Assignee: Ghadi Shayban
Resolution: Completed Votes: 0
Labels: None

Patch: Code and Test

 Description   

Below from https://groups.google.com/d/msg/clojure/MJc-69TgjR0/9HZqE7-kM9UJ

There seems to be an issue with the rebinding of loop-bindings using loop/recur in go blocks,
specifically when you are just changing the order of the original bindings in a recur call.

Take this snippet for example:
(require '[clojure.core.async :refer [go timeout]])
(go (loop [a :black, b :white]
(println a b)
(<! (timeout 1000))
(recur b a)))

Instead of repeatedly printing

:black :white
:white :black
:black :white
:white :black
(...)

it actually prints

:black :white
:white :white
:white :white
:white :white
(...)

Note however, that

(require '[clojure.core.async :refer [go timeout]])
(go (loop [a :black, b :white]
(println a b)
(<! (timeout 1000))
(recur (identity b) (identity a))))

works correctly.



 Comments   
Comment by Ghadi Shayban [ 03/Aug/13 1:45 PM ]

Root cause:
Recurring with (recur b a) will emit semantically invalid code.
essentially
(let [b a
a b]

instead of something like:
(let [temp-b b
b a
a b]

Preliminary patch is on branch ASYNC-16.

TODO: add basic test and port the patch to cljs

Comment by Ghadi Shayban [ 03/Aug/13 2:06 PM ]

fixed with tests + cljs port.

Generated at Mon Sep 01 16:08:54 CDT 2014 using JIRA 4.4#649-r158309.