Skip to content

Instantly share code, notes, and snippets.

@vbuaraujo
Created October 10, 2017 16:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vbuaraujo/a785e0ea8e646de2bd631dc7cc98ebd2 to your computer and use it in GitHub Desktop.
Save vbuaraujo/a785e0ea8e646de2bd631dc7cc98ebd2 to your computer and use it in GitHub Desktop.
(import (scheme base)
(scheme write))
(define *update-methods* (list '*update-methods*))
(define-record-type <method> (make-method predicate action) method?
(predicate method-predicate)
(action method-action))
(define (make-generic name)
(let ((methods '()))
(lambda args
(if (and (pair? args) (eq? (car args) *update-methods*))
(begin
(set! methods ((cadr args) methods))
methods)
(apply-applicable-method name methods args)))))
(define (apply-applicable-method name methods args)
(cond ((null? methods) (error "No applicable method" name args))
((apply (method-predicate (car methods)) args)
(apply (method-action (car methods)) args))
(else (apply-applicable-method name (cdr methods) args))))
(define (add-method! generic method)
(generic *update-methods*
(lambda (methods)
(cons method methods))))
(define (get-methods generic)
(generic *update-methods*
(lambda (methods)
methods)))
(define show (make-generic 'show))
(add-method! show (make-method
(lambda (x) (number? x))
(lambda (x) (display "I am number ") (display x) (newline))))
(add-method! show (make-method
(lambda (x) (string? x))
(lambda (x) (display "I am the string ") (write x) (newline))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment