 ;; Internal rep. of a trait is a fn from args to [binding-seq impl-map]
 ;; TODO: forn ow, args may be multiple evaluated?
 (defmacro deftrait [name args state-bindings child-traits & protocols-and-methods]
-  `(defn ~name ~args
-     (apply merge-traits
-      [(concat (interleave '~args ~args) '~state-bindings)
-       '~(parse-protocols-and-methods protocols-and-methods)]
-      ~(parse-trait-form child-traits))))
+  (let [[method-fn-defs protocol-method-bodies]
+        (parse-protocols-and-methods (concat args (take-nth 2 state-bindings)) protocols-and-methods)]
+;    (println method-fn-defs "\n" protocol-method-bodies)
+    `(do (defn ~name ~args
+           (apply merge-traits
+                  [(concat (interleave '~args ~args) '~state-bindings)
+                   '~protocol-method-bodies]
+                  ~(parse-trait-form child-traits)))
+         ~@method-fn-defs)))
 
 (defn- render-trait-methods-inline [trait-map]
   (apply concat (map (partial apply cons) trait-map)))

      (cons [proto methods]
            (parse-protocols-and-method-pairs more)))))

(defn- parse-protocols-and-methods [args]
  (let [pairs (parse-protocols-and-method-pairs args)]
    (assert (apply distinct? (cons nil (map first pairs))))
    (into {} pairs)))

(defn merge-traits [& traits]
  (let [bindings  (vec (apply concat (map first traits)))]
    (assert (apply distinct? (cons nil (take-nth 2 bindings))))
    [bindings
     (reduce util/merge-disjoint {} (map second traits))]))

(defn parse-trait-form [traits]
  (vec (map #(if (list? %)


 (defprotocol P0)

 (deftrait +foo+ [x] [y (atom x)] [] P2 (p21 [foo z] (+ z @y)) (p22 [foo] (swap! y inc)) P0)

                                        ; (deftrait +bar+ [w] [z (inc w)] [(+foo+ (* w 2))] P1 (p11 [bar y] (- y w)))
 )

