anchor.diff:      (when (plusp overdraft)
         (incf (balance account) (embezzle *bank* overdraft)))))
   
  -(defreply assess-low-balance-penalty ((account #@bank-account))
  +(defreply assess-low-balance-penalty ((account =bank-account=))
     (with-properties ((bal balance)) account
       (when (< bal *minimum-balance*)
         (decf bal (* bal .01)))))
   
  -(defreply merge-accounts ((acc1 #@bank-account) (acc2 @#bank-account))
  -  (with-manipulators ((balance1 balance)) acc1
  -    (with-manipulators ((balance2 balance)) acc2
  +(defreply merge-accounts ((acc1 =bank-account=) (acc2 =bank-account=))
  +  ;; with-accessors works, of course :)
  +  (with-accessors ((balance1 balance)) acc1
  +    (with-accessors ((balance2 balance)) acc2
         (incf balance1 balance2)
         (setf balance2 0))))
  
positive.code: ;; Things to note:
  ;; * No advanced method combination
  ;; * No need for class allocation (can simply keep data in prototype)
  ;; * No distinction between classes and objects. The #@foo scheme is only for convenience
  ;;   denoting that the object is used as a prototype, stored in a different namespace.
  ;; * No equivalent of :INITFORM. All properties start off 'initialized' with whatever value the
  ;;   nearest parent set. Getting :INITFORM-like behavior requires writing replies for the
  ;;   INITIALIZE-SHEEP message.
  ;; * Message definition is on actual objects, not on classes. #@foo fetches an actual object.
  ;; * The hierarchy list for sheep works identically to CLOS's class precedence list (same sorting)
  (in-package :sheeple-user)
  
  (defvar *max-acc-num* 0)
  (defparameter *minimum-balance* 500)
  
negative.code: ;; convenient way that fits more nicely with Lisp-style development. DEFPROTO should be used
  ;; for prototypes that are meant to be part of the text code, while clone should be used for
  ;; anonymous objects.
  ;; There is no difference between the actual objects that DEFPROTO and SPAWN create,
  ;; DEFPROTO is purely convenience for defining code more concisely and precisely,
  ;; and for interactive development.
  (defproto =bank-account= ()
    ((customer-name "NoName")
     (balance 0)
     (account-number 0 :reader 'account-number)
     (account-type :bronze)))
  
  (defreply init-sheep :after ((account =bank-account=) &key)
    (setf (property-value account 'account-number) (incf *max-acc-num*)))
  
  ;; SHEEPLE-USER> (property-value =bank-account= 'customer-name) => "NoName"
  ;; SHEEPLE-USER> (account-number =bank-account=) => 0
  
  (defproto =checking-account= (=bank-account=) ())
  
  (defproto =savings-account= (=bank-account=)
    ((interest-rate 0)))
  
  (defproto =proxy-account= (=bank-account=) ())
  
  (defproto =money-market-account= (=checking-account= =savings-account=) ())
  
  ;; defsheep provides similar facilities to defproto, but without automatic accessor generation,
  ;; and the objects remain anonymous.
  (defvar *account-of-bank-president*
    (defsheep (=bank-account=)
        ((customer-name "The Prez Man")
         (balance 9001))))
  
  (defvar *janes-account*
    (defsheep (=bank-account=)
        ((customer-name "Jane Doe")
         (balance 1000))))
  
  ;; SPAWN is the most minimalist of the 3 creation methods: it only accepts a list of prototypes.
  ;; The two advantages of using SPAWN are that A. it's a function, you can apply it. B. It's simple.
  (defvar *lots-of-accounts*
    (loop repeat 1000 collect (spawn =bank-account=)))
  
  ;; you can add or remove direct properties from an object at any time, too...
  
  ;; this auto-generates accessors:
  (add-property (car *lots-of-accounts*) 'unique "I'm a unique butterfly!" :accessor t)
  (remove-property (car *lots-of-accounts*) 'unique) ;poof. Accessors stay, though!
  
  ;; You can also inspect objects and their internals at the REPL...
  ;;
  ;; SHEEPLE-USER> (property-summary *janes-account*)
  ;; Sheep: #<Sheep [=BANK-ACCOUNT=] #x1501FDF6>
  ;; Properties:
  
  ;;    Name:     CUSTOMER-NAME
  ;;    Value:    "Jane Doe"
  ;;    Owner:    #<Sheep [=BANK-ACCOUNT=] #x1501FDF6>
  
  ;;    Name:     BALANCE
  ;;    Value:    1000
  ;;    Owner:    #<Sheep [=BANK-ACCOUNT=] #x1501FDF6>
  
  ;;    Name:     ACCOUNT-NUMBER
  ;;    Value:    6
  ;;    Owner:    #<Sheep [=BANK-ACCOUNT=] #x1501FDF6>
  
  ;;    Name:     ACCOUNT-TYPE
  ;;    Value:    :BRONZE
  ;;    Owner:    #<Sheep =BANK-ACCOUNT= #x14FBC12E>
  
  ;;    Name:     NICKNAME
  ;;    Value:    =BANK-ACCOUNT=
  ;;    Owner:    #<Sheep =BANK-ACCOUNT= #x14FBC12E>
  
  ;; NIL
  ;; SHEEPLE-USER>
  ;; the [=foo=] name means that the object is inheriting the :nickname property, whereas
  ;; the same without [] means the object's nickname is set locally.
  
  (defmessage withdraw (account amount)
    (:documentation "Withdraw the specified amount from the account.
  Signal an error if the current balance is less than AMOUNT."))
  (defreply withdraw ((account =bank-account=) amount)
    (when (< (balance account) amount)
      (error "Account overdrawn."))
    (decf (balance account) amount))
  
  (defreply withdraw :before ((account =checking-account=) amount)
    (let ((overdraft (- amount (balance account))))
      (when (plusp overdraft)
        (withdraw (overdraft-account account) overdraft)
        (incf (balance account) overdraft))))
  
  (defreply withdraw ((proxy =proxy-account=) amount)
    (withdraw (proxied-account proxy) amount))
  
  (defreply withdraw :before ((account *account-of-bank-president*) amount)
  