1Using objects
2
3    Objects are user-defined types which are associated with user-
4    defined functions to manipulate them.  Object types are defined
5    similarly to structures in C, and consist of one or more elements.
6    The advantage of an object is that the user-defined routines are
7    automatically called by the calculator for various operations,
8    such as addition, multiplication, and printing.  Thus they can be
9    manipulated by the user as if they were just another kind of number.
10
11    An example object type is "surd", which represents numbers of the form
12
13	    a + b*sqrt(D),
14
15    where D is a fixed integer, and 'a' and 'b' are arbitrary rational
16    numbers.  Addition, subtraction, multiplication, and division can be
17    performed on such numbers, and the result can be put unambiguously
18    into the same form.	 (Complex numbers are an example of surds, where
19    D is -1.)
20
21    The "obj" statement defines either an object type or an actual
22    variable of that type.  When defining the object type, the names of
23    its elements are specified inside of a pair of braces.  To define
24    the surd object type, the following could be used:
25
26	    obj surd {a, b};
27
28    Here a and b are the element names for the two components of the
29    surd object.  An object type can be defined more than once as long
30    as the number of elements and their names are the same.
31
32    When an object is created, the elements are all defined with zero
33    values.  A user-defined routine should be provided which will place
34    useful values in the elements.  For example, for an object of type
35    'surd', a function called 'surd' can be defined to set the two
36    components as follows:
37
38	    define surd(a, b)
39	    {
40		    local x;
41
42		    obj surd x;
43		    x.a = a;
44		    x.b = b;
45		    return x;
46	    }
47
48    When an operation is attempted for an object, user functions with
49    particular names are automatically called to perform the operation.
50    These names are created by concatenating the object type name and
51    the operation name together with an underscore.  For example, when
52    multiplying two objects of type surd, the function "surd_mul" is
53    called.
54
55    The user function is called with the necessary arguments for that
56    operation.	For example, for "surd_mul", there are two arguments,
57    which are the two numbers.	The order of the arguments is always
58    the order of the binary operands.  If only one of the operands to
59    a binary operator is an object, then the user function for that
60    object type is still called.  If the two operands are of different
61    object types, then the user function that is called is the one for
62    the first operand.
63
64    The above rules mean that for full generality, user functions
65    should detect that one of their arguments is not of its own object
66    type by using the 'istype' function, and then handle these cases
67    specially.	In this way, users can mix normal numbers with object
68    types.  (Functions which only have one operand don't have to worry
69    about this.)  The following example of "surd_mul" demonstrates how
70    to handle regular numbers when used together with surds:
71
72	    define surd_mul(a, b)
73	    {
74		    local x;
75
76		    obj surd x;
77		    if (!istype(a, x)) {
78			    /* a not of type surd */
79			    x.a = b.a * a;
80			    x.b = b.b * a;
81		    } else if (!istype(b, x)) {
82			    /* b not of type surd */
83			    x.a = a.a * b;
84			    x.b = a.b * b;
85		    } else {
86			    /* both are surds */
87			    x.a = a.a * b.a + D * a.b * b.b;
88			    x.b = a.a * b.b + a.b * b.a;
89		    }
90		    if (x.b == 0)
91			    return x.a; /* normal number */
92		    return x;		/* return surd */
93	    }
94
95    In order to print the value of an object nicely, a user defined
96    routine can be provided.  For small amounts of output, the print
97    routine should not print a newline.	 Also, it is most convenient
98    if the printed object looks like the call to the creation routine.
99    For output to be correctly collected within nested output calls,
100    output should only go to stdout.  This means use the 'print'
101    statement, the 'printf' function, or the 'fprintf' function with
102    'files(1)' as the output file.  For example, for the "surd" object:
103
104	    define surd_print(a)
105	    {
106		    print "surd(" : a.a : "," : a.b : ")" : ;
107	    }
108
109    It is not necessary to provide routines for all possible operations
110    for an object, if those operations can be defaulted or do not make
111    sense for the object.  The calculator will attempt meaningful
112    defaults for many operations if they are not defined.  For example,
113    if 'surd_square' is not defined to square a number, then 'surd_mul'
114    will be called to perform the squaring.  When a default is not
115    possible, then an error will be generated.
116
117    Please note: Arguments to object functions are always passed by
118    reference (as if an '&' was specified for each variable in the call).
119    Therefore, the function should not modify the parameters, but should
120    copy them into local variables before modifying them.  This is done
121    in order to make object calls quicker in general.
122
123    The double-bracket operator can be used to reference the elements
124    of any object in a generic manner.	When this is done, index 0
125    corresponds to the first element name, index 1 to the second name,
126    and so on.	The 'size' function will return the number of elements
127    in an object.
128
129    The following is a list of the operations possible for objects.
130    The 'xx' in each function name is replaced with the actual object
131    type name.	This table is displayed by the 'show objfunctions' command.
132
133	    Name	Args	Comments
134
135	    xx_print    1	print value, default prints elements
136	    xx_one      1	multiplicative identity, default is 1
137	    xx_test     1	logical test (false,true => 0,1),
138				  default tests elements
139	    xx_add      2
140	    xx_sub      2
141	    xx_neg      1	negative
142	    xx_mul      2
143	    xx_div      2	non-integral division
144	    xx_inv      1	multiplicative inverse
145	    xx_abs      2	absolute value within given error
146	    xx_norm     1	square of absolute value
147	    xx_conj     1	conjugate
148	    xx_pow      2	integer power, default does multiply,
149				  square, inverse
150	    xx_sgn      1	sign of value (-1, 0, 1)
151	    xx_cmp      2	equality (equal,nonequal => 0,1),
152				   default tests elements
153	    xx_rel      2	relative order, positive for >, etc.
154	    xx_quo      3	integer quotient
155	    xx_mod      3	remainder of division
156	    xx_int      1	integer part
157	    xx_frac     1	fractional part
158	    xx_inc      1	increment, default adds 1
159	    xx_dec      1	decrement, default subtracts 1
160	    xx_square   1	default multiplies by itself
161	    xx_scale    2	multiply by power of 2
162	    xx_shift    2	shift left by n bits (right if negative)
163	    xx_round    3	round to given number of decimal places
164	    xx_bround   3	round to given number of binary places
165	    xx_root     3	root of value within given error
166	    xx_sqrt     3	square root within given error
167	    xx_or       2	bitwise or
168	    xx_and      2	bitwise and
169	    xx_not      1	logical not
170	    xx_fact     1	factorial or postfix !
171	    xx_min      1	value for min(...)
172	    xx_max      1	value for max(...)
173	    xx_sum      1	value for sum(...)
174	    xx_assign   2	assign, defaults to a = b
175	    xx_xor      2	value for binary ~
176	    xx_comp     1	value for unary ~
177	    xx_content  1	unary hash op
178	    xx_hashop   2	binary hash op
179	    xx_backslash 1	unary backslash op
180	    xx_setminus 2	binary backslash op
181	    xx_plus     1	unary + op
182
183    Also see the standard resource files:
184
185	    deg.cal
186	    dms.cal
187	    ellip.cal
188	    hms.cal
189	    mod.cal
190	    natnumset.cal
191	    poly.cal
192	    quat.cal
193	    regress.cal
194	    set8700.cal
195	    surd.cal
196	    test2300.cal
197	    test3100.cal
198
199## Copyright (C) 1999,2010,2021  Landon Curt Noll
200##
201## Calc is open software; you can redistribute it and/or modify it under
202## the terms of the version 2.1 of the GNU Lesser General Public License
203## as published by the Free Software Foundation.
204##
205## Calc is distributed in the hope that it will be useful, but WITHOUT
206## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
207## or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU Lesser General
208## Public License for more details.
209##
210## A copy of version 2.1 of the GNU Lesser General Public License is
211## distributed with calc under the filename COPYING-LGPL.  You should have
212## received a copy with calc; if not, write to Free Software Foundation, Inc.
213## 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
214##
215## Under source code control:	1991/07/21 04:37:22
216## File existed as early as:	1991
217##
218## chongo <was here> /\oo/\	http://www.isthe.com/chongo/
219## Share and enjoy!  :-)	http://www.isthe.com/chongo/tech/comp/calc/
220