Skip to content

Instantly share code, notes, and snippets.

@lynaghk
Created January 2, 2012 16:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lynaghk/1551222 to your computer and use it in GitHub Desktop.
Save lynaghk/1551222 to your computer and use it in GitHub Desktop.
ClojureScript multimethod namespace reference problem
;;ClojureScript compiler 329708 (2011.12.14)
;;Based on RangeNum protocol by Tassilo Horn:
;; http://groups.google.com/group/clojure/browse_thread/thread/f3192b351b0ab2b4/ec6c106dfdcf0cf9?lnk=gst&q=ranged#msg_ed6de8b7a5cabf41
(ns c2.main
(:refer-clojure :exclude [+])
(:use-macros [c2.util :only [typeof]]))
(defprotocol RangeNumProtocol
(check [this])
(value [this]))
(defprotocol RangeNumLimits
(upper [this])
(lower [this]))
(deftype RangeNum [v l u]
RangeNumProtocol
(check [this]
(if (or (> v u) (< v l))
(throw (js/Error. "Over/Underflow"))
this))
(value [this] (and (check this) v))
RangeNumLimits
(upper [this] u)
(lower [this] v))
(extend-protocol RangeNumProtocol
number
(check [this] this)
(value [this] this))
(defmulti + #(let [x (first %&)]
(cond
(= "number" (typeof x)) :number
(instance? RangeNum x) :range_num)))
(defmethod + :number
([a] a)
([a b] (clojure.core/+ a (value b)))
([a b & more] (reduce + (+ a b) more)))
(defmethod + :range_num
([a] a)
([a b] (RangeNum. (value (+ (value a) b)) (lower a) (upper a)))
([a b & more] (reduce + (+ a b) more)))
;;Here's the problem: despite + being excluded in the namespace declaration, it still points to clojure.core/+ rather than the multimethod.
(let [x (RangeNum. 500 1 1000)]
(+ x 100) ;;=> [object Object]100
(clojure.core/+ x 100) ;;=> [object Object]100
(c2.main/+ x 100) ;;=> c2.main.RangeNum
)
@lynaghk
Copy link
Author

lynaghk commented Jan 4, 2012

Fixed here:

https://github.com/lynaghk/clojurescript/tree/114-refer-clojure-exclude

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment