[comp.lang.misc] Herman Rubin's opinions on computer languages

nevin1@ihlpb.ATT.COM (Liber) (09/08/88)

In article <910@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:

>When I see a language, the corresponding question is
>whether the designers have provided a way for me to use the hardware instruc-
>tions, and how easy and convenient it is for me to do that.

In other words:  when you look at a language, you look to see how low a
level it is and how easy and convenient it is for you to hand optimise
in it.  This doesn't sound like you want a *high* level language to me.

>Consequently, the first thing to strike me about PL/I is that the insertion of
>the hardware instructions the gurus did not consider in their infinite wisdom
>worthy of including in the language is forced to be in the same clumsy form
>which discourages the use of assembler language.  That the language designers
>do not consider this problem important is, I believe, the major problem in
>producing efficient semi-portable software.

Don't you mean NON-portable software?  To me, semi-portable software
means that the machine-dependent parts are isolated and that's all that
has to be changed when porting to a different machine.  With your
ideas, the machine-dependent parts would be tightly integrated with the
rest of the software; this is what makes porting a nightmare.

>> I have no desire to praise PL/I, but I honestly don't see any resemblance
>> to any of the assembly languages I've ever used.
 
>I repeat, what about the multitudinous operations which the gurus have not
>included.

What, from a functionality point of view, can't you program in PL/I
that you can program in all assembly languages (and, for a given
assembly language, would need no changes whatsoever when porting it to
another machine which uses the same CPU)?  In other words, what
machine-independent OS-independent code are you referring to that can
be done in assembly but not done in PL/I?

>The only assembly language I have used in which I used this used ^.  I do not
>know of any use for ^ other than concatenation and power (or superscript) until 
>the C gurus came up with the idea of saying, "Nobody uses this, so we will use
>it for exclusive or."

What would you have chosen for xor, considering a very limited
keyboard, and that most of the other symbols were taken?  C was created
in the early 70s, when a PDP-11 was considered state-of-the-art.
Remember, C was not intended to be a verbose language; keystrokes were
to be kept at a minimum.  Given these conditions, what would you have
chosen?

>This is similar to the use of \ for an escape character.

I pose the same question as above.  And remember, the escape character
should be one character, be printable, and the ESC key did not exist on
most keyboards at the time.

>Language designers should have more respect for even moderately established 
>notation in mathematics and computational theory.

Well, this is funny considering mathematicians don't show respect for
moderately established notations.  sin^(-1)(x) should not mean
arcsin(x), abuse of the ' symbol, d/dx not really division, etc.  And
they aren't limited by what appears on a keyboard, either.  Language
designers do the best they can; the only other way to do things is to
invent new symbols for everything (')+(' for non-associative
[floating point] addition, etc.), and that is not practical in
reality.

>> In the absence of an agreed notation for such a fundamental operation,
>> the use of functional notation has a lot to commend it.

>This is a major bone of contention and interpretation.  I consider that
>a binary operator function normally uses an infix symbol.

Who invented the f(x,y) syntax anyway?  It sure wasn't the computer
gurus.  Prefix notation is extendable (arbitrary number of arguments),
infix is not (well, not easily).  And quite frequently I find myself
having to add another parameter to a function when I try to generalize
it.  This would be very difficult to do with infix notation.

>It may be
>necessary to invent a corresponding symbol, which need not be a single
>character, for the purposes of a program if one is not available.

Well, unless you have a nice graphics terminal, you aren't inventing a
symbol; you are merely using an ordered collection of other symbols to
represent your own.

>I see the problem of assembler language that it is functional notation
>and not overloaded operator.

I never found this to be a problem when I programmed in assembler.  I
liked having a 1:1 correspondence between assembly language and machine
language, and overloaded operators would most definitely go against
that.  And if you, a mathematician, have so much trouble with
functional notation write yourself a preprocessor.

>What do you think the reaction of HLL users
>would be if you required them to write addint(x,y) for x+y if one wanted
>to add the integers x and y?

Many already do.  It occurs in a very old language; a language about as
old as FORTRAN.  It's call LISP.

Or, did you mean to ask that addint(x,y) be used for adding integers,
addreal(x,y) for adding reals, etc.?  If you did, then I answer No, I
don't want to have to do this.  That is one of the reasons I'm using an
HLL in the first place!  And how do you propose to define the
overloaded operators?  If you do it the C++ way, you haven't escaped
your original problem, only moved it.

>in addition to the usual operations.  I maintain that any acceptable language
>should allow such additions, including the temporary addition of infix
>functions, if necessary.

Then WRITE a language, and show us that this is indeed better.

>One point concerning the above.  Standard mathematical operations can produce
>more than one result.

And many functions can produce more than two results.  If you are going
to generalize, then do it right!

>A simple example is division, with quotient and
>remainder.  Another example is that one frequently wants both the sine and
>cosine; it is only about 30% more expensive to produce both of them simul-
>taneously than to produce one.

A LOT of overhead if you only need one.

And why should a programmer programming in a HLL care whether these can
be performed simultaneously.  He specifies what he needs in the HLL,
and the compiler is supposed to generate the best possible machine code
for doing that.  If the compiler isn't doing that you should be
complaining about the implementation, not the language.  Neither of
these two examples show any inherent problems with most HLLs (C, PL/I,
etc.); the problems are with a given implementation.

 _ __		NEVIN J. LIBER  ..!att!ihlpb!nevin1  (312) 979-4751  IH 4F-410
' )  )			 Anyone can survive being frozen in liquid nitrogen;
 /  / _ , __o  ____	  it's surviving the *thawing* that counts :-).
/  (_</_\/ <__/ / <_	These are NOT AT&T's opinions; let them make their own.

P.S.:
In article <6966@well.UUCP> Jef Poskanzer <jef@rtsg.ee.lbl.gov> writes:

@I just did some find/sed/grep hacking to find out just how prevalent
@cross-posting is.

@Here are the people who cross-posted to five groups:
@, Herman Rubin,

Congratulations!

cik@l.cc.purdue.edu (Herman Rubin) (09/09/88)

In article <8695@ihlpb.ATT.COM>, nevin1@ihlpb.ATT.COM (Liber) writes:
> In article <910@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:

I wish to clarify some of the points I made which I believe seem to be
misunderstood.  First let me make it clear that I believe that the "user
friendly" software should enable me to utilize those features of the machine
which I find can provide a solution to my problems which is efficient and
which I can understand.  If not, I would call it "user inimical" instead.

> >When I see a language, the corresponding question is
> >whether the designers have provided a way for me to use the hardware instruc-
> >tions, and how easy and convenient it is for me to do that.
> 
> In other words:  when you look at a language, you look to see how low a
> level it is and how easy and convenient it is for you to hand optimise
> in it.  This doesn't sound like you want a *high* level language to me.

No.  If I see that the language does not have a construction, or the use
of machine instructions, which I can clearly see are appropriate, will it
let me add it without going into extreme contortions.
	
		...........................

>                                                    That the language designers
> >do not consider this problem important is, I believe, the major problem in
> >producing efficient semi-portable software.
> 
> Don't you mean NON-portable software?  To me, semi-portable software
> means that the machine-dependent parts are isolated and that's all that
> has to be changed when porting to a different machine.  With your
> ideas, the machine-dependent parts would be tightly integrated with the
> rest of the software; this is what makes porting a nightmare.

To me, semi-portable software means that the user must decide how to modify
the procedure to take into account the capabilities of the machine.  This 
does not make porting a nightmare, but it does not trivialize it either.
There are many library procedures already which take into account features
such as what is the largest machine-representable floating-point number,
the particular representation of integers, floating-point numbers of various
precision, whether or not certain traps are available, etc.  The use of these
features should affect the program as well.

There is also the problem of optimizing.  I have used the CDC6500 a lot (for
some time it was THE production machine at Purdue) and the 6600 a little. 
These machines the same instructions, and, barring pathologies, any program
on one will run on the other and give the same answer.  Nevertheless, the
programming should be different because of timing problems.

			..................

> >The only assembly language I have used in which I used this used ^.  I do not
> >know of any use for ^ other than concatenation and power (or superscript) until 
> >the C gurus came up with the idea of saying, "Nobody uses this, so we will use
> >it for exclusive or."
> 
> What would you have chosen for xor, considering a very limited
> keyboard, and that most of the other symbols were taken?  C was created
> in the early 70s, when a PDP-11 was considered state-of-the-art.
> Remember, C was not intended to be a verbose language; keystrokes were
> to be kept at a minimum.  Given these conditions, what would you have
> chosen?

Probably I would have chosen %, partly because of its slight similarity to
the letter x.  Alternatively, how about using a two-character combination,
which was done in FORTRAN because of character limitations.  After all,
C uses ++ and --, which I think are also mistakes; I would have used ' and `.

> >This is similar to the use of \ for an escape character.
> 
> I pose the same question as above.  And remember, the escape character
> should be one character, be printable, and the ESC key did not exist on
> most keyboards at the time.

I can see a reason for an escape character in a program.  However, I do not
feel it has to be printable.  For private purposes, I have used DELETE as an
escape character.  But why was ! tied up for negation, instead of using ~
(or even a quoted -).  Why was there no check to see if \ was wanted for
something else.

> >Language designers should have more respect for even moderately established 
> >notation in mathematics and computational theory.
> 
> Well, this is funny considering mathematicians don't show respect for
> moderately established notations.  sin^(-1)(x) should not mean
> arcsin(x)

Why not?  It is the inverse of the sin _function_.  This notation is fairly
standard.

> abuse of the ' symbol, d/dx not really division

It is, if you look at it the right way.

> , etc.  And
> they aren't limited by what appears on a keyboard, either.  Language
> designers do the best they can; the only other way to do things is to
> invent new symbols for everything (')+(' for non-associative
> [floating point] addition, etc.), and that is not practical in
> reality.
> 
> >> In the absence of an agreed notation for such a fundamental operation,
> >> the use of functional notation has a lot to commend it.
> 
> >This is a major bone of contention and interpretation.  I consider that
> >a binary operator function normally uses an infix symbol.
> 
> Who invented the f(x,y) syntax anyway?  It sure wasn't the computer
> gurus.  Prefix notation is extendable (arbitrary number of arguments),
> infix is not (well, not easily).  And quite frequently I find myself
> having to add another parameter to a function when I try to generalize
> it.  This would be very difficult to do with infix notation.

In general, the f(x,y) notation is used when the operator nature is not
considered important, and it is the function f which takes on some import-
ance.  If the operator notion is important, it is often the case that an
additional parameter (or parameters) is (are) used as a subscript to the
operator symbol.

> >It may be
> >necessary to invent a corresponding symbol, which need not be a single
> >character, for the purposes of a program if one is not available.
> 
> Well, unless you have a nice graphics terminal, you aren't inventing a
> symbol; you are merely using an ordered collection of other symbols to
> represent your own.

We should have terminals, which need not be expensive graphics terminals,
but relatively cheap ones with user-definable downloadable characters.
However, the possibility of combining characters is still there.

> >I see the problem of assembler language that it is functional notation
> >and not overloaded operator.
> 
> I never found this to be a problem when I programmed in assembler.  I
> liked having a 1:1 correspondence between assembly language and machine
> language, and overloaded operators would most definitely go against
> that.  And if you, a mathematician, have so much trouble with
> functional notation write yourself a preprocessor.
> 
> >What do you think the reaction of HLL users
> >would be if you required them to write addint(x,y) for x+y if one wanted
> >to add the integers x and y?
> 
> Many already do.  It occurs in a very old language; a language about as
> old as FORTRAN.  It's call LISP.
> 
> Or, did you mean to ask that addint(x,y) be used for adding integers,
> addreal(x,y) for adding reals, etc.?  If you did, then I answer No, I
> don't want to have to do this.  That is one of the reasons I'm using an
> HLL in the first place!  And how do you propose to define the
> overloaded operators?  If you do it the C++ way, you haven't escaped
> your original problem, only moved it.

If the C++ way is implemented more-or-less as a macro expander, with inline
whenever possible, what is wrong with that?  I agree with your objection to
having to use addint and addreal; what you are objecting to at this point is
the nonoverloading.  I want these advantages of a HLL without losing the
power of the machine, and I have seen no refutation of the possibility of
this.  I certainly expect to have to define the overloading of an operator
when I use it in a situation not anticipated by the language producer, and
I do not expect the language producer to anticipate all of these cases; not
by a long shot.

> >in addition to the usual operations.  I maintain that any acceptable language
> >should allow such additions, including the temporary addition of infix
> >functions, if necessary.
> 
> Then WRITE a language, and show us that this is indeed better.
> 
> >One point concerning the above.  Standard mathematical operations can produce
> >more than one result.
> 
> And many functions can produce more than two results.  If you are going
> to generalize, then do it right!
> 
> >A simple example is division, with quotient and
> >remainder.  Another example is that one frequently wants both the sine and
> >cosine; it is only about 30% more expensive to produce both of them simul-
> >taneously than to produce one.
> 
> A LOT of overhead if you only need one.

Surprisingly not.  However, I would not object to having another function
included in the library.  It would not call the usual sincos function.

> And why should a programmer programming in a HLL care whether these can
> be performed simultaneously.  He specifies what he needs in the HLL,
> and the compiler is supposed to generate the best possible machine code
> for doing that.  If the compiler isn't doing that you should be
> complaining about the implementation, not the language.  Neither of
> these two examples show any inherent problems with most HLLs (C, PL/I,
> etc.); the problems are with a given implementation.

Is there a compiler which could take

	a = erf(x);
	b = exp(-x*x);

and recognize that a combined algorithm is faster?  Now I know that this
is the case, and would put in such a function, but I would want it called
something like erfd (erf and its derivative) and use the syntax

	(a,b) = erfd(x);

If a and b are to be in registers, I would expect the results to be treated
accordingly.

As for division with a quotient and remainder, the dividend should be of
type long long.  How do we put this in your favorite language?  How do we
put long * long -> long long into it?  How do we do arithmetic on long long
in the language?  Some of this can be done in C++, but unless symbolic
registers are present, not well.  Most languages do not seem to understand
that multiplication and division frequently should not be type conserving.
With overloaded operators, this is not difficult provided the language does
not get in the way.  In fact, I would start with an overloaded, weakly typed,
assembler.  An example would be

	x = y * z

Assuming that hardware instruction corresponding to this exist for certain
type combinations, that hardware instruction would be used if the types
conform.  However, I would reserve the right to modify the * to force the
operation to use the desired types if something else is wanted.

I hope this provides some clarification.
-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)