spade icon indicating copy to clipboard operation
spade copied to clipboard

Binding Forms Incompatible with defclass

Open superstructor opened this issue 3 years ago • 1 comments

Binding forms such as let are incompatible with defclass as such forms only return the value of the last form.

E.g.

(defclass example
   []
   (let [a true]
      {:background (if a :blue :grey)}
      [:h4
        {:color (if a :black :white)}]
      [:&:hover
        {:border [[(px 1) :solid :grey]]}]))

;; will only output
;; [:&:hover
;;        {:border [[(px 1) :solid :grey]]
;; as the first 2 forms are ignored due to the let

The root cause of this is defclass macro return semantics being different to defn / do in that it returns all top level forms, instead of the value of the last form. Its understandable once analyzed that the above let example does what it does in that context, but it is initially surprising behavior for a Clojure(Script) programmer. It certainly caught me out because I was trying to bind a common value with let and it took me awhile to realise why all the styles were not coming through.

I'm not sure how to fix this. Maybe a mitigation such as allowing a single form return style for defclass could work ? E.g.

(defclass example
  []
  [(let ... ])

superstructor avatar May 10 '21 00:05 superstructor