Chapter 32: Case Study: Purely Functional Objects

 < Free Open Study > 



Our final case study continues the development of the existential object model. This model was introduced briefly in §24.2, which showed how existential packages could be regarded as simple objects, and compared the properties of this style of abstraction with the use of existentials to implement more conventional abstract data types. In this chapter, we use the tools developed in the past few chapters (type operators and higher-order subtyping, plus one new feature, polymorphic update, that we introduce in §32.7) to extend these simple existential objects to a set of idioms offering the flexibility of full-blown object-oriented programming, including classes and inheritance.

32.1 Simple Objects

Let us begin by recalling, from §24.2, the type of purely functional Counter objects:

   Counter = {$X, {state:X, methods:{get:XNat, inc:XX}}}; 

The elements of this type are packages with a hidden state type X, a state of type X, and a record of methods of type {get:XNat,inc:XX}.

For the first few sections of this chapter, we will use the type {x:Nat} as the representation type of all our objects. (In §32.8 we will see how to define objects with multiple instance variables, as well as classes that add new instance variables.) We will consistently use the abbreviation CounterR when we are talking about the internal state type.

   CounterR = {x:Nat}; 

A counter object is an element of the type Counter, defined according to the rule for existential introduction (T-PACK in Figure 24-1).[1]

   c = {*CounterR,        {state = {x=5},         methods = {get = λr:CounterR. r.x,                    inc = λr:CounterR. {x=succ(r.x)}}}} as Counter;  c : Counter 

Invoking the methods of a Counter involves unpacking it, selecting the appropriate field from its methods, and applying it to the state,

   sendget = λc:Counter.               let {X,body} = c in               body.methods.get(body.state);  sendget : Counter  Nat 

and finally (in the case of inc, which must return a new object, not just a bare number) repackaging the result into a new object with the same representation type and methods as the original.

   sendinc = λc:Counter.               let {X,body} = c in                 {*X,                  {state = body.methods.inc(body.state),                   methods = body.methods}} as Counter;  sendinc : Counter  Counter 

These basic functions can be used to build up more complex terms that manipulate Counter objects.

   addthree = λc:Counter. sendinc (sendinc (sendinc c));  addthree : Counter  Counter 

[1]The examples in this chapter are terms of (Figure 31-1) with records (11-7), numbers (8-2) and polymorphic update (32-1). The associated OCaml implementation is fullupdate.



 < Free Open Study > 



Types and Programming Languages
Types and Programming Languages
ISBN: 0262162091
EAN: 2147483647
Year: 2002
Pages: 262

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net