From: stephen@estragon.uchicago.edu (Stephen P Spackman)
Subject: Re: Types, arrays, generality, and notation (was: Fortran90 and Arrays)
Organization: University of Chicago CILS
	<STEPHEN.92Apr11043808@estragon.uchicago.edu>
	<1992Apr13.194947.17250@newshost.lanl.gov>
Date: Tue, 14 Apr 1992 22:19:12 GMT

In article <1992Apr13.194947.17250@newshost.lanl.gov> jlg@cochiti.lanl.gov (Jim Giles) writes:
|In article <STEPHEN.92Apr11043808@estragon.uchicago.edu>, stephen@estragon.uchicago.edu (Stephen P Spackman) writes:
||> [...]
||> Register allocation, type representation selection, calling
||> conventions, inlining, space/speed generation choices, argument format
||> checking, exception handling, and code placement. That's probably only
||> a quarter of the list of things that you can't get right on a
||> module-at-a-time basis. You really are straightjacketting yourself by
||> INSISTING on separate compilation.
|
|[...]
|Further, by moving code generation into the _loader_, such things
|_are_ possible with separate compilation.  Certainly, even without
|such drastic measures, certain of these are appropriate work for 
|the loader - like argument format checking.

I guess we don't disagree then.

||> |[...]
||> |The explicit declarations available to a language _could_ include
||> |usage statistics from test runs or preceeding versions.
||> 
||> But self-modifying source is a worse disaster than self-modifying
||> object. (Of course, there's a clean, standard solution in the form of
||> compiled, automatically-derived interface files).
|
|Oh?  I see.  You are assuming that all declarations about a program
|need to be in source.  This is not true (though, the user should have
|the option of where to put declarations - if he wants the assertion
|about usage statistics in source he should be allowed to put it there).

YOU said "declarations", not me. A declaration is the place where one
declares something, no? I'm a great fan of compiled interfaces, but
I'd hardly call them "declarations".

||> [...]
||> |That's what relocatable files _are_ (like C dot-oh files).
||> 
||> Ha ha. Try dumping one some day. Thre MAY be a few compilers that get
||> this right (in fact Mark Rain's Mary2 was supposed to, ten years gone
||> by), but they're not what you'd call common....
||> 
||> Here's the acid test: can you take your relocatable file and use it on
||> a machine with a different architecture? I thought not....
|
|Here's the other acid test.  Can a software pirate move a copy of my
|code to another machine/architecture without my permission?  I thought
|not....  The _reason_ vendors prefer not to distribute code is to
|limit piracy.  Why would they want an arbitrarily redistributable
|intermediate code representation instead?  That makes piracy nearly
|as easy a publishing the code would have.

Right. Which establishes my point: .o files typically NOT in
intermediate code. Thankyou.

And yes, I would far rather be writing code for one platform than
twenty. I don't believe you can honestly think that the binary
incompatibility between PCs and Macs significantly inhibits software
piracy????

|I think _all_ type-construction methods deserve a distinguished syntax.
|There are only eight that I can think of (the same eight that C.A.R. Hoare
|thought of in Structured Programming, Dijkstra, Dahl, and Hoare).  These
|eight are:
|
|   I) Intrinsic data types.  These should be chosen as appropriate for
|	 the intended problem domain(s) of the language.  Are you saying
|	 that there should be no distinguished syntax for, say, integer 
|	 literals?

A language should not be restricted to a particular problem domain or
domains. A good language is _necessarily_ a general purpose language.

And yes, I am saying that. I should be able to use a denotation like
"28" to refer to something represented as a product of prime powers as
well as to something represented by a 32-bit machine word.

The other 7 type species you list are:
	enumerated, records, unions, arrays, sets, sequences
	(streams), and all recursive types lumped together.

|These are the eight data types all general programming languages should 
|support.  By allowing them to be used orthogonally (like: an array of
|sequences, or a linked list of records, etc.) you can build any data type
|I've ever come across.  Are there any Hoare left out?  In any case, it 
|seems perfectly appropriate - even desirable - for each of these to have 
|a distinguished syntax to improve legibility of the code.

What about:
	the many variant numeric types, like
		fixeds, bignums, constructive reals, prime power
		product integers, rationals, rationals in irrational
		base, ... not all of which (I can guarantee) are going
		to be "intrinsic" to an implementation
	numbers with units, like 9.8 m/s2
	functions
	dependent products
	dependent functions
	type itself

	continuations
	processes
	files
	times
	terminals
	people

Why are you willing to grant special status to arrays and sets and not
to:
	trees
	bags
	dags
	graphs
	posets
	lattices

||> [...]
||> System-reserved mechanisms: fortran has keywords and weird syntaxes
||> for this and that. [...]
|
|Yes, but no keywords are reserved in Fortran since the syntactic rules 
|are such that it's always possible to distinguish keywords from other 
|identifiers by position.  In fact, far from being a benefit, Fortran 
|has been strongly criticized for this.  They are certainly not system 
|reserved.  Further, Fortran 90 permits overloading all the operators 

THEN HOW DO I INTRODUCE A NEW KEYWORD? I tell you, it's a reserved
mechanism. How am I failing to communicate this idea? If I can't make
one, but the language implementor does, it's reserved.

|for user defined meanings.  I would prefer that it allow definition 
|of new operators constructed from an operator character set `@^*+-<>/\|' 
|and maybe a few others - I would prefer this mostly becuase it would 
|then be possible to discourage overloading the intrinsic operators 
|for inappropriate meanings.  Fortran 90 also permits defining named 
|operators which (like the named intrinsic operators: .and., .or., etc.  
|must be enclosed between dots).

Sure took long enough! But hoorah. Can the overloads be resolved off
opaque types, or do they see the implementations?

|So, none of these things are reserved in Fortran - even though some 
|people think they _should_ be.  Apparently, J DOES reserve most of
|the special symbols for arcane purposes of its own.  It is a strange
|case: those things that should be spelled out with a keyword for
|clarity, it uses some arcane symbol for; and those things that 
|symbols should be available to users for are prohibited.

I'm with you on that.

||> 
||> |with an efficient method of calculating without floating-point and
||> |I suspect Fortran (even J) would be quickly extended to support it.
||> 
||> Fixed point with the compiler tracking the scaling factor, of course.
|
|It's considerably slower than floating-point.  Also, it's not 
|more accurate than floating-point, it just has _different_ error 
|characteristics (unless you scale on _every_ operation, in which
|case it _IS_ floating-point, just inefficiently simulated in
|software).

Integer arithmetic slower than floating point? You're kidding! And
accuracy trades against speed. I can get more accuracy by using a
wider word, if I want to, and leave the tradeoffs to the compiler,
where they belong.

||> Von Neumann pointed this out, and I concur: there aren't enough
||> things in nature with a dynamic range in excess of 2^64 to justify
||> giving hardware support to floating point; what it's actually USED for
||> is to avoid thinking about dynamic range at all, and that leads to
||> bugs.
|
|The dynamic range, just of linear scale, of things scientists routinely
|calculate is about 10^160.  For volume scaling in this same range you

Bull. Name me a phyiscal process that is operative over that range,
for computational purposes. A typical example of the things that
floating point is claimed to be really necessary for is climatology.
Now, out of the parameters that apply to gas laws and fluid dynamics,
how many will work over a factor of 10^4?

|need 10^480.  Further, it's desirable not to have to rescale intermediate
|calculations and such - so a wider exponent range is valuable.  Further,
|if over/underflow are what you are complaining about, the wider range 
|makes this _less_ of a problem, not more.

||> [...]
||> In principle we could have 128-bit integers that are significantly
||> faster than IEEE floating point - and a lot more useful - and I think
||> it's really stupid that the FORTRAN community has such a stranglehold
||> on hardware architecture that people don't wake up and start demanding
||> good support for integers.
|
|Yes, I think integers are important - but _independently_ of whether
|floating-point is supported or not.

Trouble is that the hardware girls are handing us float INSTEAD of
integers, because the FORTRAN crowd are so vociferous!

||> [... reduction on empty array ...]
||> Nono, you missed the point. Some operations (like "+") make SENSE for
||> empty arrays, and there you supply the appropriate value (0). Others
||> (like "min") only make sense on an empty array in an extended domain
||> (for present purposes: don't make sense) and so you REQUIRE at least
||> one element, pass THAT as the identity, and then reduce the REMAINDER
||> of the array (which will now be length 0 if the original was length
||> 1).
|
|But, the _user_ should control which semantics he wants.  The compiler
|shouldn't lock him into a given decision.  Further, except on intrinsic
|operators, the compiler has no idea which to do.  Or are you saying that
|reduction should only be supported for intrinsics?

????

That was my point. Identity is part of the programmer-provided
semantics, and you mustn't go locking people into a default that is
actually meaningless half the time.... This is one you MUST be able to
specify, because the compiler DOESN'T know. Or are you suggesting that
reduction should only be.... Never mind.

||> [...]
||> |For example: let's scan addition across an list of integers (1,3,5,7,9).
||> |What happens if the result is (16,8,5,15,25) [I summed from the middle 
||> |element out, alternating left and right]?  Is this meaningful to any
||> |algorithm you know?
||> 
||> You need to use "cons" instead of "+" to see how it might be
||> interesting - "+" has the wrong algebraic properties for this
||> operation, and that ought (in principle) to be a static type error.
|
|How does the compiler know which user-defined functions have 
|the right algebraic properties for an unordered scan?  Further,

By user declaration, if your compiler isn't smart enough to check this
kind of property (such compilers HAVE been built. Ones that will
accept "stable sort" and "list of prime numbers" as types, and
actually check them).

|it seem to me that "cons" applied to the list of integers does 
|nothing but reorder the list.  Why would a compiler determined
|reorder be useful - a reorder driven by the random number 
|generator would - just an arbitrary compiler decision though?

Because it's an intermediate data structure that then gets processed
in some distributed fashion, I suppose. I had the impression that it
was your contribution to the thread, though. ;-)
----------------------------------------------------------------------
stephen p spackman         Center for Information and Language Studies
stephen@estragon.uchicago.edu                    University of Chicago
----------------------------------------------------------------------