Add overload.input ======================================================================= diff --git a/changelog b/changelog index 377aa85..fc15048 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,5 @@ +20080819 tpd src/input/Makefile overload.input added +20080819 dxc src/input/overload.input added 20080818 tpd src/input/Makefile biquat.input added 20080818 dxc src/input/biquat.input added 20080818 dxc "David Cyganski" (no known email) diff --git a/src/input/Makefile.pamphlet b/src/input/Makefile.pamphlet index 0d919d6..1c2fa8e 100644 --- a/src/input/Makefile.pamphlet +++ b/src/input/Makefile.pamphlet @@ -341,6 +341,7 @@ REGRES= algaggr.regress algbrbf.regress algfacob.regress alist.regress \ nqip.regress nsfip.regress numbers.regress octonion.regress \ oct.regress ode.regress odpol.regress op1.regress \ opalg.regress operator.regress op.regress ovar.regress \ + overload.regress \ padic.regress parabola.regress pascal1.regress pascal.regress \ patch51.regress page.regress \ patmatch.regress pat.regress perman.regress perm.regress \ @@ -613,10 +614,10 @@ FILES= ${OUT}/algaggr.input ${OUT}/algbrbf.input ${OUT}/algfacob.input \ ${OUT}/nepip.input ${OUT}/newton.input \ ${OUT}/nlode.input ${OUT}/none.input ${OUT}/noonburg.input \ ${OUT}/noptip.input ${OUT}/nqip.input ${OUT}/nsfip.input \ - ${OUT}/ntube.input ${OUT}/oct.input ${OUT}/ode.input \ + ${OUT}/ntube.input ${OUT}/oct.input ${OUT}/ode.input \ ${OUT}/octonion.input ${OUT}/odpol.input \ ${OUT}/opalg.input ${OUT}/operator.input ${OUT}/op.input \ - ${OUT}/op1.input ${OUT}/ovar.input \ + ${OUT}/op1.input ${OUT}/ovar.input ${OUT}/overload.input \ ${OUT}/padic.input ${OUT}/palette.input \ ${OUT}/parpcurv.input ${OUT}/parscurv.input ${OUT}/parsurf.input \ ${OUT}/pascal1.input \ @@ -927,6 +928,7 @@ DOCFILES= \ ${DOC}/odpol.input.dvi ${DOC}/op1.input.dvi \ ${DOC}/opalg.input.dvi ${DOC}/operator.input.dvi \ ${DOC}/op.input.dvi ${DOC}/ovar.input.dvi \ + ${DOC}/overload.input.dvi \ ${DOC}/padic.input.dvi ${DOC}/palette.input.dvi \ ${DOC}/parabola.input.dvi ${DOC}/parpcurv.input.dvi \ ${DOC}/parscurv.input.dvi ${DOC}/parsurf.input.dvi \ diff --git a/src/input/overload.input.pamphlet b/src/input/overload.input.pamphlet new file mode 100644 index 0000000..2db85a7 --- /dev/null +++ b/src/input/overload.input.pamphlet @@ -0,0 +1,680 @@ +\documentclass{article} +\usepackage{axiom} +\begin{document} +\title{\$SPAD/src/input overload.input} +\author{David Cyganski} +\maketitle +\begin{abstract} +Type conversion and overload problems +\end{abstract} +\eject +\tableofcontents +\eject +<<*>>= +)spool overload.output +)set message test on +)set message auto off +)clear all +@ +\section{Type Conversion and Overload problems} +Several non-intuitive problems with overloading and type conversions +arose while developing the biquaternion (see biquat.input) support +function collection. I have extracted the minimum code set to illustrate +each of these problems. + +\section{Implicit and Explicit Type Conversions} +We begin by illustrating function calling with variously typed +arguments and conversion which we will break in various ways, some +understandable, some not(?), below. + +The cos function will produce float outcomes for float arguments +<<*>>= + +--S 1 of 28 +cos(1.237) +--R +--R +--R (1) 0.3276321705 9891498386 +--R Type: Float +--E 1 + +@ +can handle expressions that mix floats and integers +<<*>>= + +--S 2 of 28 +cos(1.237/2) +--R +--R +--R (2) 0.8147490934 6341557739 +--R Type: Float +--E 2 + +@ +but will respect an integer expression, as we would want it to, +by not evaluating +<<*>>= + +--S 3 of 28 +cos(2/3) +--R +--R +--R 2 +--R (3) cos(-) +--R 3 +--R Type: Expression Integer +--E 3 + +@ +We can coerce the evaluation as a float by forcing the floating point +evaluation of the division and typing of the outcome in a variety of +ways. Each of the following forms is effective in some appropriate +and understandable way. Some act explicitly on the ``/'' operator +to force a polymorphic choice, others convert the type of the second +constand in each expression which results in a proper implicit selection +of which ``/'' definitition to use. +<<*>>= + +--S 4 of 28 +cos(2/3::Float) +--R +--R +--R (4) 0.7858872607 7694800072 +--R Type: Float +--E 4 + +--S 5 of 28 +cos((2/3)::Float) +--R +--R +--R (5) 0.7858872607 7694800072 +--R Type: Float +--E 5 + +--S 6 of 28 +cos(2/3$Float) +--R +--R +--R (6) 0.7858872607 7694800072 +--R Type: Float +--E 6 + +--S 7 of 28 +cos((2/3)$Float) +--R +--R +--R (7) 0.7858872607 7694800072 +--R Type: Float +--E 7 + +--S 8 of 28 +cos(2/[EMAIL PROTECTED]) +--R +--R +--R (8) 0.7858872607 7694800072 +--R Type: Float +--E 8 + +--S 9 of 28 +cos((2/3)@Float) +--R +--R +--R (9) 0.7858872607 7694800072 +--R Type: Float +--E 9 + +@ +But, as we would expect, it is too late to attempt coercion after the +fact. Coercion operates ``on the surface and not deeply'' as illustrated +here. +<<*>>= + +--S 10 of 28 +cos(2/3)::Float +--R +--R +--RDaly Bug +--R Cannot convert from type Expression Integer to Float for value +--R 2 +--R cos(-) +--R 3 +--R +--E 10 + +@ +However, there is a real need for a deep coercion operator that operates +on the innermost atomic constants. Suppose we define +<<*>>= + +--S 11 of 28 +cosf(x:Expression Integer):Expression Integer == 1+cos(x/2) +--R +--R Function declaration cosf : Expression Integer -> Expression Integer +--R has been added to workspace. +--R Type: Void +--E 11 + +@ +which is an example of a simple function that might be defined in the +course of typical work. We wish to declare functions as having integer +based fractions, rather than forming approximate decimal expansions, which +is preferred for purposes of analytic examination and simplification for +both the human and the Axiom system. The Axiom book and online resources +are full of examples in which this choice has been made by the authors +thanks to the power of this form of expression -- even though it amounts +to lying to Axiom in many cases as to the ultimate destiny of the function +being defined. But woe to us if we wish later to evaluate it in a more +general way because it is a tangled web we weave when we practice to +decieve. +<<*>>= + +--S 12 of 28 +cosf(2/3) +--R +--R Compiling function cosf with type Expression Integer -> Expression +--R Integer +--R +--R 1 +--R (11) cos(-) + 1 +--R 3 +--R Type: Expression Integer +--E 12 + +--S 13 of 28 +cosf((2/3)::Float) +--R +--R Conversion failed in the compiled user function cosf . +--R +--RDaly Bug +--R Cannot convert from type Float to Expression Integer for value +--R 0.6666666666 6666666667 +--R +--E 13 + +@ +Thus in effect once we wrap a function around an integer base definition, +we are stuck and unable to evaluate it as a float later, unlike the core +basic functions that can be used either way. This forces us to choose the +Float type throughout at a loss of comprehensibility and analyzability, +unless we seek to more than double our development type by supplying an +overloaded integer base and Float base version of {\bf every} step of a +sequential development of a formula. + +Bizarrely, the draw function seems to have the power to override the +type problem as shown here +<<*>>= + +--S 14 of 28 +--draw(cosf(x),x=0..15) +--E 14 + +@ +Why can't we grant this deep coercion power to some new form of floating +point conversion operation which can be applied at will? If draw has +this power, why not put it in the hands of the user? + +Alternatively, it would be best to have a {\bf mixed} type -- mixed += Integer/Float. Like Maple expressions it would leave integers as +integers and floats as floats, unmolested and treated as generic +constant quantities with distinguishable parts until an {\bf evalf} +like function that would force them entirely into the Float type. For +example, in Maple ``cos(2/3)+1.2323'' remains as is, while in Axiom +we get +<<*>>= + +--S 15 of 28 +cos(2/3)+1.2323 +--R +--R +--R (12) 2.0181872607 769480007 +--R Type: Expression Float +--E 15 + +@ +In a way, Axiom already has a quantity treated like this -- the constant +%pi is treated as a special float which remains unevaluated and does not +force combination of itself with an Integer. It simply results in a new +kind of Integer evaluation of type Pi +<<*>>= + +--S 16 of 28 +3/4+%pi +--R +--R +--R 4%pi + 3 +--R (13) -------- +--R 4 +--R Type: Pi +--E 16 + +@ +\section{Overloading problems} +Now let's examine properties and problems with overloading. + +Define the type $Q$ of Hamiltonian biquaternions +<<*>>= + +--S 17 of 28 +C:=Complex Expression Integer +--R +--R +--R (14) Complex Expression Integer +--R Type: Domain +--E 17 + +--S 18 of 28 +Q:=Quaternion C +--R +--R +--R (15) Quaternion Complex Expression Integer +--R Type: Domain +--E 18 + +@ +While developing the support functions, this definition of biquat +division was introduced to simplify the format of the formulae +<<*>>= + +--S 19 of 28 +((x:Q)/(y:Q)):Q == x*inv(y) +--R +--R Function declaration ?/? : (Quaternion Complex Expression Integer, +--R Quaternion Complex Expression Integer) -> Quaternion Complex +--R Expression Integer has been added to workspace. +--R Type: Void +--E 19 + +@ +But is this typed function in any way actually restricted to quaternions? +On the face, it would appear all is normal, here's an example of +integer division +<<*>>= + +--S 20 of 28 +x:=15/6 +--R +--R Compiling function / with type (Quaternion Complex Expression +--R Integer,Quaternion Complex Expression Integer) -> Quaternion +--R Complex Expression Integer +--R +--R 5 +--R (17) - +--R 2 +--R Type: Quaternion Complex Expression Integer +--E 20 + +@ +But though the answer was right, the type is now a biquat. If we don't +notice this, and proceed, some things seem still to act normally, +for example, no complaint from Axiom with +<<*>>= + +--S 21 of 28 +cos(x) +--R +--R +--R 5 +--R (18) cos(-) +--R 2 +--R Type: Expression Integer +--E 21 + +@ +Of course, we still get a correct answer with +<<*>>= + +--S 22 of 28 +cos(1.237) +--R +--R +--R (19) 0.3276321705 9891498386 +--R Type: Float +--E 22 + +@ +But let's try to apply this as a simple mixed float/integer function +<<*>>= + +--S 23 of 28 +cos(15.457/6) +--R +--R Conversion failed in the compiled user function / . +--R +--RDaly Bug +--R Cannot convert from type Float to Quaternion Complex Expression +--R Integer for value +--R 15.457 +--R +--E 23 + +@ +Obviously the quaternion version of ``/'' is being invoked despite +mismatches of the arguments and the supposed overloading in effect. +Well, what if we built a new cosine function that forced the form of +the arguments into certain types to avoid mismatch? +<<*>>= + +--S 24 of 28 +c(y:Float):Float == cos(y) +--R +--R Function declaration c : Float -> Float has been added to workspace. +--R Type: Void +--E 24 + +@ +At first this seems to work, we can still evaluate a float +<<*>>= + +--S 25 of 28 +c(1.237) +--R +--R Compiling function c with type Float -> Float +--R +--R (21) 0.3276321705 9891498386 +--R Type: Float +--E 25 + +@ +and we can even get a float answer when we introduce the integer coercible +biquat variable value generated from the above. +<<*>>= + +--S 26 of 28 +c(x) +--R +--R +--R (22) - 0.8011436155 4693371483 +--R Type: Float +--E 26 + +@ +But that was only misdirection, because this breaks down for reasonable +expressions because of the ``/'' operation still not being resolved +correctly. +<<*>>= + +--S 27 of 28 +c(1.237/2) +--R +--R Conversion failed in the compiled user function / . +--R +--RDaly Bug +--R Cannot convert from type Float to Quaternion Complex Expression +--R Integer for value +--R 1.237 +--R +--E 27 + +@ +Rather than complaining about it, what if we tried the various coercions +that served to solve the similar type conversion problem we had when +just dealing with Integer Fraction versus Floats at the top of the page. +Our results are mixed. Recall that each of the following worked in the +previous case, producing the correct floating result in each case. +<<*>>= + +--S 28 of 28 +cos(2/3::Float) +--R +--R +--R 2 +--R (23) cos(-) +--R 3 +--R Type: Expression Integer +--E 28 + +--S 29 of 28 +cos((2/3)::Float) +--R +--R +--R (24) 0.7858872607 7694800072 +--R Type: Float +--E 29 + +--S 30 of 28 +cos(2/3$Float) +--R +--R +--R 2 +--R (25) cos(-) +--R 3 +--R Type: Expression Integer +--E 30 + +--S 31 of 28 +cos((2/3)$Float) +--R +--R +--R (26) 0.7858872607 7694800072 +--R Type: Float +--E 31 + +--S 32 of 28 +cos(2/[EMAIL PROTECTED]) +--R +--R +--R 2 +--R (27) cos(-) +--R 3 +--R Type: Expression Integer +--E 32 + +--S 33 of 28 +cos((2/3)@Float) +--R +--R +--RDaly Bug +--R An expression involving @ Float actually evaluated to one of type +--R Quaternion Complex Expression Integer . Perhaps you should use :: +--R Float . +--E 33 + +@ +Try these examples with our type constrained function, which has better +luck now +<<*>>= + +--S 34 of 28 +c(2/3::Float) +--R +--R +--R (28) 0.7858872607 7694800072 +--R Type: Float +--E 34 + +--S 35 of 28 +c((2/3)::Float) +--R +--R +--R (29) 0.7858872607 7694800072 +--R Type: Float +--E 35 + +--S 36 of 28 +c(2/3$Float) +--R +--R +--R (30) 0.7858872607 7694800072 +--R Type: Float +--E 36 + +--S 37 of 28 +c((2/3)$Float) +--R +--R +--R (31) 0.7858872607 7694800072 +--R Type: Float +--E 37 + +--S 38 of 28 +c(2/[EMAIL PROTECTED]) +--R +--R +--R (32) 0.7858872607 7694800072 +--R Type: Float +--E 38 + +--S 39 of 28 +c((2/3)@Float) +--R +--R +--RDaly Bug +--R An expression involving @ Float actually evaluated to one of type +--R Quaternion Complex Expression Integer . Perhaps you should use :: +--R Float . +--E 39 + +@ +Could the above problems have been avoided by not assigning types +to the function we defined? Let's repeat the entire example with +this single change for the function c2 +<<*>>= + +--S 40 of 28 +c2(y) == cos(y) +--R +--R Type: Void +--E 40 + +--S 41 of 28 +c2(1.237) +--R +--R Compiling function c2 with type Float -> Float +--R +--R (34) 0.3276321705 9891498386 +--R Type: Float +--E 41 + +--S 42 of 28 +c2(x) +--R +--R There are 2 exposed and 6 unexposed library operations named cos +--R having 1 argument(s) but none was determined to be applicable. +--R Use HyperDoc Browse, or issue +--R )display op cos +--R to learn more about the available operations. Perhaps +--R package-calling the operation or using coercions on the arguments +--R will allow you to apply the operation. +--R Cannot find a definition or applicable library operation named cos +--R with argument type(s) +--R Quaternion Complex Expression Integer +--R +--R Perhaps you should use "@" to indicate the required return type, +--R or "$" to specify which version of the function you need. +--R AXIOM will attempt to step through and interpret the code. +--R +--R 5 +--R (35) cos(-) +--R 2 +--R Type: Expression Integer +--E 42 + +@ +But that was only misdirection, because this breaks down for +reasonable expressions +<<*>>= + +--S 43 of 28 +c2(1.237/2) +--R +--R Conversion failed in the compiled user function / . +--R +--RDaly Bug +--R Cannot convert from type Float to Quaternion Complex Expression +--R Integer for value +--R 1.237 +--R +--E 43 + +@ +and various attempts at coercion also fail -- compare these results +to the previous ones +<<*>>= + +--S 44 of 28 +c2(2/3::Float) +--R +--R +--R 2 +--R (36) cos(-) +--R 3 +--R Type: Expression Integer +--E 44 + +--S 45 of 28 +c2((2/3)::Float) +--R +--R +--R (37) 0.7858872607 7694800072 +--R Type: Float +--E 45 + +--S 46 of 28 +c2(2/3$Float) +--R +--R +--R 2 +--R (38) cos(-) +--R 3 +--R Type: Expression Integer +--E 46 + +--S 47 of 28 +c2((2/3)$Float) +--R +--R +--R (39) 0.7858872607 7694800072 +--R Type: Float +--E 47 + +--S 48 of 28 +c2(2/[EMAIL PROTECTED]) +--R +--R +--R 2 +--R (40) cos(-) +--R 3 +--R Type: Expression Integer +--E 48 + +--S 49 of 28 +c2((2/3)@Float) +--R +--R +--RDaly Bug +--R An expression involving @ Float actually evaluated to one of type +--R Quaternion Complex Expression Integer . Perhaps you should use :: +--R Float . +--E 49 + +@ +Lastly, we cannot now use the graph function, draw, on such a function +since the wrong ``/'' function is used, contrary to the bypassing of +internal types we saw take place with draw in the example prior to the +introduction of operator overloading. +<<*>>= + +--S 50 of 28 +--draw(c(x),x=0..15) +--E 50 + +@ +{\sl Not safe at any speed}. Most oddly, the ordinary cos() function which +exposes no ``/'' division Now fails to work with draw despite the fact +that we just saw it above still working with Integer and Float arguments +applied directly. +<<*>>= + +--S 51 of 28 +--draw(cos(x),x=0..15) +--E 51 + +)spool +)lisp (bye) + +@ +\eject +\begin{thebibliography}{99} +\bibitem{1} nothing +\end{thebibliography} +\end{document}
_______________________________________________ Axiom-developer mailing list Axiom-developer@nongnu.org http://lists.nongnu.org/mailman/listinfo/axiom-developer