{"action":"opened","issue":{"url":"https://api.github.com/repos/lfex/los/issues/7","labels_url":"https://api.github.com/repos/lfex/los/issues/7/labels{/name}","comments_url":"https://api.github.com/repos/lfex/los/issues/7/comments","events_url":"https://api.github.com/repos/lfex/los/issues/7/events","html_url":"https://github.com/lfex/los/issues/7","id":94514125,"number":7,"title":"Add implementation for Clojure-like multi-methods","user":{"login":"oubiwann","id":894251,"avatar_url":"https://avatars.githubusercontent.com/u/894251?v=3","gravatar_id":"","url":"https://api.github.com/users/oubiwann","html_url":"https://github.com/oubiwann","followers_url":"https://api.github.com/users/oubiwann/followers","following_url":"https://api.github.com/users/oubiwann/following{/other_user}","gists_url":"https://api.github.com/users/oubiwann/gists{/gist_id}","starred_url":"https://api.github.com/users/oubiwann/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/oubiwann/subscriptions","organizations_url":"https://api.github.com/users/oubiwann/orgs","repos_url":"https://api.github.com/users/oubiwann/repos","events_url":"https://api.github.com/users/oubiwann/events{/privacy}","received_events_url":"https://api.github.com/users/oubiwann/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-07-11T22:54:32Z","updated_at":"2015-07-11T22:54:32Z","closed_at":null,"body":"Usage should be something like this:\r\n\r\n```cl\r\n> (include-lib \"los/include/multi-methods.lfe\")\r\n> (defmulti area 'type)\r\n> (defmethod area 'rectangle\r\n       ((`(#(length ,l) #(width ,w)))\r\n         (* l w)))\r\n> (area '(#(type triangle) #(base 2) #(height 4)))\r\n  4.0\r\n```\r\n\r\nA non-macro version of this could be done in the following manner:\r\n\r\n```cl\r\n(defmodule polymorph\r\n  (export all))\r\n\r\n(defun area\r\n  ((`(,type . ,rest))\r\n   (dispatch 'area type rest)))\r\n\r\n(defun dispatch\r\n  ((fname `#(type ,type) args)\r\n   (call (MODULE) (list_to_atom (++ (atom_to_list fname)\r\n                                    \"-\"\r\n                                    (atom_to_list type))) args)))\r\n\r\n(defun area-triangle\r\n  ((`(#(base ,b) #(height ,h)))\r\n   (* b h (/ 1 2))))\r\n\r\n(defun area-rectangle\r\n  ((`(#(length ,l) #(width ,w)))\r\n   (* l w)))\r\n```\r\n\r\nThese could then be used in the following manner:\r\n\r\n```cl\r\n(c \"examples/no-macros/polymorph.lfe\")\r\n#(module polymorph)\r\n(slurp \"examples/no-macros/polymorph.lfe\")\r\n#(module polymorph)\r\n> (area '(#(type triangle) #(base 2) #(height 4)))\r\n4.0\r\n> (area '(#(type rectangle) #(length 2) #(width 4)))\r\n8\r\n```\r\n\r\nAdditional implementations could be added with ease:\r\n\r\n```cl\r\n(defun area-square\r\n  ((`(#(side ,s)))\r\n   (* s s)))\r\n\r\n(defun area-circle\r\n  ((`(#(radius ,r)))\r\n   (* (math:pi) r r)))\r\n```\r\n\r\nThen use them:\r\n\r\n```cl\r\n> (area '(#(type square) #(side 2)))\r\n  4\r\n> (area '(#(type circle) #(radius 2)))\r\n  12.566370614359172\r\n\r\n```"}}