How can I write a defprotocol (and defrecord to implement it) that declares a method with the same name as an existing function, and dispatch dynamically to the protocol/record's method iff I call it with an instance of the protocol/record, but otherwise dispatch to the existing function?
For example, I want to create a geometry helper that supports basic arithmetic (just multiplication in this example, to keep it short):
(defprotocol SizeOps
  (* [this factor] "Multiply each dimension by factor and return a new Size"))
At this point I'm already getting some foreboding pushback from the compiler:
Warning: protocol #'user/SizeOps is overwriting function *
WARNING: * already refers to: #'clojure.core/* in namespace: user, being replaced by: #'user/*
Then the implementation:
(defrecord Size [width height]
  SizeOps
  (* [this factor] (Size. (* width factor) (* height factor))))
That compiles okay, but when I try to use it, the only * it knows is the one in my protocol:
(* (Size. 1 2) 10)
IllegalArgumentException No implementation of method: :* of protocol: #'user/SizeOps found for class: java.lang.Long
I can hack around this by fully specifying the core * function in my implementation:
(defrecord Size [width height]
  SizeOps
  (* [this factor] (Size. (clojure.core/* width factor) (clojure.core/* height factor))))
(* (Size. 1 2) 10)
#user.Size{:width 10, :height 20}
But I get the same IllegalArgumentException if I try to call (* 3 4) later on. I can stomach using the namespaced clojure.core/* in my defrecord implementation, but I want my users to be able to call * on my Size records as well as on Long, Double, etc., as usual.
Similar Q&A:
- 5438379: extending 
Stringwith a*operator that works like Python:(* "!" 3)⇒"!!!", but obscures core's*just as in my example - 6492458: excluding core functions like 
(ns user (:refer-clojure :exclude [*]))avoids the "overwriting" warning, but also avoids having that function around :( - 1535235: same, with a gesture toward using a multimethod but no details
 
I suspect the right solution lies somewhere in lower-level dispatch functionality like defmulti and defmethod or deftype / derive but I'm not super familiar with the nuances of Clojure's runtime polymorphism. And I'm gonna have a whole host of Size, Point, Rectangle, Circle, etc., types that each support some subset of +, -, *, / operations, so I'd love to know if there's a way to tell defprotocol to participate in / build on the polymorphism of any existing functions rather than simply overwrite them.