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'.