From: rockwell@socrates.umd.edu (Raul Deluth Miller-Rockwell)
Subject: Re: Fortran90 and Arrays
Organization: Traveller
	<ROCKWELL.92Apr6230831@socrates.umd.edu>
	<1992Apr7.174954.10303@newshost.lanl.gov>
Date: Wed, 8 Apr 1992 05:15:32 GMT

Jim Giles:
>  On the contrary.  There are numerous numerical problems for which
>  manipulating the odd elements on one time step and the even
>  elements on the next is _exactly_ what you want to do.  In fact,
>  for these problems _IF_ an alternate algorithm exists at all, it is
>  usually less stable numerically, slower, or both.  This example was
>  chosen to demonstrate the simplicity of notation for manipulating
>  arrays with stride.

Manipulation of odd elements and even elements is a problem
significantly different from copying elements in place in the array.

>  I consider J's treatment of type to be crippled.  It gives me (so
>  far as you've presented) inadequate control over the operational
>  use of data.  Something like Fortran (or Ada, C, Pascal, Modula,
>  etc.) is much preferable to the "typeless" identifier system used
>  in J.

Hmm... and I consider Fortran's to be crippled because it forces me to
restrict my problem space in what I consider an arbitrary fashion.
But "typeless" is a misnomer.  The type of an expression is sharply
limited by the operations performed on the results of that expression.
The type of an expression may also be limited by the technique used to
generate arguments for the expression.

This is not "typeless".

>  It generally makes no sense to explicitly apply an identity
>  operation.  If you know the type of your argument ahead of time,
>  you don't bother.  If you don't know your type ahead of time, your
>  code will be inefficient and likely buggy since you're coding in
>  the dark.

And under the right circumstances, an entire program can be compiled
down to a constant.  That doesn't mean that all programs have this
characteristic.

Yeah, if an expression is guaranteed to be an identity operation for
all possible arguments, you can usually just rip it out.  But it is at
times proper to have a function which is an identity for some part of
its domain.

>  |> >  So, the use of these operations requires _some_ static
>  |> >  knowledge of the rank of the arguments.  This static
>  |> >  knowledge should be encoded explicitly into the function
>  |> >  definition so that the optimizer has a chance of producing
>  |> >  good code.

>  |> Most likely the static information will be explicitly encoded
>  |> into either the function definition or the code which uses that
>  |> definition.

>  So far, you have not presented _any_ method of doing so in J.  If
>  such a capability exists, please present it.

Eh?  If I have an expression like:
   mean=. sum divided_by tally

And I've defined 'sum' as:
   sum=. +/

Then I've a static restriction on the arguments to 'mean': they must
be numeric.

More generally, if I ever use an expression of the form
    invalid ^: predicate

where 'invalid' is the empty function, then the compiler must restrict
the resulting code so that 'predicate' is always false.

>  From what you've presented so far, _any_ component of a program
>  which is written in J seems likely to me to be the largest time
>  consumer of the entire programming environment - even if it's
>  rarely used.

There is a certain amount of truth to this.  As I've stated before,
the current implementations of J have not been optimized for speed.
There are, some very good reasons to expect that J will be able to
compete with languages like Fortran, in terms of speed.  I'll let you
know when that starts to happen ;-)

>  That's what I said.  Your rank 5 array is a rank one array whose
>  elements are large.  Fortran 90 has a way of doing that.

Yes, but from what I've seen, Fortran 90 forces you to make this
declaration about the array, and it's not sufficient to make this
declaration about the function which is designed this way.  This means
lots of bookkeeping code to accomplish a very simple end.

>  I'm not interested in novice programmers per se.  I'm interested in
>  _expert_ programmers.  But you're right, the decision of whether
>  the default semantics of arrays is row-wise of column-wise does not
>  effect novices - so the natural column-wise ordering should be
>  chosen since that's what most _existing_ programmers are familiar
>  with.

Where that is the best metric, sure.

>  |> Here, 'comma rank minus-one' defines the desired operation.

>  You mean `comma quote underscore one'.  And, I don't know what this
>  does, but it appears to explicitly denote a direction - which is
>  what I said _should_ be done.  You have presented an example which
>  supports my position which was that there should be no default
>  direction for those operations for which no `natural' default
>  exists.

Actually, I meant 'concatenate rank minus-one'.  And what it does is
catenate items from the left argument to items from the right
argument.  The number of items on the left must conform with the
number of items on the right.  The operation done on each of those
item pairs is concatenation.  For the case of concatenating a 3x3
matrix to a 3 element vector, there are three items on each side, and
each 3 element subarray (rank 1) from the matrix is concatenated with
a one element subarray (rank 0) from the vector.  So, the result is a
3x4 matrix.

I'm not sure what you mean about directions.  More specifically, I'm
not sure how you intend to indicate direction without some system of
reference.  I believe you're advocating that we must use a cardinal
system of reference (where every dimension must be given an arbitrary
name), and that you're trying to avoid an ordinal system of reference
(where dimensions are ordered).

>  |> The advantage of this rule is 'rank' has a consistent and easily
>  |> understandable definition which is usable with any operation in
>  |> the language.  No exceptions are needed.

>  I still don't understand what it does.  Does it apply to the vector
>  or to the array?

Well, neither.  It applies to the operation.  The derived operation
then applies to the vector or to the array.

>  Exactly.  I _wanted_ the function to be more verbose so that I can
>  read the code several months later (or read other people's code)
>  and have a chance of seeing what it means.  It also gives more
>  explicit information to the compiler for optimization purposes.

Verbosity in and of itself does not achieve clarity, and can hinder
insight into the problem.  It's useful to document the purpose of an
operation.  It's useful to choose meaningful names.  It's useful to
document global influences.  It's not useful to add verbosity for its
own sake.

>  You gave no J example of the code to do this operation, but I
>  suspect it will contain no clues at all about the rank of it's
>  arguments - and therefore provide neither the compiler nor the
>  programmer any idea what's going on.  Further, the example was
>  stated as requiring a function to handle arrays of rank 4 through 7
>  - without an run-time test, how does your J code insure that arrays
>  of rank greater than 7 aren't incorrectly passed?

Well, since no actual operation has been specified, it's rather
difficult to provide code for it.  However, if the operation was
called 'operation', I could use:
    operation"7
to make sure that arrays of rank greater than 7 aren't incorrectly
passed.

-- 
Raul Deluth Miller-Rockwell                   <rockwell@socrates.umd.edu>
Newsgroups: comp.lang.misc