:PROPERTIES: :ID: 4a838201-9b9c-44e6-aec8-017663363627 :END: #+TITLE: Why no defmethod? #+Author: Yann Esposito #+Date: [2020-06-12] tags :: [[id:debfbdb6-03a6-478e-8316-bce0119c0dd7][clojure]] [[id:155859f9-3f3c-4cea-bce4-70f24fca05fa][functional programming]] source :: The main reason is that it is harder to reason about in our environment. ~defmethod~ is exactly like a ~cond~ or ~case~ but potentially distributed between multiple files. So: #+begin_src clojure (ns foo.bar (:require [baz])) ...300 lines of code... (foo :x) => "NICE X" #+end_src And after a few weeks someone add a require: #+begin_src clojure (ns foo.bar (:require [[baz] [pownd.core]])) ...300 lines of code... (foo :x) => "PWND!!!!" #+end_src So ~defmethod~ is harder to reason about because the logic is distributed. And as a developer it is harder to reason statically about the code. Still, this could totally be fine for clojure libraries doing "magic" stuff. There is a big difference between the code aimed for a production environment /application/ written by a team and a codebase for a /library/. So "never use defmethod" is a way of saying that it is only allowed if you really tried your best not to use it but this does not make sense, and you can show why to the rest of the team.