uncomplicate / neanderthal

Fast Clojure Matrix Library
http://neanderthal.uncomplicate.org
Eclipse Public License 1.0
1.06k stars 56 forks source link

Provide fallback reduction as an Object extension instead of IFn. #74

Closed katox closed 4 years ago

katox commented 4 years ago

The implementation for the "class" (the function in question) given one of fluokitten's protocol is chosen: 1) if it directly implements the protocol => (fn ...) doesn't, 2) if one of its direct super-classes implements the protocol => in order fn itself, AFunction and AFn don't, 3) if Clojure can find one implementation by the following algorithm: a) get all clojure.core/supers of "class" as a set, b) iterate over the set (i.e. the order is unknown) to keep only implementors of the protocol), c) reduces the sequence of implementors left-to-right (the order is stable now but it is still unknown) and it either prefers the current / the first result or the second if the latter is more specific as tested by Class/isAssignableFrom. The IFn or IFn$... interfaces are in no such relation so it is always false and the reduction prefers always the first implementation found, 4) fallback to Object if nothing was found so far.

The important outcome is that it doesn't always work for primitive functions. It can pick either the specific IFn$... implementation (which is often the case) or the generic IFn implementation. The IFn doesn't have to fail it can work and even return the correct answer but it'll use a suboptimal implementation.

However we can take advantage of #4 above - that is let Object be the fallback implementation instead of IFn. The primitive version will always have a priority if it exists.

Signed-off-by: Kamil Toman kamil.toman@leafclick.com