changeset 21061:220506787b93

doc: Overhaul chapter on old-style Object Oriented Programming. * oop.txi: Clean up language which had some odd phrasings. Use the neutral third person rather than "we/our". Eliminate extra spaces before code in @example blocks. Wrap lines at 80 characters.
author Rik <rik@octave.org>
date Wed, 13 Jan 2016 22:18:55 -0800
parents 31d41418fa57
children d9c1884d1aaa
files doc/interpreter/oop.txi
diffstat 1 files changed, 223 insertions(+), 229 deletions(-) [+]
line wrap: on
line diff
--- a/doc/interpreter/oop.txi	Wed Jan 13 17:11:56 2016 -0800
+++ b/doc/interpreter/oop.txi	Wed Jan 13 22:18:55 2016 -0800
@@ -24,16 +24,16 @@
 @node Object Oriented Programming
 @chapter Object Oriented Programming
 
-Octave includes the capability to include user classes, including the
-features of operator and function overloading.  Equally a user class
-can be used to encapsulate certain properties of the class so that
-they cannot be altered accidentally and can be set up to address the
-issue of class precedence in mixed class operations.
+Octave includes the capability to create user-defined classes, including the
+capabilities of operator and function overloading.  Classes can protect
+internal properties so they can not be altered accidentally which facilitates
+data encapsulation.  In addition, rules can be created to address the issue
+of class precedence in mixed class operations.
 
-This chapter discussions the means of constructing a user class with
-the example of a polynomial class, how to query and set the properties
-of this class, together with the means to overload operators and
-functions.
+This chapter discusses the means of constructing a user class, how to query and
+set the properties of a class, and how to overload operators and functions.
+Throughout this chapter real code examples are given using a class designed
+for polynomials.
 
 @menu
 * Creating a Class::
@@ -46,12 +46,12 @@
 @node Creating a Class
 @section Creating a Class
 
-We use in the following text a polynomial class to demonstrate the use
-of object oriented programming within Octave.  This class was chosen as
-it is simple, and so doesn't distract unnecessarily from the
-discussion of the programming features of Octave.  However, even still
-a small understand of the polynomial class itself is necessary to
-fully grasp the techniques described.
+This chapter illustrates user-defined classes and object oriented programming
+through a custom class designed for polynomials.  This class was chosen as it
+is simple, and therefore doesn't distract unnecessarily from the discussion of
+the programming features of Octave.  Even so, a bit of background on the goals
+of the polynomial class is necessary before the syntax and techniques of Octave
+object oriented programming are introduced.
 
 The polynomial class is used to represent polynomials of the form
 @tex
@@ -80,48 +80,47 @@
 a = [a0, a1, a2, @dots{}, an];
 @end example
 
-We therefore now have sufficient information about the requirements of
-the class constructor for our polynomial class to write it.  All object
-oriented classes in Octave, must be contained with a directory taking
-the name of the class, prepended with the @@ symbol.  For example, with
-our polynomial class, we would place the methods defining the class in
-the @@polynomial directory.
+This is is a sufficient specification to begin writing the constructor for the
+polynomial class.  All object oriented classes in Octave must be located in a
+directory that has the name of the class prepended with the @@ symbol.  For
+example, the polynomial class will have all of its methods defined in the
+@@polynomial directory.
 
-The constructor of the class, must have the name of the class itself
-and so in our example the constructor with have the name
-@file{@@polynomial/polynomial.m}.  Also ideally when the constructor is
-called with no arguments to should return a value object.  So for example
-our polynomial might look like
+The constructor for the class must be the name of the class itself; in this
+example the constructor has the name @file{@@polynomial/polynomial.m}.
+Ideally, even when the constructor is called with no arguments it should return
+a valid object.  A constructor for the polynomial class might look like
 
 @example
 @EXAMPLEFILE(@polynomial/polynomial.m)
 @end example
 
-Note that the return value of the constructor must be the output of
-the @code{class} function called with the first argument being a
-structure and the second argument being the class name.  An example of
-the call to this constructor function is then
+Note that the return value of the constructor must be the output of the
+@code{class} function.  The first argument to the @code{class} function is a
+structure and the second is the name of the class itself.  An example of
+calling the class constructor to create an instance is
 
 @example
 p = polynomial ([1, 0, 1]);
 @end example
 
-Note that methods of a class can be documented.  The help for the
-constructor itself can be obtained with the constructor name, that is
-for the polynomial constructor @code{help polynomial} will return the
-help string.  Also the help can be obtained by restricting the search
-for the help to a particular class, for example @code{help
-@@polynomial/polynomial}.  This second method is the only means of
-getting help for the overloaded methods and functions of the class.
+Methods are defined by m-files in the class directory and can have embedded
+documentation the same as any other m-file.  The help for the constructor can
+be obtained by using the constructor name alone, that is, for the polynomial
+constructor @code{help polynomial} will return the help string.  Help can be
+restricted to a particular class by using the class directory name followed
+by the method.  For example, @code{help @@polynomial/polynomial} is another
+way of displaying the help string for the polynomial constructor.  This second
+means is the only way to obtain help for the overloaded methods and functions
+of the class.
 
-The same is true for other Octave functions that take a function name
-as an argument.  For example @code{type @@polynomial/display} will
-print the code of the display method of the polynomial class to the
-screen, and @code{dbstop @@polynomial/display} will set a breakpoint
-at the first executable line of the display method of the polynomial
-class.
+The same specification mechanism can be used wherever Octave expects a function
+name.  For example @code{type @@polynomial/display} will print the code of the
+display method of the polynomial class to the screen, and
+@code{dbstop @@polynomial/display} will set a breakpoint at the first
+executable line of the display method of the polynomial class.
 
-To check where a variable is a user class, the @code{isobject} and
+To check whether a variable belongs to a user class, the @code{isobject} and
 @code{isa} functions can be used.  For example:
 
 @example
@@ -137,13 +136,13 @@
 @DOCSTRING(isobject)
 
 @noindent
-The available methods of a class can be displayed with the
-@code{methods} function.
+The available methods of a class can be displayed with the @code{methods}
+function.
 
 @DOCSTRING(methods)
 
 @noindent
-To inquire whether a particular method is available to a user class, the
+To inquire whether a particular method exists for a user class, the
 @code{ismethod} function can be used.
 
 @DOCSTRING(ismethod)
@@ -162,12 +161,12 @@
 @node Manipulating Classes
 @section Manipulating Classes
 
-There are a number of basic classes methods that can be defined to allow
-the contents of the classes to be queried and set.  The most basic of
-these is the @code{display} method.  The @code{display} method is used
-by Octave when displaying a class on the screen, due to an expression
-that is not terminated with a semicolon.  If this method is not defined,
-then Octave will printed nothing when displaying the contents of a class.
+There are a number of basic class methods that can (and should) be defined to
+allow the contents of the classes to be queried and set.  The most basic of
+these is the @code{display} method.  The @code{display} method is used by
+Octave when displaying a class on the screen, usually the result of an Octave
+expression that does not end with a semicolon.  If this method is not defined,
+then Octave won't print anything when displaying the contents of a class.
 
 @DOCSTRING(display)
 
@@ -179,46 +178,47 @@
 @end example
 
 @noindent
-Note that in the display method, it makes sense to start the method
-with the line @code{fprintf ("%s =", inputname (1))} to be consistent
-with the rest of Octave and print the variable name to be displayed
-when displaying the class.
+Note that in the display method it makes sense to start the method with the
+line @code{printf ("%s =", inputname (1))} to be consistent with the rest of
+Octave and print the variable name to be displayed when displaying a class
+object.
 
-To be consistent with the Octave graphic handle classes, a class
-should also define the @code{get} and @code{set} methods.  The
-@code{get} method should accept one or two arguments, and given one
-argument of the appropriate class it should return a structure with
-all of the properties of the class.  For example:
+To be consistent with the Octave graphic handle classes, a class should also
+define the @code{get} and @code{set} methods.  The @code{get} method accepts
+one or two arguments.  The first argument is an object of the appropriate
+class.  If no other argument is given then the method should return a structure
+with all the properties of the class.  If a second argument is given it should
+be a property name and the property specified should be retrieved.
 
 @example
 @EXAMPLEFILE(@polynomial/get.m)
 @end example
 
 @noindent
-Similarly, the @code{set} method should taken as its first argument an
-object to modify, and then take property/value pairs to be modified.
+Similarly, the first argument to the @code{set} method should be an object and
+any additional arguments should be property/value pairs.
 
 @example
 @EXAMPLEFILE(@polynomial/set.m)
 @end example
 
 @noindent
-Note that as Octave does not implement pass by reference, than the
-modified object is the return value of the @code{set} method and it
-must be called like
+Note that Octave does not implement pass by reference; Therefore, to modify an
+object requires an assignment statement using the return value from the
+@code{set} method.
 
 @example
-p = set (p, "a", [1, 0, 0, 0, 1]);
+p = set (p, "poly", [1, 0, 0, 0, 1]);
 @end example
 
 @noindent
-Also the @code{set} method makes use of the @code{subsasgn} method of
-the class, and this method must be defined.  The @code{subsasgn} method
-is discussed in the next section.
+The @code{set} method makes use of the @code{subsasgn} method of the class, and
+therefore this method must also be defined.  The @code{subsasgn} method is
+discussed more thoroughly in the next section (@pxref{Indexing Objects}).
 
-Finally, user classes can be considered as a special type of a
-structure, and so they can be saved to a file in the same manner as a
-structure.  For example:
+Finally, user classes can be considered to be a special type of a structure,
+and they can be saved to a file in the same manner as a structure.  For
+example:
 
 @example
 @group
@@ -230,19 +230,18 @@
 @end example
 
 @noindent
-All of the file formats supported by @code{save} and @code{load} are
-supported.  In certain circumstances, a user class might either contain
-a field that it makes no sense to save or a field that needs to be
-initialized before it is saved.  This can be done with the
-@code{saveobj} method of the class
+All of the file formats supported by @code{save} and @code{load} are supported.
+In certain circumstances a user class might contain a field that it doesn't
+make sense to save, or a field that needs to be initialized before it is saved.
+This can be done with the @code{saveobj} method of the class.
 
 @DOCSTRING(saveobj)
 
 @noindent
-@code{saveobj} is called just prior to saving the class to a
-file.  Likely, the @code{loadobj} method is called just after a class
-is loaded from a file, and can be used to ensure that any removed
-fields are reinserted into the user object.
+@code{saveobj} is called just prior to saving the class to a file.  Similarly,
+the @code{loadobj} method is called just after a class is loaded from a file,
+and can be used to ensure that any removed fields are reinserted into the user
+object.
 
 @DOCSTRING(loadobj)
 
@@ -257,21 +256,21 @@
 @node Defining Indexing And Indexed Assignment
 @subsection Defining Indexing And Indexed Assignment
 
-Objects can be indexed with parentheses, either like
-@code{@var{a} (@var{idx})} or like @code{@var{a} @{@var{idx}@}}, or even
-like @code{@var{a} (@var{idx}).@var{field}}.  However, it is up to the user
-to decide what this indexing actually means.  In the case of our polynomial
-class @code{@var{p} (@var{n})} might mean either the coefficient of the
-@var{n}-th power of the polynomial, or it might be the evaluation of the
+Objects can be indexed with parentheses or braces, either like
+@code{@var{obj}(@var{idx})} or like @code{@var{obj}@{@var{idx}@}}, or even
+like @code{@var{obj}(@var{idx}).@var{field}}.  However, it is up to the
+programmer to decide what this indexing actually means.  In the case of the
+polynomial class @code{@var{p}(@var{n})} might mean either the coefficient of
+the @var{n}-th power of the polynomial, or it might be the evaluation of the
 polynomial at @var{n}.  The meaning of this subscripted referencing is
 determined by the @code{subsref} method.
 
 @DOCSTRING(subsref)
 
-For example we might decide that indexing with @qcode{"()"} evaluates the
-polynomial and indexing with @qcode{"@{@}"} returns the @var{n}-th coefficient
-(of @var{n}-th power).  In this case the @code{subsref} method of our
-polynomial class might look like
+For example, this class uses the convention that indexing with @qcode{"()"}
+evaluates the polynomial and indexing with @qcode{"@{@}"} returns the
+@var{n}-th coefficient (of the @var{n}-th power).  The code for the
+@code{subsref} method of looks like
 
 @example
 @EXAMPLEFILE(@polynomial/subsref.m)
@@ -289,10 +288,9 @@
 responsibility of these methods to handle the rest of the chain (if needed),
 usually by forwarding it again to @code{subsref} or @code{subsasgn}.
 
-If you wish to use the @code{end} keyword in subscripted expressions
-of an object, then the user needs to define the @code{end} method for
-the class.  For example, the @code{end} method for our polynomial class might
-look like
+If you wish to use the @code{end} keyword in subscripted expressions of an
+object, then the there must be an @code{end} method defined.  For example, the
+@code{end} method for the polynomial class might look like
 
 @example
 @group
@@ -301,39 +299,36 @@
 @end example
 
 @noindent
-which is a fairly generic @code{end} method that has a behavior similar to
-the @code{end} keyword for Octave Array classes.  It can then be used as
-follows:
+which is a fairly generic @code{end} method that has a behavior similar to the
+@code{end} keyword for Octave Array classes.  It can then be used as follows:
 
 @example
 @group
 p = polynomial ([1,2,3,4]);
-p(end-1)
+p@{end-1@}
   @result{} 3
 @end group
 @end example
 
-Objects can also be used as the index in a subscripted expression themselves
-and this is controlled with the @code{subsindex} function.
+Objects can also be used themselves as the index in a subscripted expression 
+and this is controlled by the @code{subsindex} function.
 
 @DOCSTRING(subsindex)
 
-Finally, objects can equally be used like ranges, using the @code{colon}
-method
+Finally, objects can be used like ranges by providing a @code{colon} method.
 
 @DOCSTRING(colon)
 
 @node Indexed Assignment Optimization
 @subsection Indexed Assignment Optimization
 
-Octave's ubiquitous lazily-copied pass-by-value semantics implies
-a problem for performance of user-defined subsasgn methods.  Imagine
-a call to subsasgn:
+Octave's ubiquitous lazily-copied pass-by-value semantics implies a problem for
+performance of user-defined subsasgn methods.  Imagine a call to subsasgn:
 
 @example
 @group
-  ss = substruct ("()",@{1@});
-  x = subsasgn (x, ss, 1);
+ss = substruct ("()", @{1@});
+x = subsasgn (x, ss, 1);
 @end group
 @end example
 
@@ -342,48 +337,47 @@
 
 @example
 @group
-  function x = subsasgn (x, ss, val)
-    @dots{}
-    x.myfield (ss.subs@{1@}) = val;
-  endfunction
+function x = subsasgn (x, ss, val)
+  @dots{}
+  x.myfield (ss.subs@{1@}) = val;
+endfunction
 @end group
 @end example
 
 The problem is that on entry to the subsasgn method, @code{x} is still
-referenced from the caller's scope, which means that the method will
-first need to unshare (copy) @code{x} and @code{x.myfield} before performing
-the assignment.  Upon completing the call, unless an error occurs,
-the result is immediately assigned to @code{x} in the caller's scope,
-so that the previous value of @code{x.myfield} is forgotten.  Hence, the
-Octave language implies a copy of N elements (N being the size of
-@code{x.myfield}), where modifying just a single element would actually
-suffice, i.e., degrades a constant-time operation to linear-time one.
-This may be a real problem for user classes that intrinsically store large
-arrays.
+referenced from the caller's scope, which means that the method will first need
+to unshare (copy) @code{x} and @code{x.myfield} before performing the
+assignment.  Upon completing the call, unless an error occurs, the result is
+immediately assigned to @code{x} in the caller's scope, so that the previous
+value of @code{x.myfield} is forgotten.  Hence, the Octave language implies a
+copy of N elements (N being the size of @code{x.myfield}), where modifying just
+a single element would actually suffice.  In other words, a constant-time
+operation is degraded to linear-time one.  This may be a real problem for user
+classes that intrinsically store large arrays.
 
-To partially solve the problem, Octave uses a special optimization for
-user-defined subsasgn methods coded as m-files.  When the method
-gets called as a result of the built-in assignment syntax (not direct subsasgn
-call as shown above), i.e.
+To partially solve the problem Octave uses a special optimization for
+user-defined subsasgn methods coded as m-files.  When the method gets called as
+a result of the built-in assignment syntax (not a direct subsasgn call as shown
+above), i.e.,
 
 @example
-  x(1) = 1;
+x(1) = 1;
 @end example
 
-@b{AND} if the subsasgn method is declared with identical input and output argument,
-like in the example above, then Octave will ignore the copy of @code{x} inside
-the caller's scope; therefore, any changes made to @code{x} during the method
-execution will directly affect the caller's copy as well.
+@b{AND} if the subsasgn method is declared with identical input and output
+arguments, as in the example above, then Octave will ignore the copy of
+@code{x} inside the caller's scope; therefore, any changes made to @code{x}
+during the method execution will directly affect the caller's copy as well.
 This allows, for instance, defining a polynomial class where modifying a single
 element takes constant time.
 
 It is important to understand the implications that this optimization brings.
-Since no extra copy of @code{x} in the caller's scope will exist, it is
+Since no extra copy of @code{x} will exist in the caller's scope, it is
 @emph{solely} the callee's responsibility to not leave @code{x} in an invalid
-state if an error occurs throughout the execution.  Also, if the method
-partially changes @code{x} and then errors out, the changes @emph{will} affect
-@code{x} in the caller's scope.  Deleting or completely replacing @code{x}
-inside subsasgn will not do anything, however, only indexed assignments matter.
+state if an error occurs during the execution.  Also, if the method partially
+changes @code{x} and then errors out, the changes @emph{will} affect @code{x}
+in the caller's scope.  Deleting or completely replacing @code{x} inside
+subsasgn will not do anything, however, only indexed assignments matter.
 
 Since this optimization may change the way code works (especially if badly
 written), a built-in variable @code{optimize_subsasgn_calls} is provided to
@@ -392,9 +386,9 @@
 
 @example
 @group
-  function y = subsasgn (x, ss, val)
-    @dots{}
-  endfunction
+function y = subsasgn (x, ss, val)
+  @dots{}
+endfunction
 @end group
 @end example
 
@@ -410,10 +404,9 @@
 @node Function Overloading
 @subsection Function Overloading
 
-Any Octave function can be overloaded, and allows an object specific
-version of this function to be called as needed.  A pertinent example
-for our polynomial class might be to overload the @code{polyval} function
-like
+Any Octave function can be overloaded, and this allows an object specific
+version of a function to be called as needed.  A pertinent example for the
+polynomial class might be to overload the @code{polyval} function.
 
 @example
 @group
@@ -422,7 +415,7 @@
 @end example
 
 This function just hands off the work to the normal Octave @code{polyval}
-function.  Another interesting example for an overloaded function for our
+function.  Another interesting example of an overloaded function for the
 polynomial class is the @code{plot} function.
 
 @example
@@ -432,14 +425,14 @@
 @end example
 
 @noindent
-which allows polynomials to be plotted in the domain near the region
-of the roots of the polynomial.
+which allows polynomials to be plotted in the domain near the region of the
+roots of the polynomial.
 
-Functions that are of particular interest to be overloaded are the class
-conversion functions such as @code{double}.  Overloading these functions
-allows the @code{cast} function to work with the user class and can aid
-in the use of methods of other classes with the user class.  An example
-@code{double} function for our polynomial class might look like.
+Functions that are of particular interest for overloading are the class
+conversion functions such as @code{double}.  Overloading these functions allows
+the @code{cast} function to work with a user class and can aid in the use of
+methods of other classes with the user class.  An example @code{double}
+function for the polynomial class might look like
 
 @example
 @group
@@ -601,7 +594,7 @@
 @caption{Available overloaded operators and their corresponding class method}
 @end float
 
-An example @code{mtimes} method for our polynomial class might look like
+An example @code{mtimes} method for the polynomial class might look like
 
 @example
 @group
@@ -612,18 +605,18 @@
 @node Precedence of Objects
 @subsection Precedence of Objects
 
-Many functions and operators take two or more arguments and so the
-case can easily arise that these functions are called with objects of
-different classes.  It is therefore necessary to determine the precedence
-of which method of which class to call when there are mixed objects given
-to a function or operator.  To do this the @code{superiorto} and
-@code{inferiorto} functions can be used
+Many functions and operators take two or more arguments and so the situation
+can easily arise that these functions are called with objects of different
+classes.  It is therefore necessary to determine the precedence of which method
+of which class to call when there are mixed objects given to a function or
+operator.  To do this the @code{superiorto} and @code{inferiorto} functions can
+be used
 
 @DOCSTRING(superiorto)
 
 @DOCSTRING(inferiorto)
 
-For example with our polynomial class consider the case
+For example with the polynomial class consider the case
 
 @example
 2 * polynomial ([1, 0, 1]);
@@ -631,41 +624,40 @@
 
 @noindent
 That mixes an object of the class @qcode{"double"} with an object of the class
-@qcode{"polynomial"}.  In this case we like to ensure that the return type of
-the above is of the type @qcode{"polynomial"} and so we use the
-@code{superiorto} function in the class constructor.  In particular our
-polynomial class constructor would be modified to be
+@qcode{"polynomial"}.  In this case the return type should be
+@qcode{"polynomial"} and so the @code{superiorto} function is used in the class
+constructor.  In particular the polynomial class constructor would be modified
+to
 
 @example
 @EXAMPLEFILE(@polynomial/polynomial_superiorto.m)
 @end example
 
-Note that user classes always have higher precedence than built-in
-Octave types.  So in fact marking our polynomial class higher than the
-@qcode{"double"} class is in fact not necessary.
+Note that user classes always have higher precedence than built-in Octave
+types.  Thus, marking the polynomial class higher than the @qcode{"double"}
+class is not actually necessary.
 
-When faced with two objects that have the same precedence, Octave will use the
-method of the object that appears first on the list of arguments.
+When confronted with two objects with equal precedence, Octave will use the
+method of the object that appears first in the list of arguments.
 
 @node Inheritance and Aggregation
 @section Inheritance and Aggregation
 
-Using classes to build new classes is supported by octave through the
-use of both inheritance and aggregation.
+Using classes to build new classes is supported by octave through the use of
+both inheritance and aggregation.
 
-Class inheritance is provided by octave using the @code{class}
-function in the class constructor.  As in the case of the polynomial
-class, the octave programmer will create a struct that contains the
-data fields required by the class, and then call the class function to
-indicate that an object is to be created from the struct.  Creating a
-child of an existing object is done by creating an object of the
-parent class and providing that object as the third argument of the
-class function.
+Class inheritance is provided by octave using the @code{class} function in the
+class constructor.  As in the case of the polynomial class, the Octave
+programmer will create a structure that contains the data fields required by
+the class, and then call the class function to indicate that an object is to be
+created from the structure.  Creating a child of an existing object is done by
+creating an object of the parent class and providing that object as the third
+argument of the class function.
 
-This is easily demonstrated by example.  Suppose the programmer needs
-an FIR filter, i.e., a filter with a numerator polynomial but a unity
-denominator polynomial.  In traditional octave programming, this would
-be performed as follows.
+This is most easily demonstrated by example.  Suppose the programmer needs a
+FIR filter, i.e., a filter with a numerator polynomial but a unity denominator
+polynomial.  In traditional Octave programming this would be performed as
+follows.
 
 @example
 @group
@@ -675,36 +667,36 @@
 @end group
 @end example
 
-The equivalent class could be implemented in a class directory
-@@FIRfilter that is on the octave path.  The constructor is a file
-FIRfilter.m in the class directory.
+The equivalent class could be implemented in a class directory @@FIRfilter that
+is on the Octave path.  The constructor is a file @file{FIRfilter.m} in the
+class directory.
 
 @example
 @EXAMPLEFILE(@FIRfilter/FIRfilter.m)
 @end example
 
-As before, the leading comments provide command-line documentation for
-the class constructor.  This constructor is very similar to the
-polynomial class constructor, except that we pass a polynomial object
-as the third argument to the class function, telling octave that the
-FIRfilter class will be derived from the polynomial class.  Our FIR
-filter does not have any data fields, but we must provide a struct to
-the @code{class} function.  The @code{class} function will add an
-element named polynomial to the object struct, so we simply add a
-dummy element named polynomial as the first line of the constructor.
-This dummy element will be overwritten by the class function.
+As before, the leading comments provide documentation for the class
+constructor.  This constructor is very similar to the polynomial class
+constructor, except that a polynomial object is passed as the third argument to
+the @code{class} function, telling Octave that the FIRfilter class will be
+derived from the polynomial class.  The FIR filter does not have any data
+fields, but it must provide a struct to the @code{class} function.  The
+@code{class} function will add an element named polynomial to the object
+struct, so in this case a dummy element named polynomial is created as the
+first line of the constructor.  This dummy element will be overwritten by the
+@code{class} function.
 
-Note further that all our examples provide for the case in which no
-arguments are supplied.  This is important since octave will call the
-constructor with no arguments when loading objects from save files to
-determine the inheritance structure.
+Note that all of the sample code provide for the case in which no arguments are
+supplied.  This is important because Octave will call the constructor with no
+arguments when loading objects from saved files in order to determine the
+inheritance structure.
 
-A class may be a child of more than one class (see the documentation
-for the @code{class} function), and inheritance may be nested.  There
-is no limitation to the number of parents or the level of nesting
-other than memory or other physical issues.
+A class may be a child of more than one class (see the documentation for the
+@code{class} function), and inheritance may be nested.  There is no limitation
+to the number of parents or the level of nesting other than memory or other
+physical issues.
 
-As before, we need a @code{display} method.  A simple example might be
+As before, a class requires a @code{display} method.  A simple example might be
 
 @example
 @group
@@ -712,12 +704,12 @@
 @end group
 @end example
 
-Note that we have used the polynomial field of the struct to display
-the filter coefficients.
+Note that the polynomial field of the struct is used to display the filter
+coefficients.
 
-Once we have the class constructor and display method, we may create
-an object by calling the class constructor.  We may also check the
-class type and examine the underlying structure.
+Once a constructor and display method exist, it is possible to create an
+instance of the class.  It is also possible to check the class type and examine
+the underlying structure.
 
 @example
 @group
@@ -737,11 +729,11 @@
 @end group
 @end example
 
-We only need to define a method to actually process data with our
-filter and our class is usable.  It is also useful to provide a means
-of changing the data stored in the class.  Since the fields in the
-underlying struct are private by default, we could provide a mechanism
-to access the fields.  The @code{subsref} method may be used for both.
+The only thing remaining to make this class usable is a method for processing
+data.  However, it is desirable to also have a way of changing the data stored
+in the class.  Since the fields in the underlying struct are private by
+default, it is necessary to provide a mechanism to access the fields.  The
+@code{subsref} method may be used for both tasks.
 
 @example
 @EXAMPLEFILE(@FIRfilter/subsref.m)
@@ -775,9 +767,9 @@
 @end group
 @end example
 
-In order to change the contents of the object, we need to define a
-@code{subsasgn} method.  For example, we may make the polynomial field
-publicly writable.
+In order to change the contents of the object a @code{subsasgn} method is
+needed.  For example, the following code makes the polynomial field publicly
+writable
 
 @example
 @group
@@ -785,25 +777,27 @@
 @end group
 @end example
 
-So that
+@noindent
+so that
 
 @example
 @group
-octave:6> f = FIRfilter ();
-octave:7> f.polynomial = polynomial ([1 2 3]);
+octave:1> f = FIRfilter ();
+octave:2> f.polynomial = polynomial ([1 2 3])
 f.polynomial = 1 + 2 * X + 3 * X ^ 2
 @end group
 @end example
 
-Defining the FIRfilter class as a child of the polynomial class
-implies that and FIRfilter object may be used any place that a
-polynomial may be used.  This is not a normal use of a filter, so that
-aggregation may be a more sensible design approach.  In this case, the
-polynomial is simply a field in the class structure.  A class
-constructor for this case might be
+Defining the FIRfilter class as a child of the polynomial class implies that
+a FIRfilter object may be used any place that a polynomial object may be used.
+This is not a normal use of a filter.  It may be a more sensible design
+approach to use aggregation rather than inheritance.  In this case, the
+polynomial is simply a field in the class structure.  A class constructor for
+the aggregation case might be
 
 @example
 @EXAMPLEFILE(@FIRfilter/FIRfilter_aggregation.m)
 @end example
 
-For our example, the remaining class methods remain unchanged.
+For this example the other class methods remain unchanged.
+