James Giles wrote:
> Actually, I prefer subscripts and functions to have the same syntax.
> That way (though it's rare) you can replace a function on integers
> with a predefined array, or vice-versa, without recoding the rest of
> your program. This isn't a strongly felt bias, but I do prefer it.
One more frequently wishes to go the other way -- change an array to a
procedure -- because of some increase of requirements.
Unfortunately, the symmetry isn't complete -- one can't put a "function"
reference on the left side of an assignment, in the I/O list of a READ
statement, as the actual argument associated to an INTENT(OUT) dummy
argument....
C allows a function in a value definition context, but it has the "wrong"
semantics: It returns a pointer through which the value is assigned.
I dare you to try to keep a linked sorted with these semantics.
The "correct" semantics are as in POP-2 or CURL: When a procedure reference
is the LHS of an assignment, the RHS is a hidden argument to an "updater"
procedure that is invoked after the RHS is evaluated. It is responsible for
storing (or whatever it wants to do) the RHS. A "function" and "updater"
are a joined-at-the-hip pair -- if you have one you have the other one --
just like an array. BTW, an array is a function/updater pair for which
the compiler knows how to write the bodies of the procedures, and then
inlines them.
If an updater reference appears as the LHS in an assignment, or in the I/O
list of a READ statement, it's obvious what to do. It's nearly as obvious
when it's associated as an actual argument associated to dummy argument with
specified INTENT -- The question is, do you use copy-in-out or do you pass
in the reference and invoke it every time? It's even less obvious when it's
associated to a dummy argument without specified INTENT.
Further, Fortran has a type for which one has a constructor but no names
and no operations: The subscript triplet. One can't use these as arguments,
so one couldn't simply replace an array by a function/updater pair. More
work is needed.
David Parnas recommended in "On the criteria to be used for decomposing
systems into modules," which appeared in December 1972 Communications of
the ACM, that representations of data objects should be encapsulated in
single-purpose procedures -- one for access and one for updating. Most
practitioners tried to shoe-horn this principle into existing languages
by using functions for access, and subroutines (typically with a different
name) for updating. Unfortunately, if followed diligently, this practice
increases code bulk substantially: One has two procedures with their
headers and declarations for every data object. If ones compiler doesn't
do procedure inlining, one also gets a large and slow executable file.
Very few practitioners suggested that linguistic mechanisms would be
helpful. Charles Geschke and James Mitchell did, however, advocate a
uniform syntax of reference -- both for access and updating -- in "On
the problem of uniform references to data structures," whjich appeared
in IEEE Transactions on Software Engineering, SE-1, 2 (June 1975).
Therein, they reported on the use of this principle in the MESA programming
language, another cool idea that Xerox Data Systems managed to pound into
the ground before disappearing altogether.
D. T. Ross appears to have anticipated everybody with "Uniform Referents:
An essential property for a software engineering language", which appeared
in "Software Engineering," edited by J. T. Tou, volume 1, Academic Press
(1969).
Notwithstanding that many users of languages that have "uniform syntax of
reference" have positive things to say about the long-term "ownership"
costs of programs written in them (see the references in the paper by
Geschke and Mitchell), other users have had negative experiences (that
have only been explained to me by hand-waving, so I don't know what they
are). Thus there is some resistance to adding a facility for a more
uniform syntax of reference to Fortran. The usual argument is "Fortran
users want to see what their code is doing." But then, all of that "what
the code is doing" is buried inside of a pair of procedures, so you can't
see what it's doing at the relevant point of use, anyway. When structures
were being developed ca. 1996, there was a faction that advocated a
functional syntax of reference, i.e. component(structure) instead of
structure%component. They obviously lost the battle.
The bottom line is that it would be a lot of work to add to Fortran, it's
not obvious it could be done completely (how do you represent the absence
of the "upper bound" in a subscript triplet that becomes an actual argument
when you change an array to a function/updater pair?) and there is some
resistance to the concept.
Best regards,
Van Snyder
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|