ClojureScript

defrecord recur method head target object

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Completed
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
    None
  • Patch:
    Code and Test

Description

The docstring for defrecord indicates "recur calls to the method head should *not* pass the target object", but in ClojureScript an argument in this position is evidently required, resulting in a discrepancy relative to Clojure.

Example code:

(defprotocol ISearch
  (search [this coll]))
(defrecord Search [needle]
  ISearch
  (search [this coll]
   (when (seq coll)
    (if (= needle (first coll))
     needle
     (recur (rest coll))))))

And its use:

(-> (->Search 1) (search [:a 1 "b"]))
(-> (->Search :z) (search [:a 1 "b"]))

yield 1 and nil respectively in Clojure.

If you attempt to compile the Search defrecord in ClojureScript, you will get "recur argument count mismatch at line 7".

It appears that this can be fixed in the example code by simply adding a dummy value for the first argument to recur (it can even be nil and doesn't have to be this).

This ticket requests that this be fixed to match Clojure. Since this would be a breaking change, perhaps legacy code could be accepted while simultaneously emitting a warning diagnostic.

Activity

Hide
David Nolen added a comment -

Yes warning diagnostic desirable in this case.

Show
David Nolen added a comment - Yes warning diagnostic desirable in this case.
Hide
Mike Fikes added a comment -

The attached patch should allow any code implementing protocol methods, via defrecord, extend-type, reify, etc. that passes a target object to be accepted with a warning diagnostic. It also accepts code that omits the target object (i.e., the way the Clojure compiler does). This should eliminate this difference from Clojure without being a breaking change for existing ClojureScript code that recurs to protocol method heads.

An example warning (taken from the tests) looks like this:

WARNING: Ignoring target object "this" passed in recur to protocol method head at line 24 src/test/cljs/cljs/recur_test.cljs

where the target object indicated in quotes is actually the form for the first expression being passed to recur.

Show
Mike Fikes added a comment - The attached patch should allow any code implementing protocol methods, via defrecord, extend-type, reify, etc. that passes a target object to be accepted with a warning diagnostic. It also accepts code that omits the target object (i.e., the way the Clojure compiler does). This should eliminate this difference from Clojure without being a breaking change for existing ClojureScript code that recurs to protocol method heads. An example warning (taken from the tests) looks like this:
WARNING: Ignoring target object "this" passed in recur to protocol method head at line 24 src/test/cljs/cljs/recur_test.cljs
where the target object indicated in quotes is actually the form for the first expression being passed to recur.

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved: