Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

Like this presentation? Why not share!

Stoop 416-lsp






Total Views
Views on SlideShare
Embed Views



0 Embeds 0

No embeds



Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
Post Comment
Edit your comment

Stoop 416-lsp Stoop 416-lsp Presentation Transcript

  • LSP
    • Stéphane Ducasse --- 2005
  • A step deeper in Subtyping...
  • Liskov Substitution Principle (LSP)
    • if for each object o1 of type S there is another object o2 of type T such that for all programs P defined in terms of T, the behavior of P is unchanged when o1 is substituted for o2, then S is a subtype of T.
    • Barbara Liskov, "Data Abstraction and Hierarchy," SIGPLAN Notices, 23,5 (May 1988)
  • A Simple Bag
    • We will define a Bag as an object that accepts two messages: put and count
    • (send a-Bag 'put x)
      • puts an element x into the Bag, and
    • (send a-Bag 'count x)
      • gives the count of occurrences of x in the Bag (without changing a-Bag's state).
  • A Simple Set
    • Likewise, a Set is defined as an object that accepts two messages:
    • (send a-Set 'put x)
      • puts an element x into a-Set unless it was already there,
    • (send a-Set 'count x)
      • gives the count of occurrences of x in a-Set (which is always either 0 or 1).
  • A Bag Function
    • (define (fnb bag)
    • (send bag 'put 5)
    • (send bag 'put 5)
    • (send bag 'count 5))
    • The behavior of this function can be summed as follows: given a Bag, the function adds two elements into it and returns
    •      (+ 2 (send orig-bag 'count 5))
  • The problem
    • Technically you can pass to fnb a Set object as well. Just as a Bag, a Set object accepts messages put and count . However applying fnb to a Set object will break the function's post-condition
    • Therefore, passing a set object where a bag was expected changes behavior of some program. According to the Liskov Substitution Principle (LSP), a Set is not substitutable for a Bag -- a Set cannot be a subtype of a Bag.
  • Another function
    • (define (fns set)
    • (send set 'put 5)
    • (send set 'count 5))
    • The behavior of this function is: given a Set, the function adds an element into it and returns 1.
  • Problem two
    • If you pass to this function a bag (which -- just as a set -- replies to messages put and count ), the function fns may return a number greater than 1 . This will break fns 's contract, which promised always to return 1.
  • Finally
    • Therefore, from the OO point of view, neither a Bag nor a Set are a subtype of the other.
    • Bag and Set only appear similar. The interface or an implementation of a Bag and a Set appear to invite subclassing of a Set from a Bag (or vice versa). Doing so however will violate the LSP -- and you have to brace for very subtle errors.
    • Sets and Bags are very simple types, far simpler than the ones you deal with in a production code. either. It's manual work -- you have to see the problem
  • Watch out
    • Alas, LSP when considered from an OOP point of view is undecidable.
    • You cannot count on a compiler for help in pointing out an error. You cannot rely on regression tests
  • In C++
    • typedef int const * CollIterator; // Primitive but will do
    • class CBag {
    • public:
    • int size(void) const; // The number of elements in the bag
    • virtual void put(const int elem); // Put an element into the bag
    • int count(const int elem) const; // Count the number of occurrences
    • // of a particular element in the bag
    • virtual bool del(const int elem); // Remove an element from the bag
    • // Return false if the element
    • // didn't exist
    • CollIterator begin(void) const; // Standard enumerator interface
    • CollIterator end(void) const;
    • CBag(void);
    • virtual CBag * clone(void) const; // Make a copy of the bag
    • private:
    • // implementation details elided
    • };
  • CSet
    • class CSet : public CBag {
    • public:
    • bool memberof(const int elem) const { return count(elem) > 0; }
    • // Overriding of CBag::put
    • void put(const int elem)
    • { if(!memberof(elem)) CBag::put(elem); }
    • CSet * clone(void) const
    • { CSet * new_set = new CSet(); *new_set += *this; return new_set; }
    • CSet(void) {}
    • };
  • Summary
    • Subtyping...