jlg@lanl.gov (Jim Giles) (09/20/88)
From article <1531@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > This is not true. Just because something in 'C' has the form of a function > does not mean it is forced to be a function: > > getchar() > min()/max() on many machines > feof() > isprint() > This is one of the reasons that C is less portable than Fortran. The set of intrinsic functions is not defined anywhere. I may indeed want to write my own versions of some of the above functions (add pow() to the list). If one implementation allows me to do so, another shouldn't prevent me - unless the standard says that the function is intrinsic - in which case, the implementor is allowed to switch. The present C 'standard' (such as it is) is K&R. K&R doesn't mention any intrinsics as far as I know. As I said before, the ANSI C standard will probably address this issue. >> A secondary objection is that >> exponentiation is a mathematical operation for which mathematicians >> and others have always had (and still expect) a shorthand syntax. > > This syntax is, however, not the one Fortran uses. The mathematical syntax > for exponentiation is actually not displayable in ASCII text. That is _not_ a valid argument for omitting exponentiation as an operator. Subscripting is not expressible in ASCII text either. Yet both Fortran _AND_ C have a syntax for subscripting. I would argue (as I have before) that the syntax for mathemetical operations in a programming language should be as close as possible to the syntax used by the target user community for those same operations. Constraints of the character set and of the compiler may prevent you from getting _exact_ identity with the user's preferred syntax - but you should still try to get close. J. Giles Los Alamos
chris@mimsy.UUCP (Chris Torek) (09/20/88)
>In article <1531@ficc.uu.net> peter@ficc.uu.net (Peter da Silva) writes: >>... Just because something in 'C' has the form of a function >>does not mean it is forced to be a function: >> >> getchar() >> min()/max() on many machines >> feof() >> isprint() [i.e., these are often macros] In article <3748@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >This is one of the reasons that C is less portable than Fortran. The set >of intrinsic functions is not defined anywhere. `Old C' has no intrinsics (in the Fortran definition) to define, hence the second statement is true. The first contains two implications, one of which is true and one of which is, at best, a matter of opinion. C is less portable than it might be: if `getc' is a function, the statement c = getc(files[index++]); works. On other machines, getc() is a macro that evaluates its argument more than once, producing bizarre results. Someone with an implementation of the first sort can write code with embedded side effects and get away with it; that code is not `de facto portable'. >The present C 'standard' (such as it is) is K&R. K&R 1st ed. is too weak a standard: the existing `de facto' standard is much richer, but also more vague. The semantics of `common extensions' to K&R 1 (including such things as the math library) are not particularly well defined, so it is hard to use these `portably'. (All these words are in quotes only because I am not willing to define them here now.) >As I said before, the ANSI C standard will probably address this issue. It does indeed. >>[Mathematical exponentiation] syntax is, however, not the one Fortran >>uses. The mathematical syntax for exponentiation is actually not >>displayable in ASCII text. >That is _not_ a valid argument for omitting exponentiation as an operator. True. >... the syntax for mathemetical operations in a programming language >should be as close as possible to the syntax used by the target user >community for those same operations. I would suggest `^', which not only looks like `go up', but also exists in both ASCII and EBCDIC, and even appears as an up-arrow in old ASCII. (Before some ANSI standard whose exact number I never knew, the characters [ \ ] and ^ were often displayed as four arrows. Some of you may even have four arrows showing on your screens now. Bonus quadrivia points to those who remember which way the arrows went :-) .) Anyway, I happen to believe that intrinsic functions make perfectly good `operators'. (Just another matter of opinion.) (I could ask why Fortran does not have a syntax for min and max operators....) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
peter@ficc.uu.net (Peter da Silva) (09/20/88)
In article <3748@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > From article <1531@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > > This is not true. Just because something in 'C' has the form of a function > > does not mean it is forced to be a function: > > getchar() > > min()/max() on many machines > > feof() > > isprint() > > > This is one of the reasons that C is less portable than Fortran. The set > of intrinsic functions is not defined anywhere. And it shouldn't be. > I may indeed want to write > my own versions of some of the above functions (add pow() to the list). So #undef them. > > This syntax is, however, not the one Fortran uses. The mathematical syntax > > for exponentiation is actually not displayable in ASCII text. > That is _not_ a valid argument for omitting exponentiation as an operator. No, and I'm not saying it is. What I'm saying is that just because something is an operator in mathematics doesn't mean it has to be one in any given programming language. What about integration, differentiation, and so on? There's even a syntax for differentiation that is expressable in ASCII. -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
jlg@lanl.gov (Jim Giles) (09/21/88)
From article <13635@mimsy.UUCP>, by chris@mimsy.UUCP (Chris Torek): >>... the syntax for mathemetical operations in a programming language >>should be as close as possible to the syntax used by the target user >>community for those same operations. > > I would suggest `^', which not only looks like `go up', but also exists Unfortunately, it did _not_ exist on the old 026 keypunches - and _THAT'S_ the origin of the Fortran character set constraints. I agree, `^' is a much better choice. It just wasn't here when it was needed. `**' was chosen as a rather obvious lesser_of_many_evils - it at least suggests _something_ to do with multiplication (which is how most people regard exponentiation). > why Fortran does not have a syntax for min and max operators....) Suggest a standard mathematical notation for min and max which most potential users are familiar with - I wouldn't oppose including it. J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/21/88)
From article <1554@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): >> I may indeed want to write >> my own versions of some of the above functions (add pow() to the list). > > So #undef them. #undef _only_ works on macros. If pow() is not implemented as a macro, #undef will do _nothing_ to it. By the way, if you really believe that intrinsic functions should not be identified as such, you'd better hurry - the ANSI committee is about to define a whole raft of them. It is a good idea though, it helps make code portable (something that C is particularly bad at). > There's even a syntax for differentiation that is expressable in ASCII. And, when differentiation is added to a programming language, the syntax you mention is the one that should be used. J. Giles Los Alamos
d25001@mic.UUCP (Carrington Dixon) (09/21/88)
In article <13635@mimsy.UUCP> chris@mimsy.UUCP (Chris Torek) writes: > >I would suggest `^', which not only looks like `go up', but also exists >in both ASCII and EBCDIC, and even appears as an up-arrow in old >ASCII. I don't think so. There is certainly no "^" character on any 3270-type keyboard that I have ever used, and I cannot find a "^" character on any copy of the familiar IBM "System/370 Reference Summary" that I have. "Shift-6" (the usual location of "^") is the EBCDIC NOT sign (sort of a hyphen with a tail). Carrington Dixon UUCP: { convex, killer }!mic!d25001
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/21/88)
In article <3907@lanl.gov> jlg@lanl.gov (Jim Giles) writes: > >By the way, if you really believe that intrinsic functions should not be >identified as such, you'd better hurry - the ANSI committee is about to >define a whole raft of them. It is a good idea though, it helps make >code portable (something that C is particularly bad at). > 1) an intrinsic function is one the compiler knows something about so that it can perform kicky optimizations like in line expansion. A function does not have to be intrinsic to aid portability. It need only be required by the standard committe. A library implementation is perfectly acceptable. If I understand correctly which ANSI committee you are refering to (C?) The proposal is *not* for intrinsic functions, but for required library functions. Implementation left to the implementer. 2) If a function is part of a library, rather than generated by the compiler, it become a matter of loader sophistication to override the standard version with my own version. All I need is away to specify the order in which the loader locates globals, and an override on "multiply defined" 'errors.' 3) C is not 'particularly bad at portable code.' I have written 100s of K lines of code in C, Pascal, and Fortran. Each has problems with portability. For the kind of code I've written, ([parts of ] operating systems, compilers, data base packages, graphics, and some largish numerical codes) and the kind of porting I've had to do, C has been much easier to deal with than either of the others. Your milage will vary, but there isn't really anything inherent in any of the languages that make it hard to write portable code. Or not. (During the mid 70's, I made quite a bit of lose change as a consultant moving Fortran between IBM, DEC, Xerox and CDC machines. I can tell you incredible horror stories about Fortran portability problems which *still* haven't been fixed. Particularly in i/o, but also in other areas.) +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
ok@quintus.uucp (Richard A. O'Keefe) (09/21/88)
In article <3823@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >Suggest a standard mathematical notation for min and max which most >potential users are familiar with - I wouldn't oppose including it. Depends on how you define "most potential users". The notation I know and like is min= /\, max= \/, which is what's normally used for lattices. (If you use the usual ordering .FALSE. < .TRUE. they even work nicely as logical operators, P/\Q = P.AND.Q .)
peter@ficc.uu.net (Peter da Silva) (09/21/88)
In article <3907@lanl.gov>, jlg@lanl.gov (Jim Giles) writes: > From article <1554@ficc.uu.net>, by peter@ficc.uu.net (Peter da Silva): > >> I may indeed want to write > >> my own versions of some of the above functions (add pow() to the list). > > So #undef them. > #undef _only_ works on macros. If pow() is not implemented as a macro, > #undef will do _nothing_ to it. If pow() is not defined as a macro, it's not intrinsic. See below. > By the way, if you really believe that intrinsic functions should not be > identified as such, you'd better hurry - the ANSI committee is about to > define a whole raft of them. It is a good idea though, it helps make > code portable (something that C is particularly bad at). They're defining functions that can be made instrinsic by including a header file that #defines them to something like __INTRINSIC_func__. If you don't want the intrinsic version, you #undef them. It doesn't require either that they be made intrinsic nor that people assume they are. > > There's even a syntax for differentiation that is expressable in ASCII. > And, when differentiation is added to a programming language, the syntax > you mention is the one that should be used. Anyone know what syntax Macsyma uses to indicate differentiation. By the way all this talk of operators and mathematics... what about division? -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net
jlg@lanl.gov (Jim Giles) (09/22/88)
From article <1028@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): > which ANSI committee you are refering to (C?) The proposal is *not* > for intrinsic functions, but for required library functions. > Implementation left to the implementer. Look again. There are a number of functions which the committee says the processor is allowed to optimize or expand in-line. The rationale document recommends that the in-line expansion be passed to the processor as a macro in one of the default includes - but (as far as I know) this is not the _required_ way of in-line expansion. Furthermore, if implementation were left to the implementor, _many_ functions would be implemented by the compiler - they're easier to do that way (if you really want them to be optimized). If I were writing a C compiler, I would certainly do pow() in-line. What you claim is that the ANSI C committee is listing a group of required functions and that these are _required_ to be implemented in a library form. I don't think this is true. J. Giles Los Alamos
jlg@lanl.gov (Jim Giles) (09/22/88)
From article <457@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> they even work nicely as logical operators, P/\Q = P.AND.Q .)
Yes I am presently designing a language in which \/ is OR and /\ is
AND. It's too bad about lattice theorists using these symbols for
max and min, but the majority of my target users are into latices
(some of them are though - so like I said, it's too bad).
J. Giles
Los Alamos
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/22/88)
In article <3957@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >From article <1028@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): >> which ANSI committee you are refering to (C?) The proposal is *not* >> for intrinsic functions, but for required library functions. >> Implementation left to the implementer. > >Look again. There are a number of functions which the committee says >the processor is allowed to optimize or expand in-line. The rationale >document recommends that the in-line expansion be passed to the processor >as a macro in one of the default includes - but (as far as I know) this >is not the _required_ way of in-line expansion. > Err, the draft standard actually allows in-line expansion of any known function, including user defined functions, provided certain rules (which I don't remember) are followed. It also requires that this be overridable. GNU C and G++ (Gnu C++), for example, already have this ability as a user option. It is an attempt to give the (definitely justifable) advantages of intrinsics while maintaining the ability to override. >Furthermore, if implementation were left to the implementor, _many_ >functions would be implemented by the compiler - they're easier to do >that way (if you really want them to be optimized). Well, maybe. When I'm implementing a compiler, I try to stay as far away from knowing semantics of called routines as possible, because the techniques I use are easier to implement if they discover the semantics on the fly than if they carry them around as imbedded knowledge. (Easier, but more expensive, when the semantics never change, which is rarely.) > If I were writing >a C compiler, I would certainly do pow() in-line. What you claim is that >the ANSI C committee is listing a group of required functions and that >these are _required_ to be implemented in a library form. I don't think >this is true. > No. I did not claim that the functions are _required_ to be implemented as libraries. You are deliberately confusing the converse and inverse of a statement. I claimed that the functions are required to be present, and that the mechanism of implementation was undefined. They may be implemented by inline generation by a knowledgable compiler, by macros in standard headers (provided side effects are correctly handled), or by libraries. My reading of the draft shows any of these to be allowed; provided that in all cases the user is allowed to override the standard version with a private version. Inline code generation is an allowable substitution in any event, provided the compiler can correctly determine that the substitution produces a semantically equivalent executable. Hopefully it is only ever done as a space/time tradeoff optimization. (Creon Levit says: "Oh yeah, the old space/time tradeoff. Takes more space and more time.) +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
jlg@lanl.gov (Jim Giles) (09/22/88)
From article <1031@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): > [...] My reading of the draft shows > any of these to be allowed; provided that in all cases the user is > allowed to override the standard version with a private version. Yes, but the method of overriding the standard version is different for each of the implementation methods that you mention. This means that a code which really does override a standard procedure definition will not be portable. It is this lack of portability that I object to. By the way, you said you liked your optimizer to figure out a new semantics for itself rather than coding it into the compiler. This works just fine if the information required for the optimizer to do it's work can be gleaned from the code skeletons or macros that define the new feature. If not (as in the case of complex numbers, for example) the method of modifying the compiler will usually produce better code that one which is extended by the other mechanisms. For example, if I have a bunch of macros that define SINE and COSINE functions (how to evaluate), I still won't be able to optimize SIN(x)*SIN(x)+COS(x)*COS(x) as well as a compiler could do if it had the semantics of trig functions built-in (the optimal evaluation strategy is to replace the whole expression with the constant 1). J. Giles Los Alamos
dodson@mozart.uucp (Dave Dodson) (09/22/88)
In article <3957@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >If I were writing a C compiler, I would certainly do pow() in-line. Considering the complexity and length of a properly written pow() routine, it does not appear to me to be practical for the compiler to in-line it. It is not adequate to evaluate pow(x,y) as exp(y*log(x)) unless additional precision is used. See "Software Manual for the Elementary Functions" by Cody and Waite, for a description of an appropriate algorithm. ---------------------------------------------------------------------- Dave Dodson {uiucdcs,sun,uunet,harvard,killer,usenix}!convex!dodson Convex Computer Corporation Richardson, Texas (214) 952-0234
fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts) (09/22/88)
In article <3976@lanl.gov> jlg@lanl.gov (Jim Giles) writes: >From article <1031@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): >> [...] My reading of the draft shows >> any of these to be allowed; provided that in all cases the user is >> allowed to override the standard version with a private version. > > >Yes, but the method of overriding the standard version is different for >each of the implementation methods that you mention. This means that >a code which really does override a standard procedure definition will >not be portable. It is this lack of portability that I object to. > Hmm. Good point. I agree. >[comment on my comment about not wanting the compiler to know semantics in advance . . .], I still >won't be able to optimize SIN(x)*SIN(x)+COS(x)*COS(x) as well as a compiler >could do if it had the semantics of trig functions built-in (the optimal >evaluation strategy is to replace the whole expression with the constant 1). > This is true, but only accurate when the expression evaluates to a constant. You couldn't (because of finite precision) replace 1-COS(X)*COS(X) with SIN(x)*SIN(x) and guarentee the same results. Although, if you can determine at compile time that COS is deterministic in X then you can replace 1-COS(X)*COS(X) with (t=COS(X),1=t*t) The case that evaluates to another function is much more common than the case that evaluates to a constant. For now, I'm willing to give up the occasional constant-replacement win for the optimizations I can get by concentrating on manipulating on the fly knowledge, and leave the level of algabric sophistication that you are contemplating to Macsyma, Mathematic, et al. Eventually, I want the optimizer for my language to be two optimizers. The first one should be Knuth's "program rewritter" which rewrites my program in my source language making substitutions such as the above. This one should mostly be an algebraic rewriting system and should be concerned only with the kind of transformations that your example represent. The second one would do only the optimizations that can't/shouldn't be done at the source level such as strength reduction and cse on adress arithmentic. It would be part of the compiler. [Knuth wanted the program rewritter to be interactive - asking if it was OK to apply various transformations. Pacific Sierra Research has done a product along these lines for vectorizing Fortran called Forge.] Marty +-+-+-+ I don't know who I am, why should you? +-+-+-+ | fouts@lemming.nas.nasa.gov | | ...!ames!orville!fouts | | Never attribute to malice what can be | +-+-+-+ explained by incompetence. +-+-+-+
jlg@lanl.gov (Jim Giles) (09/23/88)
From article <1033@amelia.nas.nasa.gov>, by fouts@lemming.nas.nasa.gov.nas.nasa.gov (Marty Fouts): > This is true, but only accurate when the expression evaluates to a > constant. You couldn't (because of finite precision) replace > 1-COS(X)*COS(X) with SIN(x)*SIN(x) and guarentee the same results. True, but Fortran would allow this anyway since optimized expressions need only to be mathematically identical, not computationally identical (see section 6.6 of the standard). > that you are contemplating to Macsyma, Mathematic, et al. ^ That's Mathematica. And I agree. I have long wanted to write the mathematics preprocessor that Knuth talks about. In fact, I want a more powerful system which could take (for example) a set of differential equations and a 3-d initial geometrical set-up and automatically generate a Fortran code which efficiently runs a finite differencing technique on the problem. J. Giles Los Alamos
ok@quintus.uucp (Richard A. O'Keefe) (09/23/88)
In article <3960@lanl.gov> jlg@lanl.gov (Jim Giles) writes:
:From article <457@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
:> they even work nicely as logical operators, P/\Q = P.AND.Q .)
:Yes I am presently designing a language in which \/ is OR and /\ is
:AND. It's too bad about lattice theorists using these symbols for
:max and min, but the majority of my target users are into latices
:(some of them are though - so like I said, it's too bad).
I don't understand why it's "too bad". My point was that the use of
/\ for minimum and \/ for maximum is CONSISTENT with their use for
.AND. and .OR.; the conventional lattice representation of the logical
values is .FALSE. = 0, .TRUE. = 1, .AND. = /\, .OR. = \/.
jlg@lanl.gov (Jim Giles) (09/24/88)
From article <596@convex.UUCP>, by dodson@mozart.uucp (Dave Dodson): > [...] > Considering the complexity and length of a properly written pow() > routine, it does not appear to me to be practical for the compiler to > in-line it. [...] pow(x,3) == x*x*x appears to me to be both accurate and short enough to be expanded in-line. The same goes for pow(x,-4.) == 1/((x*x)*(x*x). _Most_ uses of the exponentiation operator in Fortran are of this kind. Therefore, _most_ uses would benefit from in-line optimization. Things like pow(x,3.14159) could still call an external to solve - that's the power of letting the compiler in on the semantics of the basic operations. J. Giles Los Alamos
peter@ficc.uu.net (Peter da Silva) (09/24/88)
In article <596@convex.UUCP>, dodson@mozart.uucp (Dave Dodson) writes: > In article <3957@lanl.gov> jlg@lanl.gov (Jim Giles) writes: > >If I were writing a C compiler, I would certainly do pow() in-line. > Considering the complexity and length of a properly written pow() > routine, it does not appear to me to be practical for the compiler to > in-line it. No, but there are certain cases of pow that can be handled in line, with the rest passed off to the library routine: pow(floatvar, integer); pow(floatvar, constant), for certain constants. pow(constant, floatvar), for certain constants. I'm sure Jim can come up with lots more... -- Peter da Silva `-_-' Ferranti International Controls Corporation. "Have you hugged U your wolf today?" peter@ficc.uu.net