1 / 12

Object-Oriented Programming

Object-Oriented Programming. In Lisp. Lisp vs. Scheme. Lisp has much more built-in functions and special forms, the Scheme language definition takes 45 pages while Common Lisp takes 1029 pages) Apart from lexical variables Lisp also has special variables

patsy
Download Presentation

Object-Oriented Programming

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Object-Oriented Programming In Lisp

  2. Lisp vs. Scheme • Lisp has much more built-in functions and special forms, the Scheme language definition takes 45 pages while Common Lisp takes 1029 pages) • Apart from lexical variables Lisp also has special variables • Scheme uses one name space for functions, variables, etc., Lisp doesn’t. • Scheme evaluates the function part of a function call in exactly the same way as arguments, Lisp doesn’t. • Lisp functions can have rest, optional and keyword parameters. Scheme functions only can have the equivalent of a rest parameter.

  3. (defstruct account (name "") (balance 0.00) (interest-rate .06)) (defun account-withdraw (account amt) "Make a withdrawal from this account." (if (<= amt (account-balance account)) (decf (account-balance account) amt) 'insufficient-funds)) (defun account-deposit (account amt) "Make a deposit to this account." (incf (account-balance account) amt)) (defun account-interest (account) "Accumulate interest in this account." (incf (account-balance account) (* (account-interest-rate account) (account-balance account))))

  4. (defun new-account (name &optional (balance 0.00) (interest-rate .06)) "Create a new account that knows the following messages:" #'(lambda (message) (case message (withdraw #'(lambda (amt) (if (<= amt balance) (decf balance amt) 'insufficient-funds))) (deposit #'(lambda (amt) (incf balance amt))) (balance #'(lambda () balance)) (name #'(lambda () name)) (interest #'(lambda () (incf balance (* interest-rate balance)))))))

  5. > (setf acct (new-account "J. Random Customer" 1000.00)) > (send acct 'withdraw 500.00) => 500.0 > (send acct 'deposit 123.45) => 623.45 > (send acct 'name) => "J. Random Customer" > (send acct 'balance) => 623.45

  6. (defun get-method (object message) "Return the method that implements message for this object." (funcall object message)) (defun send (object message &rest args) "Get the function to implement the message, and apply the function to the args." (apply (get-method object message) args)) (defun withdraw (object &rest args) "Define withdraw as a generic function on objects." (apply (get-method object 'withdraw) args))

  7. (defmacro define-class (class inst-vars class-vars &body methods) "Define a class for object-oriented programming." ;;Define constructor and generic functions for methods `(let ,class-vars (mapcar #'ensure-generic-fn ',(mapcar #'first methods)) (defun ,class ,inst-vars #'(lambda (message) (case message ,@(mapcar #'make-clause methods)))))) (defun make-clause (clause) "Translate a message from define-class into a case clause." `(,(first clause) #'(lambda ,(second clause) .,(rest2 clause)))) (defun ensure-generic-fn (message) "Define an object-oriented dispatch function for a message, unless it has already been defined as one." (unless (generic-fn-p message) (let ((fn #'(lambda (object &rest args) (apply (get-method object message) args)))) (setf (symbol-function message) fn (get message 'generic-fn) fn)))) (defun generic-fn-p (fn-name) "Is this a generic function?" (and (fboundp fn-name) (eq (get fn-name 'generic-fn) (symbol-function fn-name))))

  8. (define-class account (name &optional (balance 0.00)) ((interest-rate .06)) (withdraw (amt) (if (<= amt balance) (decf balance amt) 'insufficient-funds)) (deposit (amt) (incf balance amt)) (balance () balance) (name () name) (interest () (incf balance (* interest-rate balance)))) (setf acct2 (account "A. User" 2000.00)) > (deposit acct2 42.00) => 2042.0 > (interest acct2) => 2164.52 > (balance acct2) => 2164.52 > (balance acct) => 623.45

  9. (define-class password-account (password acct) () (change-password (pass new-pass) (if (equal pass password) (setf password new-pass) 'wrong-password)) (otherwise (pass &rest args) (if (equal pass password) (apply message acct args) 'wrong-password))) (setf acct3 (password-account "secret" acct2)) > (balance acct3 "secret") => 2164.52 > (withdraw acct3 "guess" 2000.00) => WRONG-PASSWORD > (withdraw acct3 "secret" 2000.00) => 164.52

  10. (defclass account () ((name :initarg :name :reader name) (balance :initarg :balance :initform 0.00 :accessor balance) (interest-rate :allocation :class :initform .06 :reader interest-rate))) (defmethod withdraw ((acct account) amt) (if (< amt (balance acct)) (decf (balance acct) amt) 'insufficient-funds)) (setf a1 (make-instance 'account :balance 5000.00 :name "Fred")) > (name a1) => "Fred" > (balance a1) => 5000.0 > (interest-rate a1) => 0.06

  11. (defclass limited-account (account) ((limit :initarg :limit :reader limit)))) (defmethod withdraw ((acct limited-account) amt) (if (> amt (limit acct)) 'over-limit (call-next-method)))) (setf a2 (make-instance 'limited-account :name "A. Thrifty Spender" :balance 500.00 :limit 100.00)) > (name a2) => "A. Thrifty Spender" > (withdraw a2 200.00) => OVER-LIMIT > (withdraw a2 20.00) => 480.0

  12. (def

More Related