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

0 votes
in ClojureScript by

When extending a protocol for a record, a recursive method can never terminate in some cases.

`
(defrecord R [a])

(defprotocol P
(f [x]))

(extend-protocol P
R
(f [x]

(if x
  (recur nil)
  x))

default
(f [x]

(if x
  (recur nil)
  x)))

(prn (f 1)) ; #1
(prn (f (R. 1))) ; #2
`

{{prn}} call #1 prints {{nil}} as expected, but {{prn}} call #2 never terminates.

It looks like the compiler creates a variable assigned to {{this}} within the {{while}} loop such that the test of "{{x}}" is always really testing {{this}} when it should be testing the value of {{x}} passed in by the call to {{recur}}.

Note, I'm testing ClojureScript 1.8.51. The "Affects Version/s" field above only gives 1.7.228 as the most recent version.

3 Answers

0 votes
by

Comment made by: bstiles

Actually, "always really testing 'this' when it should be testing the value of x passed in by the call to recur" is only true if the type of the value represented by x remains the same. If, as in the example, the type changes, the call should be dispatched to the properly matching method implementation.

This seems to behave as expected in Clojure.

0 votes
by

Comment made by: dnolen

Confirmed with Mike Fikes this is still an issue on master even with the recur enhancements.

0 votes
by
Reference: https://clojure.atlassian.net/browse/CLJS-1644 (reported by alex+import)
...