3

Emacs provides support for polymorphism, supporting "generic functions", like in CLOS.
According to Emacs manual:

A generic function specifies an abstract operation, by defining its name and list of arguments, but (usually) no implementation. The actual implementation for several specific classes of arguments is provided by "methods", which should be defined separately [...] by “specializing” the arguments defined by the generic function.

Unfortunately the manual does not give practical examples of a methods implementation once a generic function is defined. Can you give such an example, implementing the standard OO paradigms through cl-defgeneric/cl-defmethod?

antonio
  • 1,762
  • 12
  • 24
  • 2
    The elisp manual has a decent amount to say about them. `C-h i g (elisp) Generic Functions`. Always check the manual. – phils Sep 28 '16 at 22:56
  • 2
    You could look at Common Lisp docs (such as the hyperspec). – Qudit Sep 28 '16 at 23:24
  • 1
    If you do not find the doc to be as helpful as you think it should be please consider reporting that as a doc bug/suggestion: `M-x report-emacs-bug`. – Drew Sep 29 '16 at 00:03
  • 1
    In general, I think the doc for CL stuff in Emacs is pretty poor. Typically, you need to consult the Common Lisp doc, and then sometimes try to figure out how the Emacs-Lisp implementation might differ. – Drew Sep 29 '16 at 00:04
  • Try looking in the `cl` manual, as well. In principle, that is where I would *expect* `cl` stuff to be documented. But that manual is pretty skimpy... – Drew Sep 29 '16 at 00:05
  • @Drew: Not even mentioned in [emacs/manual/cl.html#Function-Index](https://www.gnu.org/software/emacs/manual/cl.html#Function-Index). I will consider the doc suggestion – antonio Sep 29 '16 at 09:18
  • @phils: I did not find examples [here](https://www.gnu.org/software/emacs/manual/elisp.html#Generic-Functions), only a short abstract comparison among OO languages. – antonio Sep 29 '16 at 14:03
  • 1
    No examples (my comment wasn't intended as an *answer*); but you said you were "unable to find documentation" apart from the docstrings, and that manual page contains rather more information than the docstrings. Reminding you that the manual is a thing that exists seemed fairly useful. – phils Sep 29 '16 at 20:36
  • Can you edit the post to make the question more discrete and less open-ended? The format of this site does not really lend itself to open-ended tutorials very well. – Dan Sep 29 '16 at 21:47
  • @Dan: I tried to narrow and focus the scope by linking the question to the manual reference to Generic Functions (strongly advocated by phils too). – antonio Sep 30 '16 at 10:16

1 Answers1

4

An attempt...

(require 'cl-generic)

;; Checking accounts can have a negative balance
;; Savings accounts can't
(cl-defstruct checking-account balance)
(cl-defstruct savings-account balance)

;; A generic `withdraw' method
(cl-defgeneric withdraw (account amount)    
  (:documentation "Withdraw AMOUNT from ACCOUNT balance.
Give an error for savings accounts where balance < AMOUNT"))

;; Implementation of `withdraw' for checking accounts
(cl-defmethod withdraw ((account checking-account) amount)
  (cl-decf (checking-account-balance account) amount))

;; Implementation of `withdraw' for savings accounts
(cl-defmethod withdraw ((account savings-account) amount)
  (when (< (savings-account-balance account) amount)
    (error "Account overdrawn."))
  (cl-decf (savings-account-balance account) amount))

;; Account instantiations, i.e. creation of account objects  
(setq x (make-checking-account :balance 50))
(setq y (make-savings-account :balance 50))

;; Withdraw amounts from accounts 
(withdraw x 60) ; => - 10
(withdraw y 60) ; => (error "Account overdrawn.")

See gigamonkeys.com for Common Lisp.

antonio
  • 1,762
  • 12
  • 24