4 ms·
Clojure has the best solution to expression problem I've seen in a real programming language http://clojure.org/multimethods http://clojure.org/multimethods
by ajuc 12y ago
Clojure has the best solution to expression problem I've seen in a real programming language
http://clojure.org/multimethods http://clojure.org/multimethods
(defmulti sound class)
(defmulti eat class)
(defmulti attack class)
(defmethod sound ::cow [c] "Moo!")
(defmethod sound ::dog [c] "Roof!")
(defmethod sound ::cat [c] "Miau!")
(defmethod attack ::dog [c] (bite c))
(defmethod attack ::cat [c] (scratch c))
(defmethod eat ::cow [c] ...)
(defmethod eat ::dog [c] ...)
(defmethod eat ::cat [c] ...)
...
(derive ::mad-cow ::cow)
(defmethod sound ::mad-cow [c] "MooOOOooooOOOOoooo!")
(defmethod attack ::mad-cow [c] (stampede c))
The layout problem remains, and I would like to be able to do sql- or prolog-like queries on code, but IMHO it's IDE and tooling problem more than missing language feature.
Also in clojure you can add arbitrary http://clojure.org/metadata http://clojure.org/metadata to each value, so marking your function as deprecated/in-progress/whatever is easy (but it seems you can't easily add metadata to separate implementations of multimethod right now).
...
(defmulti "Attacks."
{:deprecated "Use eat instead.",
:author "me"}
attack class)
...
Also - to confirm that people want to specify rules in tables - I've been working at 2 different companies where we had code generators with .xlsx files as input and .java as output.
- TeMPOraL 12y agoYup, multimethods are awesome. By the way, they come from CLOS - Common Lisp Object System - so Common Lisp supports them as well. I'm not sure if Clojure supports that, but in CL you can also have :before, :after and :around methods that will be called before, after and instead of an actual method, respectively. This gives you another interesting boost to extensibility. EDIT: RE querying - using Metaobject Protocol (MOP) you can do all sorts of queries you like. For instance, to compute "animals that eat" you could use generic-function-methods on a generic eat to get a list of all method metaobjects (objects associated with methods), from which you can determine for which classes an eat method is defined. CLOS + MOP is quite possibly the most powerful object system ever made.
- lispm 12y agoHow so? You ignore that the expression problem is about using static types. See the original problem statement. In languages like Smalltalk or Lisp, the Expression Problem has easy solutions - but they are not statically typed.
- fnordsensei 12y agoThe point is to not violate the type safety of the language used. There are plenty of dynamic languages that don't offer a solution to the expression problem. With that said, you can add gradual typing to Clojure with Core.Typed and still solve the expression problem using multimethods without violating type safety.
- deleted 12y ago[deleted]