comp.lang.ada
 help / color / mirror / Atom feed
* Modest proposal, 3 of 3
@ 1996-11-22  0:00 Van Snyder
  1996-11-25  0:00 ` Robert A Duff
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Van Snyder @ 1996-11-22  0:00 UTC (permalink / raw)



BACKGROUND

One of the reasons for code-bloat is the way we teach our children to
structure programs.

What Parnas had in mind when he recommended "information hiding" and
"encapsulation" in Comm. ACM (Dec 72) in "On the criteria for dividing
programs into modules" was that one could thereby (almost) change the
representations of objects in a program by changing their declarations,
but not their references -- no matter what representation one chooses,
the references always look the same: a procedure.

Almost.  In the procedures that support an "abstract data type" one must
still cope with changes in representation.

That's not terrible.  The amount of work necessary to change a
representation is reduced from something proportional to the size of a
program to something on the order of the complexity of the data type.
The unfortunate side effect is that it leads to innumerable tiny
procedures.  On the positive side, the design methodology is applicable
to any language.

Geschke and Mitchell had a better idea in IEEE TSE SE-1, 2 (June 75) in
"On the problem of uniform references to data structures":  Design
languages so that differences in representation are not reflected in
references.  So the [] vs () for arrays vs functions in C would be
considered to be a bad idea.

(Actually, Ross described the germs of the idea in Software Engineering
1 (1969) in "Uniform referents: An essential property for a software
enginering language.")

Minor incremental changes could bring Ada to the state of allowing one
to change the representation of objects without changing their
references.

PROPOSAL for next standardization of Ada

Get rid of ".all".  When an access type appears, dereference it
automatically.  This requires some way to copy "pointers."  PL/1 and
Fortran 90 had the right idea:  Use a different syntax for "pointer
assignment."  This is OK, because there are only two things you can
do with pointers (in a sane language): dereference them and copy them.

Both Fortran 90 and PL/1 use "a => b" to mean "change a so it points
where b points" and "a = b" to mean copy the data where b points into
the place where a points."  The latter in Ada requires "a.all := b.all".

If one has a datum, say "A: T", and one later decides it's necessary to
allocate it from the free store, the type of A changes from T to "access
T".  That's not too bad.  But all the references change from "A" to
"A.ALL".  That's bad.

With the change I propose, one needn't touch the references -- just
change the declaration, and add "A => new T;".  In this case, "A" refers
to the "pointer", not the data where the "pointer" points.  References
in any other context, except where "A" is bound as an actual argument to
a formal argument of "access T" type, derefences "A".  If "A" is bound
as an actual argument of type "T" instead of "access T", "A" is
effectively dereferenced, but the compiler may independently choose to
pass "A" by value or by reference, just as it could for a non-access
type.

Removing ".all" breaks source code compatibility with older versions of
the language, but it's not a disaster.  One could write a not-very-
difficult source-to-source translator that would replace "a := b" by
"a => b", whenever "a" and "b" are access types, and then "a.all" by
"a".  Ideally, this would be an Ada program, distributed in source form,
without fee.  Maybe even the standard committee could require it
accompany all compilers.

There's more that could be done to make programs more mutable, less
fragile, and more efficient, all at once.  See "Not so modest proposal,
1 of 1" to be posted soon.
-- 
What fraction of Americans believe   |  Van Snyder
Wrestling is real and NASA is fake?  |  vsnyder@math.jpl.nasa.gov




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modest proposal, 3 of 3
  1996-11-22  0:00 Modest proposal, 3 of 3 Van Snyder
@ 1996-11-25  0:00 ` Robert A Duff
  1996-11-25  0:00 ` Ken Garlington
  1996-11-26  0:00 ` Joel VanLaven
  2 siblings, 0 replies; 6+ messages in thread
From: Robert A Duff @ 1996-11-25  0:00 UTC (permalink / raw)



In article <575aq0$t4j@netline-fddi.jpl.nasa.gov>,
Van Snyder <vsnyder@math.jpl.nasa.gov> wrote:
>BACKGROUND
>[... same stuff as in proposal 2 of 3]

Did you really need to make us read all that twice?  :-)

>Geschke and Mitchell had a better idea in IEEE TSE SE-1, 2 (June 75) in
>"On the problem of uniform references to data structures":  Design
>languages so that differences in representation are not reflected in
>references.  So the [] vs () for arrays vs functions in C would be
>considered to be a bad idea.

Actually, I think it's a good idea.  The semantics of arrays and
functions are different enough, that I think they deserve a different
syntax.  IMHO, uniform reference is a Good Thing only in cases where the
semantics is closer.  E.g. I think it's a Good Thing that variables and
constants can be referenced using the same syntax (a simple name) in
Ada, because the things you can do with contants are pretty much a
subset of the things you can do with variables -- constants are just
like variables, except they can't change.  In the array-vs-function
case, you can't say "arrays are just like functions except you can't do
do-and-so".  Nor can you say the reverse, "functions are just like...".

Not to mention the fact that overload resolution of "F(X)" is a real
pain for an Ada compiler.  Consider for example:

    type T is array(Integer range <>) of Boolean;
    function F(X: Integer := 22) return T;
    
    if F(33) then -- means F(22)(33)

>Minor incremental changes could bring Ada to the state of allowing one
>to change the representation of objects without changing their
>references.

Minor?  I think there are a *lot* of things that would have to change.
Ada has lots of special-purpose syntaxes for things, which the
programmer can't mimic.  E.g., you can't define an abstract data type
that is "just like" integers, except that it has an infinite range (up
to available memory).  You can define such a data type, but it won't
have literals, range constraints, case statements, etc.

It would be nice if you could define such a data type, but I don't think
it would be "minor incremental changes".

>PROPOSAL for next standardization of Ada
>
>Get rid of ".all".   ...

I think this case is like functions-vs-arrays -- the semantics of things
vs. pointers-to-things is different enough, that I *like* having
explicit syntax for dereferences.  I just wish it weren't so ugly (I
prefer Pascal's "^" to Ada's ".all").  In fact, Ada does allow you to
leave out the ".all" in *most* cases ("X.all := Y.all" is much less
common than "X.Field := Y.Field", which means "X.all.Field :=
Y.all.Field").  I don't think that's such a good thing.

I think "X.all := Y.all" vs. "X := Y" is a perfectly reasonable way to
distinguish pointer-vs-value assignment (except I'd prefer "X^ := Y^"
for the former).  It seems more elegant than having two different
operators for ":=".  Consider integer assignment.  Is that value
assignment?  Well, usually, but if the integers are being used as array
indices in the program, then they behave like pointers.  You don't use a
different ":=" operator to do "A := B" vs. "Table(A) := Table(B)".

By the way, during the Ada 9X design, it was proposed to make ".all"
optional in more cases.  This was before I joined the 9X project, so I
don't remember the details.  I think there was some way to declare, for
a given formal parameter, that ".all" was optional for corresponding
actual parameters.

Your proposal goes much further, if I understand -- you want to make
".all" illegal.

>Removing ".all" breaks source code compatibility with older versions of
>the language, but it's not a disaster.  One could write a not-very-
>difficult source-to-source translator that would replace "a := b" by
>"a => b", whenever "a" and "b" are access types, and then "a.all" by
>"a".  Ideally, this would be an Ada program, distributed in source form,
>without fee.  Maybe even the standard committee could require it
>accompany all compilers.

I doubt if you could write such a translator in less than about 100,000
lines of code.  To do the above transformations, you have to know the
type of every name and expression, which means you have to do overload
resolution, which is a big chunk of code.  OK, maybe 50,000 lines of
code, if you're clever.  Certainly not trivial.  (Unless you happen to
have an Ada front end lying around.)

In addition, you would have to deal with cases like:

    type T is ...;
    type Ptr is access all T;
    procedure P(X: T);
    procedure P(X: Ptr);

    X: Ptr;
    ...

    P(X);

The above is legal in Ada, but would become illegal (ambiguous) under
your proposal.  The above is probably fairly common in real code, too,
for the same reason you mention (sort of) -- somebody wants to write
"P(arg)" and not have to care whether arg is a T or a pointer-to-T.

Don't say that the implicit ".all" is inserted only if needed, thus
making the above legal and calling the second P.  Besides being
confusing and error-prone, such a rule would introduce Beaujolais
effects.

>There's more that could be done to make programs more mutable, less
>fragile, and more efficient, all at once.  See "Not so modest proposal,
>1 of 1" to be posted soon.

I'm looking forward to it.  This is a lot more fun than debating who has
the best picture notation!

- Bob




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modest proposal, 3 of 3
  1996-11-22  0:00 Modest proposal, 3 of 3 Van Snyder
  1996-11-25  0:00 ` Robert A Duff
@ 1996-11-25  0:00 ` Ken Garlington
  1996-11-25  0:00   ` Mark A Biggar
  1996-11-26  0:00 ` Joel VanLaven
  2 siblings, 1 reply; 6+ messages in thread
From: Ken Garlington @ 1996-11-25  0:00 UTC (permalink / raw)



Van Snyder wrote:
> 
> BACKGROUND
> 
> This is OK, because there are only two things you can
> do with pointers (in a sane language): dereference them and copy them.

I'm not sure what a "sane" language is (isn't SANE a numerical representation?),
but I have certainly done mathematics with Ada accesses (systems programming-type
algorithms), and would like to continue to do so. Also, I'm not sure
what "copy" entails, but I assume this would permit access values to be passed
to subprograms.

> If one has a datum, say "A: T", and one later decides it's necessary to
> allocate it from the free store, the type of A changes from T to "access
> T".  That's not too bad.  But all the references change from "A" to
> "A.ALL".  That's bad.

Isn't this the general problem of making object declarations visible to clients,
as opposed to providing access routines (e.g., as an abstract data type/object)?
Other changes along these lines include changing from floating to fixed point,
chracter to a one-element string, etc. Certainly, with methodologies like
ADARTS, the programmer knows that a global variable in a package spec is a potential
maintenance issue later.

It doesn't seem that this is strong enough justification, given the incompatibilities
it would appear to introduce in existing code. (Doing a "simple" source translation
isn't so simple, I suspect, given all the ways in which access values can be used.)


-- 
LMTAS - "Our Brand Means Quality"
For more info, see http://www.lmtas.com or http://www.lmco.com




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modest proposal, 3 of 3
  1996-11-25  0:00 ` Ken Garlington
@ 1996-11-25  0:00   ` Mark A Biggar
  1996-11-26  0:00     ` Robert Dewar
  0 siblings, 1 reply; 6+ messages in thread
From: Mark A Biggar @ 1996-11-25  0:00 UTC (permalink / raw)



In article <32999420.53AA@lmtas.lmco.com> Ken Garlington <garlingtonke@lmtas.lmco.com> writes:
>Van Snyder wrote:
>> BACKGROUND
>> This is OK, because there are only two things you can
>> do with pointers (in a sane language): dereference them and copy them.
>I'm not sure what a "sane" language is (isn't SANE a numerical representation?),
>but I have certainly done mathematics with Ada accesses (systems programming-type
>algorithms), and would like to continue to do so. Also, I'm not sure
>what "copy" entails, but I assume this would permit access values to be passed
>to subprograms.

Humm, but what about = and \=, it is really hard to write most linked list
algorithms if you can't at least compare against the null pointer?


--
Mark Biggar
mab@wdl.lmco.com






^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modest proposal, 3 of 3
  1996-11-25  0:00   ` Mark A Biggar
@ 1996-11-26  0:00     ` Robert Dewar
  0 siblings, 0 replies; 6+ messages in thread
From: Robert Dewar @ 1996-11-26  0:00 UTC (permalink / raw)



>Van Snyder wrote:
>> BACKGROUND
>> This is OK, because there are only two things you can
>> do with pointers (in a sane language): dereference them and copy them.


I assume that this is a dig at the "pointer arithmetic" in C. If so, it is
misguided.

First, the rather surprising fact. Ada 95 has pointer arithmetic, C does not!

Well that sounds outrageous, what do I mean by it?

In C, a pointer is semantically a rather complex object, it is conceptually
a pointer to an object in the usual manner, together with an offset into
this object. So-called pointer arithmetic merely modifies the offset, and
there is a restriction that the offset may not be adjusted to values outside
the allocated object (with one small glitch that it is allowed to point just
past the end of an array, generating a special pointer that cannot be
dereferenced).

Sure, a typical (but not required) implementation of C is to represent this
semanti object with a single hardware pointer, and not to check for violation
of the restrictions on the offset. This means that typical C *implementations*
but not the C language itself, support completely general pointer arithmetic.

But Ada 95 on the other hand supports quite general pointer arithmetic (see
the type Integer_Address and its operations in System.Storage_Elements).
Of course these are not everyday operations in Ada 95, and would be used
only for certain purposes, e.g. computation of hash codes invlving
pointers, or implementation of a garbage collector. But such tasks can
be done in Ada 95 without going outside the semantics of the language.

I was discussing the standard template library implementation with one of
its authors a few months ago, and one of his complaints about C, and one
of the things he liked about Ada 95, was the availability of general
pointer arithmetic in Ada 95 that allowed certain algorithms involving
hashing of pointers to be written completely portably in Ada 95 that
could not be written in valid portable C.





^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Modest proposal, 3 of 3
  1996-11-22  0:00 Modest proposal, 3 of 3 Van Snyder
  1996-11-25  0:00 ` Robert A Duff
  1996-11-25  0:00 ` Ken Garlington
@ 1996-11-26  0:00 ` Joel VanLaven
  2 siblings, 0 replies; 6+ messages in thread
From: Joel VanLaven @ 1996-11-26  0:00 UTC (permalink / raw)



Van Snyder (vsnyder@math.jpl.nasa.gov) wrote:
[Background snipped]
: PROPOSAL for next standardization of Ada

: Get rid of ".all".  When an access type appears, dereference it
: automatically.  This requires some way to copy "pointers."  PL/1 and
: Fortran 90 had the right idea:  Use a different syntax for "pointer
: assignment."  This is OK, because there are only two things you can
: do with pointers (in a sane language): dereference them and copy them.

: Both Fortran 90 and PL/1 use "a => b" to mean "change a so it points
: where b points" and "a = b" to mean copy the data where b points into
: the place where a points."  The latter in Ada requires "a.all := b.all".

: If one has a datum, say "A: T", and one later decides it's necessary to
: allocate it from the free store, the type of A changes from T to "access
: T".  That's not too bad.  But all the references change from "A" to
: "A.ALL".  That's bad.
[snip]

Indeed.  That is bad.  However, declaring "A" to be of type "access T" is
the problem, no the ".all" notation.  The Ada way to solve this problem
is to declare the object "A" to be aliased.  So, "A : T" becomes 
"A : aliased T"  and can be accessed used as both an accessable object and
in the way it was before.  If you want the object pointed to by "A" to
stay around after "A" is gone then you are opening up another can of worms.
In order to have a changeless transition from "T" to "access T" then the
memory will have to be deallocated automatically and in a safe manner.  So,
you seem to be advocating required, sophisticated garbage collection.
  Irrespective of whether your "problem" is indeed a problem at all,
you have given no reason why there is anything wrong with ".all" at all.
Your problem can be as easily solved by making dereferencing automatic and
keeping ".all"  The case you talk about is changing from "T" to "access T"
so there are no ".all" constructs involved at all.  Note that in most
cases this is already done.  Ada does have automatic dereferencing.  "A.foo"
is the same if "A" is of type "T" or type "access T" and access types are
most often used with records.
  The final point I want to make is a judgment call but is my opinion of
the way Ada should be, expecially given what I understand to be the design
goals of Ada.  Access types are dangerous.  Making something an access type
we make things more complex and start to run into problems of shared access
and memory allocation/deallocation etc.  It is generally not that hard for
a good programmer to deal with access types correctly, but it still remains
that many nasty errors are due to accessing the wrong memory or some such.
To blindly change an object to access to that object is asking for trouble.
If it must be done, better to have the compiler reject the program at the
points where there might be trouble than simply allow it to compile into
an incorrect program (like mixing access and non-access types).  It might
be that the language should be more restrictive in some way so that 
access type and "regular" types aren't assigned in the same way, but your
suggestion of making de-referencing automatic doesn't seem to be the way.

-- 
-- Joel VanLaven




^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~1996-11-26  0:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-11-22  0:00 Modest proposal, 3 of 3 Van Snyder
1996-11-25  0:00 ` Robert A Duff
1996-11-25  0:00 ` Ken Garlington
1996-11-25  0:00   ` Mark A Biggar
1996-11-26  0:00     ` Robert Dewar
1996-11-26  0:00 ` Joel VanLaven

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox