Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!seismo!mcvax!ukc!eagle!icdoc!cam-cl!am From: am@cl.cam.ac.uk (Alan Mycroft) Newsgroups: comp.lang.c Subject: Re: Function prototypes versus open() Message-ID: <732@jenny.cl.cam.ac.uk> Date: Fri, 3-Jul-87 09:11:23 EDT Article-I.D.: jenny.732 Posted: Fri Jul 3 09:11:23 1987 Date-Received: Sat, 18-Jul-87 07:28:00 EDT References: <18346@ucbvax.BERKELEY.EDU> <8042@utzoo.UUCP> <2210@hoptoad.uucp> <20538@sun.uucp> <817@mcgill-vision.UUCP> Reply-To: am@cl.cam.ac.uk (Alan Mycroft) Organization: U of Cambridge Comp Lab, UK Lines: 50 In article <817@mcgill-vision.UUCP> mouse@mcgill-vision.UUCP (der Mouse) writes: (Discussion re despatcher and use of unions of function types.) >Except that this makes it effectively impossible to use the dispatcher. extern dispatcher(...., union funtypes fnarg); >int fxn(int x; int y; double z); >... >dispatcher(....,fxn); > >Oops. The argument to the dispatcher is not of type >int (*)(int,int,double) >but of type >union{int(*)(int,int,double);int(*)(int,int,double,double);} >instead. Ugly. Ugly indeed. The problem is that C does not include all the operations one would expect on union types. If you ask (say) a category theorist (and can understand the answer) he will mutter about co-products and say something more precise than: if A and B are types(objects) then so is (sometimes) union(A,B). This comes along with some functions (partial or sometimes undefined in the case of the out functions). in1: A -> union(A,B) in2: B -> union(A,B) out1: union(A,B) -> A out2: union(A,B) -> B. Now we see the problem: C in its hackerish wisdom only provides the 'out' functions via the (e).member construct. The other functions one has to hack using temporaries (see below). Now one should sympathise with those who wish casts of objects into a union type containing that object -- they only want a very natural concept. In C we could say union intorptr { int a; char *b;}; extern f(union intorptr); g() { f((union intorptr)3);} NOT IN ANSI. However, this omission leads to the following as the 'best' allowed form for g: g() { union intorptr temp; temp.a = 3; f(temp); } I fail to see that this is more readable (note we have forged an 'in' function using an 'out' function and assignment). Lest I get flamed, I will not point out the even nastier version using casts between differing pointers which does not work for functions due to the ANSI code/data pointer disinction. Motto: once in a while listen to these crazy pure mathematicians - they can't spent all day contemplating their navels and fail to notice anything significant. While we're on about this, similar reasoning may be used to contemplate why C makes it so hard to extract more than 1 result from a struct-returning function like 'ldiv'.