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?

10
  • 2
    The elisp manual has a decent amount to say about them. C-h i g (elisp) Generic Functions. Always check the manual. Commented Sep 28, 2016 at 22:56
  • 2
    You could look at Common Lisp docs (such as the hyperspec). Commented Sep 28, 2016 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. Commented Sep 29, 2016 at 0: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. Commented Sep 29, 2016 at 0:04
  • 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. Commented Sep 29, 2016 at 20:36

1 Answer 1

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.

1
  • You might want to amend or extend this example to improve readability or effectiveness. Commented Sep 29, 2016 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.