Using Templates for Generalization in RESOLVE - PowerPoint PPT Presentation

1 / 61
About This Presentation
Title:

Using Templates for Generalization in RESOLVE

Description:

... statement, but you're throwing the value away if you do usually called as part ... while (s.Length() 0) int len = s.Length(); A Little Review Parameters ... – PowerPoint PPT presentation

Number of Views:47
Avg rating:3.0/5.0
Slides: 62
Provided by: awo4
Category:

less

Transcript and Presenter's Notes

Title: Using Templates for Generalization in RESOLVE


1
Using Templates for Generalization in RESOLVE
  • Annatala Wolf
  • 222 Lecture 1

2
Templates
  • A template is a definition for a type thats
    missing a key piece of information the names of
    one or more classes it uses. In order to create
    objects of a templates type, you have to
    instantiate it first, by filling it in to
    complete the template.
  • In this course, we use templates to design
    components that will work with many different
    types of data. This is what templates are
    typically used for in C, and what generics (a
    similar paradigm) are used for in Java and C.

3
Unconventional Use
  • We will also use templates to decouple component
    dependencies, for example, by plugging in which
    version of a kernel we want to use.
  • This is not typically how things are done in C.
    Usually, you would use something called
    polymorphism to accomplish the same task (though
    the task is important, however you do it).
  • The downside to this strategy is complex error
    messages that come from mistakes in template
    instantiations and from errors involving template
    types and/or kernel Representations.

4
Instantiation
  • When you fill in a template, this is called
    instantiating the template. To do this, you
    have to plug a class name (a type) into each
    template slot.
  • Until you instantiate a template, you cant use
    it to make objects. For example, Set is a
    template parameterized by Item. You cant make a
    Set object until you fill in what Item type the
    Set will hold.

5
Instantiation in Resolve/C
  • Normally, templates are filled in directly when
    they are used to declare objects, like so
  • // typical usage, but not in Resolve/C
  • SetltTextgt myTextSet
  • However, in this class we will instantiate
    templates in a way that creates a new type you
    can use just like any non-template type. We
    always do this at the top of the file, after the
    include statements.

6
Template Expectations
  • We dont expect you to write template
    declarations, since the way we use them in this
    course is unusual and complicated.
  • However, you do need to be able to instantiate
    templates (fill them in). You should know the
    syntax for instantiation in case you need to fill
    in a template on a test. It will also help you
    in Lab 2, where you can instantiate your own
    concrete instances.

7
Template Declaration (Simplified)
Item a template parameter to Sequence_Kernel_3
  • concrete_template lt
  • concrete_instance class Item, ...
  • / Other template parameters go here too.
    There are typically a bunch, since we
    use templates to decouple everything, so
    an actual declaration is complex. But
    you wont ever have to read or write one. /
  • gt
  • class Sequence_Kernel_3
  • implements
  • abstract_instance Sequence_Kernel ltItemgt,
  • encapsulates
  • concrete_instance Rep
  • / the operation bodies go here /

the name of this concrete template class
the abstract class (the specification) this class
implements, with Item plugged in
8
Template Instantiation (Client)
  • include CT/Set/Set_Kernel_1a_C.h
  • concrete_instance
  • class Set_Of_Text
  • instantiates
  • Set_Kernel_1a_C ltTextgt

what we want to call the new type were creating
the concrete type were plugging into the
template parameter for Item
the name of the concrete template we are
instantiating
9
Using Templates
  • Once youve instantiated your Set_Of_Text, you
    can use it just like any other type.
  • object Set_Of_Text myHappySet
  • object Text name Double Rainbow
  • myHappySet.Add(name)
  • The abstract specification in Set_Kernel will
    describe what a Set does, in terms that make
    sense no matter what type is plugged into Item.

10
Four Component Types
  • Abstract Instance (e.g. AM_PM_Clock_Kernel)
  • Prototype and formal description of contract for
    a particular kind of object
  • Abstract Template (e.g. Set_Kernel)
  • Prototype and formal description of contract for
    a parameterized kind of object (described in
    general)
  • Concrete Instance (e.g. AM_PM_Clock_Kernel_1)
  • Implementation code for an abstract instance or,
    the result of instantiating a concrete template
    by filling in the template parameters
  • Concrete Template (e.g. Set_Kernel_1)
  • Implementation code for an abstract template
    (written in a general way, so it can work with
    whatever Item is)

11
Combining Instantiations
  • concrete instance
  • class Set_Of_Integer
  • instantiates
  • Set_Kernel_1a_C ltIntegergt
  • // Now that Set_Of_Integer is a concrete
    instance,
  • // it can fill a template just like any other
    type!
  • concrete instance
  • class Power_Set
  • instantiates
  • Set_Kernel_1a_C ltSet_Of_Integergt

12
Containers
  • Many libraries for C and Java maintain
    collection objects designed to hold a dynamic
    number of items in some fashion. These
    collections are usually designed to hold many
    different kinds of items.
  • In Resolve/C we call our collection objects
    containers. Common examples of Resolve/C
    containers
  • Sequence totally ordered, random-access
  • Set unordered, named access
  • Queue totally ordered, FIFO-based access

13
Sequence
  • Intuitively, a sequence is like a flexible array.
  • You can insert in the middle. Elements to the
    right all move down one position, and it gets
    longer.
  • You can remove from the middle elements to the
    right move back one position, and it gets
    shorter.
  • You cant go past the end of the sequence.
  • Mathematically, sequence is modeled by string of
    Item.
  • The default value is the empty string ltgt
  • We describe position from left to right lt0, 1,
    2gt
  • Item is the template parameter. A given
    sequence can only hold elements of a single type.

14
Sequence Kernel Operations
  • Add(pos, x)
  • requires 0 pos self
  • Remove(pos, x)
  • requires 0 pos lt self
  • Accessor pos
  • requires 0 pos lt self
  • Length()
  • requires true
  • (in other wordsno requires clause)

15
SequenceltCharactergt ? Text
  • There is one key difference between a Sequence of
    Character and a Text object Add(pos, x) consumes
    x for Sequence, and preserves x for Text.
  • The reason why has to do with how we move
    information around in Resolve/C, and the fact
    that Item could be anything, including something
    we cant copy. With Text, we know we can copy
    its elements (Character is copyable). But we
    want to write Sequence so it will work with any
    type, even one that cant be copied. Hence, it
    must be consumes.

16
Reading Specifications
  • global_procedure Smooth (
  • preserves Sequence_Of_Integer s1,
  • produces Sequence_Of_Integer s2
  • )
  • /!
  • requires
  • s1 gt 0
  • ensures
  • s2 s1 - 1 and
  • for all i, j integer,
  • a, b string of integer
  • where (s1 a ltigt ltjgt b)
  • (there exists c, d string of
    integer
  • (s2 c lt(ij)/2gt d and c
    a))
  • !/

Eep! Im scared!
17
Breaking The Specification Down
  • Sequence is modeled by string of Item (in this
    case, Integer), so s1 and s2 will be type string
    of integer in the spec.
  • /!
  • s2 s1 - 1 and
  • for all i, j integer,
  • a, b string of integer
  • where (s1 a ltigt ltjgt b)
  • (there exists c, d string of
    integer
  • (s2 c lt(ij)/2gt d and c
    a))
  • !/

Part 1
Part 2
18
The easy part
  • // requires s1 gt 0
  • // ensures s2 s1 - 1 ...
  • This tells us s2 will be one item shorter than
    s1. It makes sense, since s1 cant be empty.
  • So if s1 has one item in it, s2 must be the empty
    string. But for longer s1 values, we need more
    information.
  • Since s2 is produces-mode, all of its values will
    have to come from s1, somehow.

19
Quantifiers For All
  • When we model strings of items, frequently we
    will want to talk about what happens throughout
    the entire string. In this case, we are talking
    about all possible ways that you can arrange s1,
    so that there is an ltigt next to a ltjgt all
    consecutive pairs i j.
  • The strings a and b are merely placeholders. It
    doesnt matter what they containtheyre just
    there so we can say lets talk about consecutive
    pairs of integers in s1.
  • for all i, j integer,
  • a, b string of integer
  • where (s1 a ltigt ltjgt b) ...

20
Vacuously True
  • If there are no integers and strings that make
    the statement true, then the spec tells us
    nothing. Its already vacuously true because
    there are no cases for us to test.
  • This could only happen when s1 lt 2. But we
    already know what happens when s1 1, and s1
    cant be 0, so were good.
  • for all i, j integer,
  • a, b string of integer
  • where (s1 a ltigt ltjgt b) ...

we need at least two integers in the string for
this case to happen
21
Quantifiers There Exists
  • With there exists, were usually making some
    assertion about the state of an object. Here, we
    say what the value of s2 has to be, based on the
    value of s1.
  • there exists c, d string of integer
  • (s2 c lt(ij)/2gt d and c a)

this part tells us what we should find in s2
this part tells us where it should be in the
string
22
What are the values?
  • The values in s2 are just the smoothed (averaged)
    values of each pair of integers. This is why s2
    is one shorter than s1. For example, if there
    are six integers in s1, there are only five
    consecutive pairs.
  • s2 c lt(ij)/2gt d

each integer in s2 is the average of two
consecutive integers from s1
23
Where do the values go?
  • By adding some information about those
    placeholder string variables, we can describe
    exactly how the two strings match up.
  • Can you figure out how they line up? (Hint
    Just ignore b and d!)
  • s1 a ltigt ltjgt b
  • s2 c lt(ij)/2gt d
  • c a

24
The Meaning of Smooth( )
  • The procedure simply averages the consecutive
    values of s1, and produces s2 with the averaged
    values in the same order in which the pairs
    appeared in s1.
  • This spec is a good example because its about
    the hardest thing you would be expected to read
    and interpret. Dont let quantifiers scare you.
    Most of the string variables we create with
    quantifiers are only there as placeholders, so we
    can talk about multiple cases at the same time.

25
Recursively-Defined Specifications
  • global_procedure Weird(alters Sequence_Of_Integer
    switch)
  • /! requires
  • (switch mod 2) 0
  • ensures
  • switch SWITCH(switch)
  • math_function SWITCH(string of integer s) string
    of integer
  • if s 0 then SWITCH(s) empty string
  • else if s 2 then there exists a, b
    integer
  • where (s ltagt ltbgt and SWITCH ltbgt
    ltagt)
  • else
  • there exists a, b integer t string of
    integer
  • where (s ltagt ltbgt t and
  • SWITCH(s) ltbgt ltagt
    SWITCH(t))
  • !/

A math_function is just a piece of a
specification. It is used to make specs easier
to read. It is not code. You cant make a
call to SWITCH(s).
26
The Specification for Weird( )
  • requires
  • (switch mod 2) 0
  • The sequence must contain an even number of
    integer elements.
  • ensures
  • switch SWITCH(switch)
  • Weird(switch) will alter the sequence you pass it
    by doing whatever SWITCH describes.

27
Interpreting SWITCH(s)
  • SWITCH changes one string of integer into a
    different string of integer.
  • math_function SWITCH(string of integer s) string
    of integer
  • if s 0 then SWITCH(s) empty string
  • else if s 2 then there exists a, b
    integer
  • where (s ltagt ltbgt and SWITCH(s) ltbgt
    ltagt)
  • else
  • there exists a, b integer t string of
    integer
  • where (s ltagt ltbgt t and
  • SWITCH(s) ltbgt ltagt
    SWITCH(t))

case 1 s 0
case 2 s 2
case 3 other
28
SWITCH(s) Case 1
  • If you SWITCH(lt gt), it returns lt gt. In other
    words, it does not change s when s is the empty
    string of integer.
  • if s 0 then
  • SWITCH(s) empty string

29
SWITCH(s) Case 2
  • If s has two elements, SWITCH(s) returns a string
    consisting of those same two integer elements, in
    reverse order.
  • else if s 2 then
  • there exists a, b integer where
  • (s ltagt ltbgt and
  • SWITCH(s) ltbgt ltagt)

30
Limiting Complexity
  • It turns out that SWITCH(s) doesnt make any
    sense at all when the length of s is odd. But
    thats okay, because were only using it to
    describe what happens when the length of s is
    even.
  • In other words, we dont need to bother reasoning
    about cases that wont come up.

31
SWITCH(s) Case 3
  • If s has more than two elements, we call the
    first two a and b. We reverse these two, then
    recurse to append SWITCH(t), where t is the rest
    of the string.
  • Its safe, since s is even implies s-2 is
    even.
  • else there exists a, b integer
  • t string of integer where
  • (s ltagt ltbgt t and
  • SWITCH(s) ltbgt ltagt SWITCH(t))

32
The Meaning of SWITCH(s)
  • Given a string of integer of even length, SWITCH
    takes every two integers and swaps them, like so
  • SWITCH(lt 1, 2, 3, 4, 5, 6 gt) lt 2, 1, 4, 3, 6, 5
    gt
  • Recursive descriptions are often the easiest way
    to describe things in math. Youll need to read
    them to understand the contracts for Lab 1.
  • Note just because a spec is recursive doesnt
    mean you need to use recursion to write code that
    implements it. Weird() would be both simpler and
    more efficient if written iteratively.

33
Set
  • Intuitively, a set is like a bunch of different
    items in a bag.
  • A set is only determined by its elementsit
    doesnt contain (or more precisely, doesnt
    remember or understand) duplicate items.
  • The items are not ordered.
  • Mathematically, a Set is modeled by set of Item.
  • The default value is the empty set
  • A set is an unordered container. The RESOLVE
    Set component also requires that all elements
    be of the same type (Item).

34
Set Kernel Operations
  • Add(x)
  • requires x ? self
  • Remove(x, x_copy)
  • requires x ? self
  • Remove_Any(x)
  • requires self gt 0
  • Is_Member(x)
  • requires true
  • Size()
  • requires true

35
Why restrict Add?
  • The restriction on Add(x) for Set (you can only
    add elements to a set if theyre not in the set
    already) seems unusual. From a math standpoint,
    it might make more sense to have a set ignore
    duplicate entries, than require that the client
    never add duplicates.
  • However, this restriction does make sense from a
    design-by-contract perspective. If we prohibit
    the addition of duplicates, this allows us to
    implement Set Kernel in a lot of different ways,
    some of which are much more efficient than the
    alternative approach.

36
Why does Remove take two Items?
  • Set is designed to work with any type (though it
    includes a special restriction that Item must
    implement Is_Equal_To).
  • If the type Set holds is very large, you might
    have a use for both the key x you pass to
    Remove(x, x_copy), and the copy x_copy that gets
    yanked out of the Set. It returns the copy to
    you just in case you need it, e.g., if copying
    Item is expensive or difficult.
  • However, most of the time youll just want to
    make a throw-away variable for x_copy.

37
Example of Set Math Operations
  • Let A 1, 2 B 2, 3
  • Element (the member is in the set)
  • 1 ? A 3 ? A
  • Subset (all members of one set are in the other)
  • ? A 1 ? B 1, 2 ? A
  • Union (the combined contents of two sets, like
    OR)
  • A ? B 1, 2, 3
  • Intersection (the overlap between two sets, like
    AND)
  • A ? B 2
  • Set Difference (elements in one set that arent
    in another)
  • A\B 1 (sometimes written A-B)
  • Power Set (the set of all subsets of a set)
  • P(A) , 1, 2, 1, 2

38
Why are these not part of Set_Kernel?
  • The purpose of a kernel is to provide a minimal
    set of operations needed to examine and change
    the abstract state space of an object.
  • Kernel operations must provide the ability to
    build any possible legal object of that type, and
    the ability to identify and change an unknown
    objects contents.
  • Set_Kernel doesnt include Union and Intersection
    because you dont need them to create and change
    a given set. You can build these operations
    later, using the operations the Kernel gives you.

39
Iterating With Sets
  • The process of iterating through an unordered
    collection in Resolve relies on using the Kernel
    operations (Remove_Any(x), for Sets) to dump out
    the contents into a temporary object, so you can
    remember what youve seen and what you havent.
  • Once youve gone through all the items, the
    original Set will be empty, and the temporary Set
    will be full. A swap will then restore the
    original Set, preserving it.

40
Practice Using Sets
  • Lets build a function that takes two
    Set_Of_Integer objects (instantiated from
    SetltIntegergt) and returns a Boolean value for the
    subset operator.
  • (A ? B means all elements of A are also elements
    of B.)
  • Get into teams of two to four.
  • When writing code, remember to use object
    Set_Of_Integer to create a new empty set that
    can hold Integers, if you need one.
  • Eventually well learn how to do this kind of
    extension for ANY type of Set, but for this test
    well just use Set_Of_Integer.

41
Templating and Prototype
  • include CT/Set/Set_Kernel_1a_C.h
  • concrete instance
  • class Set_Of_Integer
  • instantiates
  • Set_Kernel_1a_C ltIntegergt
  • global_function Boolean Is_Subset(
  • preserves Set_Of_Integer subset,
  • preserves Set_Of_Integer superset
  • )
  • /!
  • ensures
  • Is_Subset
  • for all i integer
  • where i is in subset
  • (i is in superset)
  • !/

if the name of the function appears in its spec,
this means the value that gets returned
put another way, returns false iff (if and only
if) subset has something superset doesnt
42
Is_Subset
  • global_function_body Boolean Is_Subset(
  • preserves Set_Of_Integer subset,
  • preserves Set_Of_Integer superset
  • )
  • object catalyst Set_Of_Integer subset_seen
  • object Boolean answer true
  • // check each element from subset to see if
    its in superset
  • while (subset.Size() gt 0)
  • object catalyst Integer elem
  • subset.Remove_Any(elem)
  • if (not superset.Is_Member(elem))
  • answer false
  • subset_seen.Add(elem) // hold on to
    what weve
  • // already
    iterated through
  • subset subset_seen // now, we can
    restore subset

43
Planning in Is_Subset
  • Note that we started by setting our answer to
    true. This is a good choice, because in the case
    that we have nothing to test (because subset is
    empty), result is vacuously true.
  • When we set the answer to false, it has no way to
    change back again. As soon as we find a
    counterexample, we have our answer.
  • However, we cant return as soon as we find such
    a counterexample! We have to iterate through the
    rest of the set so that we can restore it to its
    original value. Planning to return at the end of
    the function avoids error.

44
Queue
  • Intuitively, a queue is like data waiting in
    line. The data waiting the longest is the next
    available.
  • A queue is useful for handling data in the order
    that it arrives or is stored (oldest item first)
  • Sometimes this is called FIFO (first in, first
    out)
  • Mathematically, a queue is modeled by string of
    Item.
  • The default value is the empty string ltgt
  • This is the same model as Sequence! The data is
    represented the same way abstractly.
  • The difference is how you access the data (what
    operations you have available to you).
  • The head (current) is the leftmost member ltA,
    Bgt

45
Arbitrary Notation
  • We model Queue abstractly by setting the head of
    the queue to be the left side.
  • Removing an object x removes the head
  • Dequeue(x) ensures (q ltxgt q)
  • Inserting an object x concatenates onto the tail
  • Enqueue(x) ensures (q q ltxgt).
  • This choice was made since English reads from
    left to right, but its arbitrary. Queue would
    work the same way if we reversed all of its specs.

46
Queue Kernel Operations
  • Enqueue(x)
  • requires true
  • Dequeue(x)
  • requires self gt 0
  • Accessor current
  • requires self gt 0
  • Length()
  • requires true

47
Practice Using Queues
  • Lets write an operation to find both the min and
    max value in a Queue. (Hint you dont need to
    make a new Queue!)
  • global_procedure Find_Min_And_Max (
  • preserves Queue_Of_Integer values,
  • produces Integer min,
  • produces Integer max,
  • )
  • /!
  • requires
  • values gt 0
  • ensures
  • max is in values and
  • min is in values and
  • for all i integer
  • where (i is in values)
  • (max i and min i)
  • !/

48
Find_Min_And_Max
  • global_procedure_body Find_Min_And_Max (
  • preserves Queue_Of_Integer values,
  • produces Integer min,
  • produces Integer max )
  • object Integer counter
  • min valuescurrent
  • max valuescurrent
  • while (counter lt values.Length())
  • object catalyst Integer last
  • values.Dequeue(last)
  • values.Enqueue(last)
  • if (max lt valuescurrent)
  • max valuescurrent
  • if (min gt valuescurrent)
  • min valuescurrent
  • counter

49
Planning in Find_Min_And_Max
  • Notice that we copy a value from the queue (which
    must exist, since its required to be nonempty)
    into min and max at the outset. This ensures we
    dont accidentally produce a number that isnt in
    the queue.
  • A common approach might involve checking the
    dequeued item, rather than using current.
    Theres nothing wrong with this approach, but
    its helpful to see how useful current can be.
    With some operations, it can provide significant
    clarity, and save time.

50
Queue Rotation
  • I like to call a Dequeue of an element, followed
    by an Enqueue of the same element, a rotation of
    a Queue.
  • Since Queue is last-in, first-out, this preserves
    order. If you rotate a Queue a number of times
    equal to the length of the Queue, it restores the
    Queue to its original values
  • original lt1, 2, 3gt (the queue has
    three elements)
  • one rotation lt2, 3, 1gt
  • two rotations lt3, 1, 2gt
  • three rotations lt1, 2, 3gt (the original order
    is restored)
  • This lets us easily iterate through a Queue while
    preserving it, without the need for a separate
    Queue.

51
Uses for Sequence, Set, Queue
  • Sequence is useful when you need to keep
    something in order as you insert new elements
    into the middle
  • an outline, when you need to edit things in the
    middle
  • a list of items you want insertion sort to keep
    in order
  • Set is useful when you need to test a binary
    condition over a group of items
  • a set of keywords, so you can check if a word is
    a keyword
  • a set of filenames, so you know which files are
    up-to-date
  • Queue is useful when you want to process things
    in the order you encounter them
  • a queue of print jobs waiting to print, oldest
    job first
  • a queue of chores that need to be done, oldest
    job first

52
Record
  • Intuitively, Record is like a single row in a
    data-base table (Anna Wolf, 123456789,
    Gemini)
  • Mathematically, Record is modeled by n-tuple of
    objects, where n is an integer between 1 and 10.
  • Record is a client template that allows different
    types to be stored together in the same object.
  • Each field of a Record (piece of tuple) has its
    own type.
  • The default value of a Record is a tuple
    consisting of the default values of all of its
    fields ( d1, d2, d3)
  • For example, the default value of
  • RecordltInteger, Text, Queue_Of_Textgt ( 0, ,
    ltgt)
  • RecordltReal, Boolean, Real, Charactergt ( 0.0,
    false, 0.0, \0)

53
Interesting Record Facts
  • In most cases, its better create a new component
    than make a Record. This is because its useful
    to have not only data held in a package, but also
    the algorithms that handle the data.
  • Theres a special version of Record found inside
    Kernels, called Representation. Its used to
    hold the Kernels data members. Representation
    works just like Record.
  • Record is a Resolve/C foundation type(and so
    is Representation).

54
Instantiating Record
  • To instantiate a record, you must fill in the
    template AND name the fields
  • concrete instance
  • class Nickname_And_Grade
  • instantiates
  • Record lt
  • Text,
  • Integer
  • gt
  • field_name (Nickname_And_Grade, 0, Text,
    nickname)
  • field_name (Nickname_And_Grade, 1, Integer,
    grade)

our name for the new Record type
the field types you can put from 1 to 10 types
here
a field_name must be declared for each field,
once the Record is instantiated (usually done
right after instatiation)
55
Instantiating Record
  • Before using a Record, you must name each field.
  • The index is the position the field appeared at
    in the instantiation, as an integer starting from
    0.
  • The fieldname is the only thing you control.
    Everything else is pulled from the instantiation.
  • field_name (Nickname_And_Grade, 0, Text,
    nickname)
  • field_name (Nickname_And_Grade, 1, Integer,
    grade)

the fieldname you want to use to access the
field at that index
name of the Record type
index of the field
the type of the field at that index
56
Record Details
  • Once you instantiate Record and name its fields,
    each fieldname has a type permanently associated
    with it.
  • Making a new Record will create one new object
    for each of its fields, and those objects will be
    of their default types. Similarly, clearing a
    Record resets each of its objects to their
    default types.
  • Record is not a collection object! A Record is a
    single tuple. It always has something inside it,
    and only stores one group of fields.

57
Combining Record Instantiations
  • concrete instance
  • class Full_Name field_name(Full_Name,
    ...
  • instantiates
  • Record lt
  • Text, ... 0, Text,
    first_name)
  • Text ... 1, Text,
    last_name)
  • gt
  • concrete_instance
  • class Name_And_Grade field_name(Name_And_G
    rade, ...
  • instantiates
  • Record lt
  • Full_Name, ... 0, Full_Name,
    name)
  • Integer ... 1, Integer,
    grade)
  • gt

58
Using Record
  • Records only operation is Accessor
  • fieldname (returns a reference to named field)
  • The only legal thing you can put in Records
    Accessor is a fieldname you have already defined.
  • Since Accessor returns a reference, you can use
    it just like its a variable. In other words, if
    you create a Full_Name object called student,
    then you just created two Text objects, called
    studentfirst_name and studentlast_name.

59
Examples Using Record
  • object Name_And_Grade student
  • object Name_And_Grade other_student
  • object Set_Of_Name_And_Grade course
  • studentnamefirst_name Early
  • studentnamelast_name Cuyler
  • studentgrade 3
  • student other_student
  • course.Add(other_student)

60
Unrolling Expressions
  • Its important that you be able to unroll an
    expression to figure out the types of its terms.
  • Consider a Queue_Of_Name_And_Grade object called
    foo. Can you identify all of the types here?
  • foocurrentnamelast_name

61
Identifying All of the Types
  • foocurrentnamelast_name

Queue_Of_Name_And_Grade
keyword
field_name
Name_And_Grade
Full_Name
Text
Write a Comment
User Comments (0)
About PowerShow.com