Clojure

Warning when a record field with the same name as a function exists for it

Details

  • Type: Enhancement Enhancement
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: Release 1.4, Release 1.5
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    Linux, clojure jar or leiningen repl

Description

Hi,

I had the following problem which took me much longer than it should have. I accidentally had a record's field with the same name as one of the functions from a protocol. When I tried to call the function from within the record I got totally weird behavior and didn't find it, until I removed every piece of code when I found the name conflict.

I wish clojure would warn me in such a case. (Disregarding any naming conventions that could have saved me.)

Following a small example to reproduce the problem:

(defprotocol HasPets
  (dogs [this])
  (cats [this])
  (octopus [this])
  (cute-ones [this]))

; Here the field "dog" is added with the same name as the protocol
(defrecord Petshop [dogs] 
  HasPets
  (dogs [this]
    [:pluto :bethoven])
  (cats [this]
    [:tom])
  (octopus [this]
    [:henry])
  (cute-ones [this]
    ; Here it was intended to call the function "dogs", instead the
    ; field is used.
    (concat (dogs this) (cats this))))

(def dogs-in-stock nil)

(let [petshop (->Petshop dogs-in-stock)]
  (println "Dogs for sale:" (dogs petshop))
  (println "All cute animals: " (cute-ones petshop)))

Results in:

clojure core.clj
Dogs for sale: [:pluto :bethoven]
Exception in thread "main" java.lang.NullPointerException
        at user.Petshop.cute_ones(core.clj:20)
        at user$eval84.invoke(core.clj:26)
        at clojure.lang.Compiler.eval(Compiler.java:6514)
        at clojure.lang.Compiler.load(Compiler.java:6955)
        at clojure.lang.Compiler.loadFile(Compiler.java:6915)
        at clojure.main$load_script.invoke(main.clj:283)
        at clojure.main$script_opt.invoke(main.clj:343)
        at clojure.main$main.doInvoke(main.clj:427)
        at clojure.lang.RestFn.invoke(RestFn.java:408)
        at clojure.lang.Var.invoke(Var.java:415)
        at clojure.lang.AFn.applyToHelper(AFn.java:161)
        at clojure.lang.Var.applyTo(Var.java:532)
        at clojure.main.main(main.java:37)

Expected warning:

Warning: the protocol function "dog" from "HasPets" conflicts with the equally named record field of "Petshop"

Without dog as a record's field:

clojure core.clj
Dogs for sale: [:pluto :bethoven]
All cute animals:  (:pluto :bethoven :tom)

Thanks for your help.

Ben.

Activity

People

Vote (0)
Watch (2)

Dates

  • Created:
    Updated:
    Resolved: