comp.lang.ada
 help / color / mirror / Atom feed
* Collective response to := messages
@ 1988-11-28 22:19 Geoff Mendal
  1988-11-29 14:39 ` Dennis Doubleday
                   ` (2 more replies)
  0 siblings, 3 replies; 64+ messages in thread
From: Geoff Mendal @ 1988-11-28 22:19 UTC (permalink / raw)


I will respond briefly to some of the replies made to my original
assignment overloading message.  Lines with ">>" are from my original
message, lines with ">" are responses to my original message.  I am a
bit shocked that some people apparantly agree with me... I'm not used
to that sort of thing.

>Date: 23 Nov 88 22:57:59 GMT
>From: hubcap!billwolf@gatech.edu  (William Thomas Wolfe,2847,)
>Subject: Ada Language Change: Assignment Overloading
>
>> 1. Why simply restrict it to assignment?  Why not include membership,
>>    short-circuit control forms, indexing, selection, attributes, etc.?
>>    These are all basic operations....
>
>   First, assignment is a "fundamental" operation; except for attributes,
>   the other things you've suggested apply only to specific classes of
>   ADTs.  As for attributes, I think we could live without them if 
>   appropriate procedures and functions were defined over the predefined
>   ADTs; having attributes for predefined ADTs and functions for user-defined
>   ADTs is another inconsistency.  Procedures and functions are definitely
>   necessary; the attribute mechanism is not.

Wrong.  Membership, qualification, attributes, and explicit type conversion
are all "fundamental" operations defined for EVERY type.  To argue that
assignment is special requires more justification than "we can live without
X and Y is necessary".  Who can live without X?  I can most certainly live
without assignment overloading.  Does this mean that overloading assignment
is a good/bad idea?  Nonsense.  Rethink your argument.

>   Another reason is that assignment procedures need to be invoked as part
>   of the evaluation of a user-defined ADT which is passed by value.  No
>   similarly vital function is performed by the other operations suggested.

I don't understand this at all.  You are assuming pass by value for an
ADT?  Rediculous.  The LRM only states that scalars and access values
are passed by copy.  In general, for an ADT, you cannot assume pass by
value and if your program depends on it, your program will execute
erroneously.  Justifying a language change based on a set of programs
which are known to execute erroneously it itself an erroneous argument.
If an "assignment procedure needs to be invoked as part of the evaluation
of a user-defined ADT" then one can explicitly write the Ada code
necessary for this.  Default components for records provide a simple
solution here.  There are other solutions as well.  None of the solutions
REQUIRE assignment to be overloaded.

>   The argument that the operations listed (except assignment and attributes)
>   should be user-programmable with respect to user-defined ADTs is reasonable,
>   but clearly assignment is in a higher class of importance than the others.

I strongly disagree.  Assignment is assignment.  A relational operator
is a relational operator.  Are we going to change the language by
taking a popular vote of which operations are "higher class" than
others?  Such justification for a language change is rediculous.  So
far, I have seen no justification why assignment should be overloaded
and not other basic operations.  Consider usability, readability,
understandibility, etc.  These should drive the justification, not
someone's arbitrary "higher class" argument.  My argument is that
while readability might be increased, understandability will be
diminished and therefore we should reject the notion that overloading
assignment is a good idea.  The designers of Ada went out of their way
to make typing Ada programs more difficult/time-consuming so that
understanding them would be easier.  Any language change should not
compromise understandability for the sole gain of making programs
easier to type.

>Date: 23 Nov 88 19:13:34 GMT
>From: trent@unix.sri.com  (Ray Trent)
>Subject: Ada Language Change: Assignment Overloading
[some verbage deleted]
>
>This standard argument against allowing the overloading of the ":="
>operator ignores the fact the programmers may want *semantics*
>in their type declarations instead of just syntax. Types are not 
>static objects that can be completely defined at compile time,
>however much the designers of Ada want to think they are.
[fraction example deleted]
>
>The Ada apolgists would have us write the semantics for ensuring
>LCD form for the type Fraction into *each and every operator*
>that acts upon 2 items of this type, instead of having that 
>functionality in the assignment operator, where it belongs. The point 
>is, readable or not, ":=" should validly ensure the *semantics* of
>every type it is defined for, as well as the pure syntactical elemants.
[more fraction examples deleted]

First, assignment is NOT an operator.  It is a basic operation.
Operators are completely different in that they follow different
scope/visbility rules and are afforded some luxeries (overloading)
not currently available to basic operations.  I tried to make this
point clear in my original message but it is obvious that still not
everyone understands the difference.  Read the LRM and be enlighted.

Now, of course programmers want semantics in their type declarations
and I believe that Ada provides some of these semantics through
predefined behavior of basic operations and operators.  But I disagree
that having the complete semantics for a type defined in an
"assignment operator" is appropriate or even desired.  Assignment
already has a very well defined semantics.  Read the LRM.  So what is
the problem?  You don't like those semantics and you would prefer to
alter them?  Fine, but I fail to see why ":=" has to be the syntagma which
carries your favorite semantics (which may not be my favorite
semantics).

One of the examples that I deleted above was "A := B / C;"
where A, B, and C were of some ADT (Fraction).  If I understand the
argument for placing the semantics in assignment instead of having the
programmer define the semantics in each user-defined operation, then
how would the semantics of passing the expression "B / C" to some
subprogram formal be handled?  There is no "assignment" here.  The
semantics have to be part of the division operation.  Perhaps you
are arguing that indeed "assignment semantics" should be a part of
EVERY operation.  This is a completely different language change,
far more involved than a "simple" overloading of "assignment".
Perhaps those who are involved with Ada formal definition projects
(DDC, etc.) can shed some light on what is involved here and if
such would be useful.

>The argument that pre-processors can be used to acheive this effect is
>bull. It ignores the absolute fact that *no one* maintains, reads, or
>is expected to understand the processed code. This is a null argument.

Quite the contrary.  The whole idea of a pre-processor or translation
tool is to remove the need to "read" the processed version.  How many
Ada programmers spend their time disassembling and reading the output
of their compilations?  A compiler is a translation tool.  The idea
being that Ada is more readable/understandable/etc. than assembly.  So
why is it that defining a mapping from some pre-processor to Ada is
met with such cynicism?  It simply provides an additional layer of
abstraction, which, the last time I looked, was thought to be a good
idea.

Those who are convinced that there is nothing above/beyond Ada should
continue to keep their blinders on so that they won't have to worry
about keeping up with computer science and software engineering.  If
others in our field had adopted this attitude, we'd still be
programming by wire wrapping and debugging with oscilloscopes.  (It is
a sad commentary that there are still Ada programmers out there who
still do not understand the need for and utility of an APSE.  You can
spot them right away... they're the ones who think that the only way
to improve/change things is by modifying the language.)

>Date: 24 Nov 88 01:55:31 GMT
>From: hp-sdd!ncr-sd!ncrcae!hubcap!billwolf@hplabs.hp.com  (William Thomas Wolfe,2847,)
>Subject: Ada Language Change: Assignment Overloading
>
>   Why can't an overloadable operation remain as a basic operation?
>
>   In order to preserve compatibility, the "old" interpretation of
>   assignment could be kept as the outermost interpretation (deepest
>   in the background), available as a default assignment procedure.

Yech!  The current language definition is clear and consistent.  A
basic operation (such as assignment) cannot be overloaded.
Overloading is defined only for subprograms, single entries,
operators, and enumeration literals.  My point was that if assignment
was to be overloaded, then it would most likely have to be
reclassified as an operator or a procedure.  Otherwise, this language
change would require much more work.  Having assignment as the only
basic operation which could be overloaded makes the semantics of
"assignment" more murky.  Overloading is complex enough without adding
a new special case to it.  And for what benefit?  I still haven't seen
a response that illustrates a useful case where overloading assignment
would do anything useful.  Does anyone have such a case?  Or is this
basically a theoretical argument whereby the impact of a language
change will not be understood until it has been made and programmers
start to experiment with it?

>>    Program provers might rely on the fact that if no exception is raised 
>>    during the "assignment", that the the value is assigned to the object.  
>
>   And what about the overloadable relational operators???
>
>   Program provers cannot now assume that "=" really means equality,
>   nor can they assume that some side effect will not occur during the
>   evaluation of an equality operator.  There is plenty of precedent here.
>   If we go ahead and overload assignment, the program prover will be able
>   to exercise one simple, consistent rule: "Assume nothing".  I think this
>   is an excellent mode of thought to force a program prover into.  

Well, not really.  Since "=" can only be overloaded by the user for
limited types, it is not a good example.  "*" is a better example.
But the point is that the current semantics of assignment do allow
program provers to make certain assumptions which make the job of
writing a program prover easier.  While it is certainly possible to
write a program prover which does not make use of the current
assignment semantics, it is far harder to do so.  The point being that
there exist applications of Ada out there which will suffer somewhat
from this proposed language change.  Whether this is a desired result
is debatable (do we really want to force the program proving folks to
go back and undertake a major redesign because a few programmers hate
to type ASSIGN?).

>> The proponents of overloading assignment have also overlooked other
>> less costly solutions such as pre-processors that would transform
>> "overloaded assignment" into Ada procedure calls, implementation-defined
>> pragmas, etc.
>
>    Wrong.  The ability to cleanly define abstract data types 
>    is very much a language issue.  Implementation-defined pragmas
>    would annihilate portability.  Preprocessors would have one hell
>    of a time implementing "If this procedure call involves passing
>    a user-defined ADT by value, then generate a temporary variable
>    of that type, invoke ASSIGN on that temporary (assuming we adhered
>    to the convention of using the name ASSIGN rather than, for example,
>    COPY or DUPLICATE), and pass the temporary instead, and remember 
>    to invoke DESTROY on the temporary afterward"...
>
>    There's no way around it.  Assignment needs to be overloadable.

I don't understand this argument at all.  Clearly one can write ASSIGN
procedures by hand to solve this sort of thing.  The only difference
is that ASSIGN (X, Y) has to be written instead of "infix" X := Y.
So why does assignment need to be overloaded?  And if one can write
the code with the intended semantics by hand, then why cannot an
advanced APSE tool do so?  Is your argument that the state of APSE
technology is not sufficient to solve the problem, and therefore we
have to solve it as a language problem?  This is again a silly argument
for making a language change and would prove my case that this is
indeed an APSE issue, not a language issue.

***********
Since overloading of assignment is not a very important issue, I'll
refrain from making any further comments about it.  I'll get back to
doing more important things... writing pre-processor tools for Ada.

gom

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

* Re: Collective response to := messages
  1988-11-28 22:19 Geoff Mendal
@ 1988-11-29 14:39 ` Dennis Doubleday
  1988-11-29 21:08 ` Ray Trent
  1988-11-29 21:44 ` William Thomas Wolfe,2847,
  2 siblings, 0 replies; 64+ messages in thread
From: Dennis Doubleday @ 1988-11-29 14:39 UTC (permalink / raw)



In article <8811282217.AA04896@ajpo.sei.cmu.edu> mendal@ANNA.STANFORD.EDU (Geoff Mendal) writes:
>But the point is that the current semantics of assignment do allow
>program provers to make certain assumptions which make the job of
>writing a program prover easier.  While it is certainly possible to
>write a program prover which does not make use of the current
>assignment semantics, it is far harder to do so.  The point being that
>there exist applications of Ada out there which will suffer somewhat
>from this proposed language change.  Whether this is a desired result
>is debatable (do we really want to force the program proving folks to
>go back and undertake a major redesign because a few programmers hate
>to type ASSIGN?).

I agree that overloading of ":=" is a bad idea, but your line of
reasoning here is not convincing (to me).  I would change your last
question to "are we really going to limit programmers to only those
language constructs which the program proving folks find easy to
handle?".  If the answer is "yes", then we're not going to get much
real work done for the next decade, at least.

Dennis Doubleday                       dd@sei.cmu.edu
Software Engineering Institute         (412)268-5873
Carnegie Mellon University
Pittsburgh, PA 15213

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

* Re: Collective response to := messages
  1988-11-28 22:19 Geoff Mendal
  1988-11-29 14:39 ` Dennis Doubleday
@ 1988-11-29 21:08 ` Ray Trent
  1988-11-30 14:37   ` Stephe Leake
                     ` (3 more replies)
  1988-11-29 21:44 ` William Thomas Wolfe,2847,
  2 siblings, 4 replies; 64+ messages in thread
From: Ray Trent @ 1988-11-29 21:08 UTC (permalink / raw)


In an article mendal@ANNA.STANFORD.EDU (Geoff Mendal) writes:
>>The Ada apolgists would have us write the semantics for ensuring
>>LCD form for the type Fraction into *each and every operator*
>>that acts upon 2 items of this type, instead of having that 
>
>First, assignment is NOT an operator.  It is a basic operation.

The argument is that it should be. (and is, in any sensible 
(i.e. non-Ada) definition of the word operator) That there is no
reason to have "basic" operators that are "special".

>One of the examples that I deleted above was "A := B / C;"
>where A, B, and C were of some ADT (Fraction).  If I understand the
>argument for placing the semantics in assignment instead of having the
>programmer define the semantics in each user-defined operation, then
>how would the semantics of passing the expression "B / C" to some
>subprogram formal be handled?  There is no "assignment" here.  The

Fine, perhaps a better example is assigning to an object that should 
be garbage-collected before assignment. (always, or the program 
will be erroneous (not in the Ada sense)) Which makes more sense, 
putting garbage collection in assignment, or assuming the programmer 
will always call a garbage collector while assigning? Even if
the programmer is a code maintainer, and not the designer?

If you are wondering why I chose my original example, consider
A := (B / C * D) + ... + (Q / (3/4)). (all variables are of type fraction,
and an appropriate "/"(A,B : INTEGER) is defined) Do you still want
LCD maintainance in the arithmetic operations? Of course, you could 
always force A := LCD(foo). What if someone wants to modify the program? 
Aren't they going to wonder/forget about this? If you are worried
about passing the expression B / C as a parameter, my answer is: 
if you have a procedure where LCDness is necessary for proving something,
you can *always* simply make "in" parameters "in out" parameters. This 
*ensures* that an input variable will be in LCD form. (if assignment is
overloadable and is overloaded as suggested) "Requiring" a A := LCD(B/C)
does not ensure the validity of something passed to a sub-program.

If assignment were overloadable, the writer of an Ada spec for
operations involving fractions could be *sure* of always having something
in LCD form when passed to a subprogram by overloading ":=" and passing
all variables as "in out" parameters. The only other way to do this
is force *all* subprograms to perform LCDing on their outputs (or inputs)
whether that condition is necessary or not. This would make the operation
A := <very complicated expression with *many* arithmetic operations>
extremely slow (potentially). The LRM explicitly says that intermediate
results need not follow the constraints of the ADT. 

>being that Ada is more readable/understandable/etc. than assembly.  So
>why is it that defining a mapping from some pre-processor to Ada is
>met with such cynicism?  It simply provides an additional layer of

Because it is used to justify inconsistent language constructs. If 
I had a nickel for every time someone said, "you don't need to 
change the language, just use a pre-processor" I'd drown in them.
Point one: any such preprocessor needs to be standardized to the
level that the language is, or it defeats the purpose of the language.
Point two: If such a preprocessor *is* in fact standarized to the level that 
the language is, there is no discernable difference between changing
the language and adding a preprocessor. Point three: the argument is that 
assignment should not be overloadable because it is not understandable
(though more readable). It makes no real difference whether you put
assignment overloading into a pre-processor or into the language. 
The pre-processing source is what will be maintained and used. 
It is identically as understandable if the language is changed as
it is if a processing step is added. Perhaps more so. If the language
is changed, no one will *assume* that assignment cannot be overloaded.
Tacking on a preprocessor is the coward's way out.

>a sad commentary that there are still Ada programmers out there who
>still do not understand the need for and utility of an APSE.  You can

It's needed because the language was designed in an inconsistant and 
inflexible manner in the first place. What would you say about a 
preprocessor that converts C into Ada. Is programming in C then
as good as programming in Ada? (don't laugh, it can be done, especially
if you use unchecked programming) I don't think so.

Another change I'd like to see. (upward compatible this time) Allow:

  if A in B | C | D | Q | Y | N then
    ...
  end if;

I.e. an extension of the membership idea. It's ridiculous to me that

  case A is 
    when B | C => ...
  end case;

is valid but the above (or some equivilent) is not. I argue that such
a construct is both more readable and more understandable than
 
  if A = B or A = C or else ... or else A = N then
    ...
  end if;

and also makes the Ada language more internally consistent. (and thus
easier to use) I also argue that compiler vendors are likely to 
implement the former more efficiently than the latter. This is especially
true when the comparands are of a large enumerated type. (hashing, and all)

Anyway, enough diatribe for today.
-- 
"Our little lives get complicated
 It's a simple thing
 Simple as a flower
 And that's a complicated thing"                     ../ray\..

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

* Re: Collective response to := messages
  1988-11-28 22:19 Geoff Mendal
  1988-11-29 14:39 ` Dennis Doubleday
  1988-11-29 21:08 ` Ray Trent
@ 1988-11-29 21:44 ` William Thomas Wolfe,2847,
  2 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-11-29 21:44 UTC (permalink / raw)


From article <8811282217.AA04896@ajpo.sei.cmu.edu>, by mendal@ANNA.STANFORD.EDU (Geoff Mendal):
>>   Another reason is that assignment procedures need to be invoked as part
>>   of the evaluation of a user-defined ADT which is passed by value.  No
>>   similarly vital function is performed by the other operations suggested.
> 
> I don't understand this at all.  You are assuming pass by value for an
> ADT?  Rediculous.  The LRM only states that scalars and access values
> are passed by copy.  In general, for an ADT, you cannot assume pass by
> value and if your program depends on it, your program will execute
> erroneously.  

    This is precisely the problem.  This is what must be fixed.

> [Argues that the proposal would mean more work for language designers]
>
> [Argues that the proposal would mean more work for program provers]
>
> [Argues that the proposal would mean less work for him, since he
>  is employed as a writer of preprocessor tools for Ada]

     Much more money is spent using a programming language such as Ada
     than is spent designing it.  Hence, if we can save the time of
     30 million programmers at the expense of the time of 300 language
     designers, I submit that this is an appropriate tradeoff.  

     What is needed is a completion of the ADT paradigm, support for
     which is the fundamental reason for the "limited private" feature.
     Given that one must remember to destroy all non-predefined ADTs 
     upon block exit, it is clear that the implications of this paradigm 
     were not appropriately considered in the Ada 83 design. 

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

* Re: Collective response to := messages
  1988-11-29 21:08 ` Ray Trent
@ 1988-11-30 14:37   ` Stephe Leake
  1988-12-01 14:54     ` David S. Rosenblum
  1988-12-01 21:31     ` Ray Trent
  1988-11-30 16:29   ` David S. Rosenblum
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 64+ messages in thread
From: Stephe Leake @ 1988-11-30 14:37 UTC (permalink / raw)



There seems to be a point of confusion concerning overloading of ":=".
Some people assume that the (overloaded) semantics of ":=" apply to
parameter passing. This seems to be a reasonable assumption, and I
think the current Ada parameter passing semantics are equivalent to
the current Ada assignment semantics. However, other types of
overloading (such as for "*") only apply when the overloaded symbol
appears _explicitly_; thus an argument could be made that the
overloaded ":=" should only be used for explicit assignments, not the
implicit ones in parameter passing. Personally, I think parameter
passing should be the same as assignment, but I just wanted to point
out the confusion.

In Ray Trent's discussion of the Fraction Abstract Data Type, he
implies that "*" and "/" do not reduce fractions to LCD form, but ":="
does. It seems to me, therefore, that he is talking about 2 data
types; LCD_Fractions and Fractions. This removes the need to overload
":=". "*" and "/" take either type and return Fraction. Then, since
there are two types involved, the compiler will remind maintainers to
include the explicit LCD operation;

A : LCD_Fraction;
B, C : Fraction;

A := B /C ; 	-- illegal
A := To_LCD_Fraction (B / C);	-- legal

I don't think ":=" should be overloadable just so we can hide type
conversions; this is one of the main complaints about C - one can
never be _sure_ what type something is.

The example above brings up a suggestion; type names should be
overloadable by functions, so we can define type conversion functions
that look like the type conversions available to scalar types. Ie the
function "To_LCD_Fraction" above should be named "LCD_Fraction". I
don't know which section of the LRM to refer to here; overloading
rules seem very scattered.

Ray Trent says:
	> The LRM explicitly says that intermediate
	> results need not follow the constraints of the ADT.
Where does it say this?

I second the motion for allowing:

  if A in (B | C | D | Q | Y | N) then
    ...
  end if;

(note that I added parentheses). Currently, we can get the same effect
with a subtype, but _only_ if B | C | D | Q | Y | N can be _uniquely_
described by a range constraint, which is often not the case. This is
leaning further towards defining sets in Ada, something that PASCAL
has always had. There are certainly problems with fully implementing
sets, but I think this extension is a good one.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-11-29 21:08 ` Ray Trent
  1988-11-30 14:37   ` Stephe Leake
@ 1988-11-30 16:29   ` David S. Rosenblum
  1988-11-30 18:29     ` William Thomas Wolfe,2847,
  1988-12-01 18:31     ` Ray Trent
  1988-11-30 18:24   ` Robert Eachus
  1988-12-02 19:34   ` Mark C. Adolph
  3 siblings, 2 replies; 64+ messages in thread
From: David S. Rosenblum @ 1988-11-30 16:29 UTC (permalink / raw)


In article <24856@sri-unix.SRI.COM> trent@unix.sri.com (Ray Trent) writes:
>In an article mendal@ANNA.STANFORD.EDU (Geoff Mendal) writes:
>>
>>First, assignment is NOT an operator.  It is a basic operation.
>
>The argument is that it should be. (and is, in any sensible 
>(i.e. non-Ada) definition of the word operator) That there is no
>reason to have "basic" operators that are "special".

Most of the non-Ada definitions of "operator" that I am familiar with
describe operators in a purely mathematical sense, i.e. in terms of
domains and algebras.  However, assignment is a concept that is peculiar to
programming languages, so in a sense you're comparing apples and oranges.
And most "sensible" definitions of assignment that I know of describe
assignment simply in terms of placing a value in a variable or memory location.

Basic operations in Ada ARE special, for very good reasons.  Unlike operators,
they are intimately connected with Ada's model of type constraints in some
way and cannot be hidden.  One of the nice features of Ada type constraints is
that they are (or at least were intended to be) implemented consistently
throughout the language, in part via the basic operations.  This consistent
enforcement would be lost if overloading of basic operations were allowed.  In
particular, by allowing overloading of assignment, it would be possible to
override one of the fundamental steps of the assignment operation, which is to
guarantee that the target variable in an assignment statement is assigned a
legal value of its type.  When you overload operators such as "=" and "+",
you may give perverse semantics to operators that have a "traditional"
meaning, but you are not able to override Ada's type checking.  Thus,
allowing overloading of assignment (or any basic operation) would seriously
weaken Ada's strong typing features.

>[lots of discussion about LCD deleted]

As I understand your LCD example, you seem to see assignment overloading
as a vehicle for implementing type constraints that can't be expressed in
Ada's constraint language (such as LCD-ness).  So why stop with assignment?
Wouldn't you need overloading of all the basic operations?  Suppose
I'm given a language change which allows overloading of basic operations,
and suppose I have a type EVEN, e.g.,

	type EVEN is new INTEGER;

which I want to constrain in a way that would require all variables of
the type to have even values.  In order to enforce this constraint
consistently in the manner of Ada, I would want to do the following:

(1) Overload := so that it raises CONSTRAINT_ERROR when given an odd
    right-hand-side.
(2) Overload the attributes 'SUCC and 'PRED so that they skip odd values.
(3) Overload the attributes 'POS and 'VAL so that count only even values.
(4) Overload the attribute 'FIRST so that it returns the smallest even
    value of EVEN's base type.
(5) Overload the attribute 'LAST so that it returns the largest even
    value of EVEN's base type.
(6) Overload the membership tests and the ".." token so that only
    even ranges are considered.
(7) Overload the indexing operation for all array types I define that are
    indexed by EVEN values, so that even-numbered components are stored and
    accessed contiguously.
(8) Overload the aggregate operation for such array types so that
    the index values for the aggregate are computed "the right way".

Yet after all these exertions, my evenness constraint would STILL not
be enforced consistently, unless I was given several more language changes.
For example, type conversions, qualifications, attribute evaluations and
membership tests never propagate exceptions.  Yet what would be the effect
of the type conversion "EVEN(3)"?  What would be the effect of the attribute
evaluation "EVEN'POS(3)"?  What would be the effect of the tests
"2 in 0 .. 3" or "3 in 0 .. 10" ?  Should they raise CONSTRAINT_ERROR, or
should they round 3 to some even value?  Suppose I instantiate INTEGER_IO to
perform I/O on EVEN values.  How do I get the instantiation to enforce my
evenness constraint?  First I would need another language change that requires
source-level assignment "operators" to be used to implement parameter
passing.  But I'm still in trouble because my overloaded := cannot be made
visible to my INTEGER_IO instantiation.  So I would ALSO need INTEGER_IO to be
redefined to accept a generic formal := parameter.  Oy!

I agree with Geoff.  The proponents of assignment overloading have not
addressed the ramifications of their proposal thoroughly enough to come
up with a fully consistent change to the language.  Until they do, I'm
happy to write ASSIGN instead of := whenever I need a "special" assignement
operation.


-- David

-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-11-29 21:08 ` Ray Trent
  1988-11-30 14:37   ` Stephe Leake
  1988-11-30 16:29   ` David S. Rosenblum
@ 1988-11-30 18:24   ` Robert Eachus
  1988-12-02 14:58     ` David S. Rosenblum
  1988-12-02 19:34   ` Mark C. Adolph
  3 siblings, 1 reply; 64+ messages in thread
From: Robert Eachus @ 1988-11-30 18:24 UTC (permalink / raw)



     There has been a lot of frothing at the mouth on both sides of
this issue about what is or is not the Ada model of assignment.  First
of all a lot has been said about what a change to the language it
would be to make assignment or other basic operations overloadable.
However, if you look in 8.7 Context of Overload Resolution, the first
paragraph states:

     "Overloading is defined for subprograms, enumeration literals,
operators, and single entries, and also for the operations that are
inherent in several basic operations such as assignment, membership
tests, allocators, the literal null, aggregates, and string literals."

      Overloading, and overload resolution involving basic operations
is a fact of Ada life.  If you think otherwise try:

      package Overload_Test is
        type A is access Boolean;
        B: constant Boolean := null = null;
        type C is access Character;
        D: constant Boolean := null = null;
      end Overload_Test;

      The compiler should accept the decalartion of B, but reject the
declaration of D.  A lot of work went on during the language
definition process to make similar (but useful) cases work for numeric
types. If you object that this example involves equality which is not
a basic operation instead try:

       package Overload_Two is
	 A: Boolean := 'b' in 'a'..'c';
         type New_Char is ('b', 'a', 'c');
	 C: Boolean := 'b' in 'a'..'c';
       end Overload_Two;

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

* Re: Collective response to := messages
  1988-11-30 16:29   ` David S. Rosenblum
@ 1988-11-30 18:29     ` William Thomas Wolfe,2847,
  1988-11-30 22:28       ` David S. Rosenblum
  1988-12-01 18:31     ` Ray Trent
  1 sibling, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-11-30 18:29 UTC (permalink / raw)


From article <10906@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> One of the nice features of Ada type constraints is
> that they are (or at least were intended to be) implemented consistently
> throughout the language, in part via the basic operations.  This consistent
> enforcement would be lost if overloading of basic operations were allowed.  In
> particular, by allowing overloading of assignment, it would be possible to
> override one of the fundamental steps of the assignment operation, which is to
> guarantee that the target variable in an assignment statement is assigned a
> legal value of its type.  

     Since the overloaded assignment would be implemented in terms of
     the existing low-level assignment operations, I don't see where any 
     potential problem exists here.  Please clarify.
 
> As I understand your LCD example, you seem to see assignment overloading
> as a vehicle for implementing type constraints that can't be expressed in
> Ada's constraint language (such as LCD-ness).  
> [...] 
> Yet after all these exertions, my evenness constraint would STILL not
> be enforced consistently, unless I was given several more language changes.
> For example, type conversions, qualifications, attribute evaluations and
> membership tests never propagate exceptions.  Yet what would be the effect
> of the type conversion "EVEN(3)"?  What would be the effect of the attribute
> evaluation "EVEN'POS(3)"?  What would be the effect of the tests
> "2 in 0 .. 3" or "3 in 0 .. 10" ?  Should they raise CONSTRAINT_ERROR, or
> should they round 3 to some even value?  

    The problems mentioned pertain specifically to this implementation
    only; if EVEN were implemented as a limited private type within an
    appropriate package, all the operations mentioned would be available 
    only through the procedures/functions provided.  Type conversions
    would not be legally expressible in the usual notation, most attributes
    would not be defined, etc.  Ada 83 allows us to do all of these things,
    but not in the "conventional" notation.  

    Since Ada does not allow implicit type conversions, the fact that we
    cannot overload type conversion does not cause us any grief in the
    parameter-passing process.  Nor do any of the other operations mentioned.

    Only assignment and destruction play vital roles in the evaluation of
    parameters and in the creation and destruction of variables (particularly
    with regard to block entry and exit).  It is the fact that the language
    does not consider the impact of these mechanisms upon the ADT paradigm,
    mechanisms which can play havoc with our abstractions, that compels us 
    to call for changes in the language with regard to the ability to
    define specific procedures for assignment and destruction which are 
    taken into consideration by these mechanisms. 

> I agree with Geoff.  The proponents of assignment overloading have not
> addressed the ramifications of their proposal thoroughly enough to come
> up with a fully consistent change to the language.  

    It is entirely possible that given the desire of AJPO to minimize the
    extent of changes in the language, it will not be possible to get Ada
    to provide complete support for the abstract data type paradigm.  Ada
    was explicitly intended as an interim solution, covering the range
    1983..20xx, and not as "the perfect language".  Perhaps for Ada it is
    already too late.  But the issue needs to be thoroughly discussed,
    because it is a major area in which Ada has "missed the boat". 

    Perhaps there is a solution which AJPO will find acceptable.  We must
    know whether or not this is the case.  If there is no hope for Ada,
    then we must focus on the construction of Ada's successor.


                                           Bill Wolfe

                                    wtwolfe@hubcap.clemson.edu

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

* Re: Collective response to := messages
  1988-11-30 18:29     ` William Thomas Wolfe,2847,
@ 1988-11-30 22:28       ` David S. Rosenblum
  1988-12-01  3:09         ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-11-30 22:28 UTC (permalink / raw)


In article <3698@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <10906@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
>> In
>> particular, by allowing overloading of assignment, it would be possible to
>> override one of the fundamental steps of the assignment operation, which is to
>> guarantee that the target variable in an assignment statement is assigned a
>> legal value of its type.  
>
>     Since the overloaded assignment would be implemented in terms of
>     the existing low-level assignment operations, I don't see where any 
>     potential problem exists here.  Please clarify.

Essentially, the problems arise from the characteristics of Ada's parameter passing semantics.
(Or we could change those too while we're at it. :-) )  Suppose ":=" overloadings are required
to have an out-mode parameter to represent the target variable.  Then an overloaded ":="
on a composite type can selectively assign to some components of the target and
leave other components undefined (if they were undefined prior to execution of the assignment).
This cannot happen with predefined assignment to objects of a composite type (i.e., when a full
composite object, not just a component of one, is given as the left-hand side).  Alternatively,
suppose ":=" overloadings are required to have an in out-mode parameter to represent the target
variable.  Then it would be impossible to assign to an undefined variable, because the
variable would first be constraint-checked when it is passed in to the assignment procedure.

For example,

procedure CIRCUMVENT is

    type LCD_FORM is
	record
	    NUMERATOR, DENOMINATOR : INTEGER;
	end record;

    X, Y : LCD_FORM;	-- X and Y undefined.

    procedure ":=" (L : out LCD_FORM; R : in FLOAT) is
    begin
	if R = 0.0 then
	    L.NUMERATOR := 0;
	else
	    -- calculate LCD form.
	end if;
    end ":=";

begin
    X := 1.5;
    -- X.NUMERATOR is presumably 3, X.DENOMINATOR is presumably 2.

    -- Y.DENOMINATOR is undefined.
    Y := 0.0;
    -- Y.DENOMINATOR is STILL undefined.
end CIRCUMVENT;

You can object that I didn't define ":=" "correctly" and that I stupidly failed to assign to
DENOMINATOR when R is zero, but that's the whole point--I've circumvented the type checking
that is inherent in predefined assignment.

> 
>> As I understand your LCD example, you seem to see assignment overloading
>> as a vehicle for implementing type constraints that can't be expressed in
>> Ada's constraint language (such as LCD-ness).  
>> [...] 
>> Yet after all these exertions, my evenness constraint would STILL not
>> be enforced consistently, unless I was given several more language changes.
>> For example, type conversions, qualifications, attribute evaluations and
>> membership tests never propagate exceptions.  Yet what would be the effect
>> of the type conversion "EVEN(3)"?  What would be the effect of the attribute
>> evaluation "EVEN'POS(3)"?  What would be the effect of the tests
>> "2 in 0 .. 3" or "3 in 0 .. 10" ?  Should they raise CONSTRAINT_ERROR, or
>> should they round 3 to some even value?  
>
>    The problems mentioned pertain specifically to this implementation
>    only; if EVEN were implemented as a limited private type within an
>    appropriate package, all the operations mentioned would be available 
>    only through the procedures/functions provided.  Type conversions
>    would not be legally expressible in the usual notation, most attributes
>    would not be defined, etc.  Ada 83 allows us to do all of these things,
>    but not in the "conventional" notation.  

That's the whole point of why you don't need assignment overloading!!!  You can also do assignment
with limited private types, but not in the "conventional" notation.  All you need to do is provide
an "appropriate subprogram".

>
>    Since Ada does not allow implicit type conversions, the fact that we
>    cannot overload type conversion does not cause us any grief in the
>    parameter-passing process.  Nor do any of the other operations mentioned.

You seem to be missing my point.  You are trying to use an overloaded assignment operator
to implement a constraint on your LCD type that can't be expressed in Ada's constraint language.
I've argued that I would want the ability to overload the other basic operations so that
I could implement in a consistent manner the constraints that I may dream up.  You've ignored that
argument and instead still seem to be harboring the belief that assignment is "different" from
the other basic operations.  What is so unique about assignment that it alone of all the basic
operations requires special treatment?

>
>    Only assignment and destruction play vital roles in the evaluation of
>    parameters and in the creation and destruction of variables (particularly
>    with regard to block entry and exit).  It is the fact that the language
>    does not consider the impact of these mechanisms upon the ADT paradigm,
>    mechanisms which can play havoc with our abstractions, that compels us 
>    to call for changes in the language with regard to the ability to
>    define specific procedures for assignment and destruction which are 
>    taken into consideration by these mechanisms. 

We can argue about implicitly invoked destruction mechanisms some other time, since Ada provides no
such animal.  And Ada's parameter passing mechanisms are defined implicitly, beyond the reach
of the programmer, as they should be (again to enforce type checking)--they have nothing
to do with assignment at the source level.  Regarding your assignment "abstraction", all
I can offer is the suggestion that reduction to LCD form is an over-specification of what I
consider to be the normal semantics of an assignment operation, and it is better left to
another procedure whose sole purpose is to perform the reduction.  If you define your
LCD type as a limited type in a package, you can provide a NORMALIZE procedure which
will achieve the desired effect.  If you need to add new code later, your only
recourse will be to use the NORMALIZE procedure, as there is no predefined assignment operation
available to confuse you.

>    It is entirely possible that given the desire of AJPO to minimize the
>    extent of changes in the language, it will not be possible to get Ada
>    to provide complete support for the abstract data type paradigm.  Ada
>    was explicitly intended as an interim solution, covering the range
>    1983..20xx, and not as "the perfect language".  Perhaps for Ada it is
>    already too late.  But the issue needs to be thoroughly discussed,
>    because it is a major area in which Ada has "missed the boat". 

I tend to agree with your last comment.  But Ada's abstraction mechanisms will never
be improved in the next revision without a proposal that is carefully thought out and
is fully consistent with the goals of the language.  As I've tried to illustrate, none
of the proposals I've seen for assignment overloading come close to meeting these criteria.

-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-11-30 22:28       ` David S. Rosenblum
@ 1988-12-01  3:09         ` William Thomas Wolfe,2847,
  1988-12-01 15:16           ` David S. Rosenblum
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-01  3:09 UTC (permalink / raw)


From article <10913@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> Alternatively, suppose ":=" overloadings are required to have an in out-mode 
> parameter to represent the target variable.  Then it would be impossible 
> to assign to an undefined variable, because the variable would first be 
> constraint-checked when it is passed in to the assignment procedure.

    This is a question which applies to any assignment procedure,
    whether ":=" or "ASSIGN".  The way I do it is to use in-out mode
    and implement the ADT as a pointer to a descriptor.  That way,
    I take advantage of the fact that all pointers are automatically
    initialized to null, and I use the null-pointer state as the 
    "empty" or "undefined" state of my ADT.  I'd prefer that all
    data types were automatically initialized to "undefined", so I
    could save the space and time associated with the pointer, but
    the workaround does get the job done.
 
>>    The problems mentioned pertain specifically to this implementation
>>    only; if EVEN were implemented as a limited private type within an
>>    appropriate package, all the operations mentioned would be available 
>>    only through the procedures/functions provided.  Type conversions
>>    would not be legally expressible in the usual notation, most attributes
>>    would not be defined, etc.  Ada 83 allows us to do all of these things,
>>    but not in the "conventional" notation.  
> 
> That's the whole point of why you don't need assignment overloading!!!  
> You can also do assignment with limited private types, but not in the 
> "conventional" notation.  All you need to do is provide an "appropriate 
> subprogram".

    Yes, I've been doing exactly that for a long time now.

>>    Only assignment and destruction play vital roles in the evaluation of
>>    parameters and in the creation and destruction of variables (particularly
>>    with regard to block entry and exit).  It is the fact that the language
>>    does not consider the impact of these mechanisms upon the ADT paradigm,
>>    mechanisms which can play havoc with our abstractions, that compels us 
>>    to call for changes in the language with regard to the ability to
>>    define specific procedures for assignment and destruction which are 
>>    taken into consideration by these mechanisms. 
> 
> We can argue about implicitly invoked destruction mechanisms some other time, 
> since Ada provides no such animal.  And Ada's parameter passing mechanisms 
> are defined implicitly, beyond the reach of the programmer, as they should 
> be (again to enforce type checking)--they have nothing to do with assignment 
> at the source level.  Regarding your assignment "abstraction", all I can 
> offer is the suggestion that reduction to LCD form is an over-specification 
> of what I consider to be the normal semantics of an assignment operation, 
> and it is better left to another procedure [...]

   The LCD example is not mine, and I'll leave it to the author of the
   example to make whatever counterpoints are appropriate.  But with regard
   to the point concerning enforcement of type checking, I'd like to point
   out that the example you gave was one in which you did NOT define an ADT;
   all you did was define a local record type.  I made the suggestion earlier
   that the definition of assignment, comparison, and other operators be
   restricted to the package specification in which the (limited) private 
   ADT type was defined.  The intent was to prohibit the implementation of
   an assignment operator over some limited private type declared somewhere
   else (e.g., TEXT_IO.FILE_TYPE).  Another point: the ADT-handling package
   could leave the denominator as an undefined integer if it jolly well
   felt like it, as long as it met the requirements imposed by the package
   specification.  I don't see how that would constitute any violation of
   type checking.  
   
>>    It is entirely possible that given the desire of AJPO to minimize the
>>    extent of changes in the language, it will not be possible to get Ada
>>    to provide complete support for the abstract data type paradigm.  Ada
>>    was explicitly intended as an interim solution, covering the range
>>    1983..20xx, and not as "the perfect language".  Perhaps for Ada it is
>>    already too late.  But the issue needs to be thoroughly discussed,
>>    because it is a major area in which Ada has "missed the boat". 
> 
> I tend to agree with your last comment.  But Ada's abstraction mechanisms 
> will never be improved in the next revision without a proposal that is 
> carefully thought out and is fully consistent with the goals of the 
> language.  As I've tried to illustrate, none of the proposals I've seen 
> for assignment overloading come close to meeting these criteria.

    I think providing complete support for the abstract data type paradigm
    is fully consistent with the goals of the language; as for carefully
    thought out proposals, a major purpose of this discussion is to uncover
    bugs in the details of the proposal prior to filing the 9X revision
    forms (which were made available by AJPO at Tri-Ada '88).  The points
    that have been made by you and others have done that.  Whether the 
    finalized request will be within AJPO's tolerance for change is,
    of course, still very much an open question.  But in this language
    or the next, the abstraction mechanisms available to programmers
    will be significantly stronger as a result. 


                                       Bill Wolfe

                                wtwolfe@hubcap.clemson.edu

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

* Re: Collective response to := messages
  1988-11-30 14:37   ` Stephe Leake
@ 1988-12-01 14:54     ` David S. Rosenblum
  1988-12-02 20:21       ` William Thomas Wolfe,2847,
  1988-12-07 16:07       ` Stephe Leake
  1988-12-01 21:31     ` Ray Trent
  1 sibling, 2 replies; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-01 14:54 UTC (permalink / raw)


In article <755@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>
>There seems to be a point of confusion concerning overloading of ":=".
>Some people assume that the (overloaded) semantics of ":=" apply to
>parameter passing. This seems to be a reasonable assumption, and I
>think the current Ada parameter passing semantics are equivalent to
>the current Ada assignment semantics.

They are not the least bit equivalent, for several reasons.  The most
obvious reason is that an implementation is free to pass composite
parameters by reference, although no implementation can "assign by
reference".  No source-level assignment operation is "invoked" to achieve
parameter passing.  Parameter passing is a language facility that is
implemented by the compiler, just as is, say, looping.

>However, other types of
>overloading (such as for "*") only apply when the overloaded symbol
>appears _explicitly_; thus an argument could be made that the
>overloaded ":=" should only be used for explicit assignments, not the
>implicit ones in parameter passing. Personally, I think parameter
>passing should be the same as assignment, but I just wanted to point
>out the confusion.

I personally believe such an interpretation of parameter passing creates
more confusion instead of less.  In essence, this interpretation adds yet
another special case to the scope and visibility rules--it allows a
subprogram call to "see past" a visible redefinition of assignment to
a predefined one that has been hidden.

>A : LCD_Fraction;
>B, C : Fraction;
>
>A := B /C ; 	-- illegal
>A := To_LCD_Fraction (B / C);	-- legal
>
>The example above brings up a suggestion; type names should be
>overloadable by functions, so we can define type conversion functions
>that look like the type conversions available to scalar types.

As I argued in the case of assignment, overloading of type conversion is
overloading of a basic operation, and such a facility would allow
one to circumvent type checking.  As you suggested above, we don't want
to turn Ada into C.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-01  3:09         ` William Thomas Wolfe,2847,
@ 1988-12-01 15:16           ` David S. Rosenblum
  1988-12-02 19:31             ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-01 15:16 UTC (permalink / raw)


In article <3702@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <10913@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
>
>   The LCD example is not mine, and I'll leave it to the author of the
>   example to make whatever counterpoints are appropriate.  But with regard
>   to the point concerning enforcement of type checking, I'd like to point
>   out that the example you gave was one in which you did NOT define an ADT;
>   all you did was define a local record type.

I constructed the example that way for clarity.  The arguments are just
as valid if I make the type private in some package.  The declared
objects would still be undefined, and the assignment of 0.0 would still
leave a component undefined.

Your suggestion of implementing ADTs as access types gets around the
problems I mentioned with parameter passing, but allowing overloading of
assignment then requires a great deal of faith (misguided in my view) in
the programmer to implement his or her ADTs in such a safe manner.  I
guess you could argue that many other language features have a similarly
implicit faith in the sanity of the programmer.

>   Another point: the ADT-handling package
>   could leave the denominator as an undefined integer if it jolly well
>   felt like it, as long as it met the requirements imposed by the package
>   specification.  I don't see how that would constitute any violation of
>   type checking.  

The ADT-handling package may feel like leaving a component undefined, but
Ada doesn't feel like leaving variables undefined after an assignment.
That's why such a user-defined assignment violates Ada's strong typing.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-11-30 16:29   ` David S. Rosenblum
  1988-11-30 18:29     ` William Thomas Wolfe,2847,
@ 1988-12-01 18:31     ` Ray Trent
  1988-12-02 14:49       ` David S. Rosenblum
  1 sibling, 1 reply; 64+ messages in thread
From: Ray Trent @ 1988-12-01 18:31 UTC (permalink / raw)


In an article dsr@hector.UUCP (David S. Rosenblum) writes:
>domains and algebras.  However, assignment is a concept that is peculiar to
>programming languages, so in a sense you're comparing apples and oranges.

Untrue. "Let S = foo" is an idea from mathematics. But this is an aside.

>And most "sensible" definitions of assignment that I know of describe
>assignment simply in terms of placing a value in a variable or memory 

Except C's definition, of course, which is that = is an operator that
returns a value and has a domain and range.

>meaning, but you are not able to override Ada's type checking.  Thus,
>allowing overloading of assignment (or any basic operation) would seriously
>weaken Ada's strong typing features.

I'm afraid unchecked programming already does that. If the language 
designers were sooooo concerned about strong typing, why was unchecked
programming included at all? Was it perhaps because programmers know
that strong typing is a crock? I'd rather have nastiness like non-strong
typing out in the open, rather than hidden away in places where it
can't necessarily be found. (like package bodies, for example)

>Ada's constraint language (such as LCD-ness).  So why stop with assignment?
>Wouldn't you need overloading of all the basic operations?  Suppose

Of course you would. (and do)

>	type EVEN is new INTEGER;
>which I want to constrain in a way that would require all variables of
>the type to have even values.  In order to enforce this constraint
[several other basic operations overloaded]

>For example, type conversions, qualifications, attribute evaluations and
>membership tests never propagate exceptions.  Yet what would be the effect

And why not? They often should.

>perform I/O on EVEN values.  How do I get the instantiation to enforce my
>evenness constraint?  First I would need another language change that requires

You shouldn't have to in a language that purports to have strong typing.
Simply using a value outside of the constraints of the ADT should raise
a constraint error.

I don't actually propose we change the language to allow assignment
overloading. It would cause too many problems at this late date.

I'm just saying it wasn't designed right the first time. I would
argue that if assignment cannot be overloaded in any situation then
"=" should not be overloadable in any situation. In fact, I think
it's inconsistant to allow overloading of any kind if you don't allow
overloading of all kinds. After all, it's just as easy to type
"FooReal(X)" and "FooInt(X)" as it is to type just "Foo(X)", right? hurm.
And more understandable, right? Might even be more readable, neh?
Not allowing ":=" to be overloaded because it's "special" is a kludge.



-- 
"Our little lives get complicated
 It's a simple thing
 Simple as a flower
 And that's a complicated thing"                     ../ray\..

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

* Re: Collective response to := messages
  1988-11-30 14:37   ` Stephe Leake
  1988-12-01 14:54     ` David S. Rosenblum
@ 1988-12-01 21:31     ` Ray Trent
  1988-12-07 16:21       ` Stephe Leake
  1 sibling, 1 reply; 64+ messages in thread
From: Ray Trent @ 1988-12-01 21:31 UTC (permalink / raw)


In the above article leake@cme-durer.ARPA (Stephe Leake) writes:
>does. It seems to me, therefore, that he is talking about 2 data
>types; LCD_Fractions and Fractions. This removes the need to overload

Indeed, this is the case. I explained that type Fraction was not a 
particularly good example, and why I used it anyway. I mostly object
to the internal inconsistancies of Ada...exceptions to the rules
for "special" operators, the non-object status of certain types
of procedural objects and not others, disallowing user definition
of attributes, the wierdnesses inherent in the "use" clause that
make it almost useless, the fact that Ada is supposed to 
be strongly typed, but that uninitialized variables of a type
are not required to contain a valid value in the range of that type,
and are also not required to contain an *invalid* value, etc., etc.

>Ray Trent says:
>	> The LRM explicitly says that intermediate
>	> results need not follow the constraints of the ADT.
>Where does it say this?

LRM 11.6 [6] states: Similarly, additional freedom is left to an 
implementation for the evaluation of numeric simple expressions. For
the evaluation of a predefined operation, an implementation is 
allowed to use the operation of a type that has a range wider than that of
the base type of the operands, provided that this delivers the exact result,
even if some intermediate results lie outside the range of the base type.

They only explicitly allow this for predefined operations, though it's
ambiguous enough that vendors are likely to allow it for user-defined
operations as well. (and it's kind of hard to test) I object to "special"
properties of language constructs that I am not "allowed" as a programmer
to use or duplicate in my own types, subprograms, etc., in any event.

-- 
"Our little lives get complicated
 It's a simple thing
 Simple as a flower
 And that's a complicated thing"                     ../ray\..

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

* Re: Collective response to := messages
  1988-12-01 18:31     ` Ray Trent
@ 1988-12-02 14:49       ` David S. Rosenblum
  0 siblings, 0 replies; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-02 14:49 UTC (permalink / raw)


In article <24922@sri-unix.SRI.COM> trent@unix.sri.com (Ray Trent) writes:
>In an article dsr@hector.UUCP (David S. Rosenblum) writes:
>>domains and algebras.  However, assignment is a concept that is peculiar to
>>programming languages, so in a sense you're comparing apples and oranges.
>
>Untrue. "Let S = foo" is an idea from mathematics. But this is an aside.

This is NOT assignment as we know it in programming languages.  You don't
later assign new values to S, there is no "storage" of foo in S, etc.  Your
expression is simply a use of the equality relation to state an assumption
or axiom.  You are guaranteed from the substitutivity of equality that ALL
subsequent occurrences of S may be replaced by "foo".  Substitutivity of
this kind is not a property of assignment.

>>And most "sensible" definitions of assignment that I know of describe
>>assignment simply in terms of placing a value in a variable or memory 
>
>Except C's definition, of course, which is that = is an operator that
>returns a value and has a domain and range.

Yes, assignment in C is an operator.  And you've just justified further the
argument that Ada's assignment is NOT an operator, since it returns no
value.  It's seems silly to use such high-falutin' terms as "domain" and
"range" to describe assignment in C though, because due to C's weak enforcement
of type constraints, assignment can operate on arbitrary unions of domains.

>>meaning, but you are not able to override Ada's type checking.  Thus,
>>allowing overloading of assignment (or any basic operation) would seriously
>>weaken Ada's strong typing features.
>
>I'm afraid unchecked programming already does that. If the language 
>designers were sooooo concerned about strong typing, why was unchecked
>programming included at all? Was it perhaps because programmers know
>that strong typing is a crock? I'd rather have nastiness like non-strong
>typing out in the open, rather than hidden away in places where it
>can't necessarily be found. (like package bodies, for example)

Yes, unchecked programming is provided in the language, but its use is heavily
discouraged.  The semantics of unchecked programming are largely left to the
discretion of the implementor, therefore making unchecked programming
a highly non-portable feature of the language.  And note the following
(admittedly difficult-to-enforce) admonition in the LRM:  "Whenever unchecked
conversions are used, it is the programmer's responsibility to ensure
that these conversions maintain the properties that are guaranteed by the
language for objects of the target type.  Programs that violate these
properties by means of unchecked conversions are erroneous."
(Book 13, Chapter 10.2, Verse 3).

"Correct use" of Ada demands a good faith effort to construct portable
programs.  (Pardon the weasel wording.)  If you believe strong typing to
be a crock (and I'm one programmer that DOESN'T "know" that it's a
crock), then why are you lamenting the unsatisfactory character of
Ada's abstraction mechanisms?  (Maybe you never said this; I'm getting confused
as to who has argued what.)  C gives you all the "abstraction" mechanisms
you seem to desire--a wide open window to the implementation details of
your data types.

We seem to be getting away from the subject.  Somebody has suggested
allowing overloading of assignment in Ada.  I have been arguing against
this proposal from the hypothetical viewpoint of a person in charge of
updating the language.  Arguments about some of Ada's fundamental language
philosophies seem out of place in this context.

>I'm just saying it [assignment] wasn't designed right the first time. I would
>argue that if assignment cannot be overloaded in any situation then
>"=" should not be overloadable in any situation. In fact, I think
>it's inconsistant to allow overloading of any kind if you don't allow
>overloading of all kinds.

This seems like an arbitrary argument.  Overloading of operators
(in the Ada sense) seems justifiable, since the operators aren't
directly concerned with the semantics of strong typing.  You can
give kooky semantics to your favorite mathematical operator, but those
semantics may be characteristic of an abstraction.  However, overloading
of Ada's basic operations does not seem justifiable, because they are
intimately concerned with the implementation of strong typing.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-11-30 18:24   ` Robert Eachus
@ 1988-12-02 14:58     ` David S. Rosenblum
  0 siblings, 0 replies; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-02 14:58 UTC (permalink / raw)


In article <42334@linus.UUCP> eachus@mbunix.mitre.org (Robert I. Eachus) writes:
|
|     "Overloading is defined for subprograms, enumeration literals,
|operators, and single entries, and also for the operations that are
|inherent in several basic operations such as assignment, membership
|tests, allocators, the literal null, aggregates, and string literals."
|
|      Overloading, and overload resolution involving basic operations
|is a fact of Ada life.

Yes, but there is an important difference between overloading of operators,
subprograms, etc., and overloading of basic operations.  Overloaded basic
operations are ALWAYS implicitly defined--they can NEVER be user-defined.
It is the proposal to allow user-defined overloadings of basic operations
that is prompting all the "frothing".


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-01 15:16           ` David S. Rosenblum
@ 1988-12-02 19:31             ` William Thomas Wolfe,2847,
  1988-12-04 21:03               ` David S. Rosenblum
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-02 19:31 UTC (permalink / raw)


From article <10918@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> 
> The ADT-handling package may feel like leaving a component undefined, but
> Ada doesn't feel like leaving variables undefined after an assignment.
> That's why such a user-defined assignment violates Ada's strong typing.

      Really?  Consider the following:

         procedure FUN_WITH_UNDEFINED_VARIABLES is

            A : INTEGER;    -- A is undefined...
            B : INTEGER;    -- B is undefined...
         
         begin
            A := B;   -- Quick, what value does A have? 
         end FUN_WITH_UNDEFINED_VARIABLES;

      This compiles and executes under Alsys Ada.

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

* Re: Collective response to := messages
  1988-11-29 21:08 ` Ray Trent
                     ` (2 preceding siblings ...)
  1988-11-30 18:24   ` Robert Eachus
@ 1988-12-02 19:34   ` Mark C. Adolph
  3 siblings, 0 replies; 64+ messages in thread
From: Mark C. Adolph @ 1988-12-02 19:34 UTC (permalink / raw)


In article <24856@sri-unix.SRI.COM>, trent@unix.SRI.COM (Ray Trent) writes:
> The LRM explicitly says that intermediate
> results need not follow the constraints of the ADT. 

Could you cite this in the LRM?  This could be a very important point for
we who are trying to model physical quantities (length, temperature,
density, etc.) as derived types and trying to do operations on these
types.

-- 

					-- Mark A.
					...uw-beaver!ssc-vax!adolph

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

* Re: Collective response to := messages
  1988-12-01 14:54     ` David S. Rosenblum
@ 1988-12-02 20:21       ` William Thomas Wolfe,2847,
  1988-12-04 21:15         ` David S. Rosenblum
  1988-12-07 16:07       ` Stephe Leake
  1 sibling, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-02 20:21 UTC (permalink / raw)


From article <10917@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> In article <755@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
>>
>>There seems to be a point of confusion concerning overloading of ":=".
>>Some people assume that the (overloaded) semantics of ":=" apply to
>>parameter passing. This seems to be a reasonable assumption, and I
>>think the current Ada parameter passing semantics are equivalent to
>>the current Ada assignment semantics.
> 
> They are not the least bit equivalent, for several reasons.  The most
> obvious reason is that an implementation is free to pass composite
> parameters by reference, although no implementation can "assign by
> reference". 

    Sure, for "in out" mode.  But for modes "in" and "out", failure to
    use the ADT's assignment procedure causes major problems:

      "out" mode:  Programmer assigns the parameter a value, and the
                   value is copied back to the actual parameter.  
                   Unfortunately, the portions of the actual parameter
                   which were formerly accessible by pointers are now
                   uncollectable garbage.

       "in" mode:  Programmer assumes that this is a "pass by value"
                   and makes modifications.  Since ADT contains pointers,
                   modification echoes through to the actual parameter.
                   Programmer could also invoke DESTROY, blowing away
                   major portions of the actual parameter.

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

* Re: Collective response to := messages
@ 1988-12-03 21:08 Erland Sommarskog
  1988-12-04 20:30 ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: Erland Sommarskog @ 1988-12-03 21:08 UTC (permalink / raw)


Geoff Mendal (mendal@ANNA.STANFORD.EDU) writes:
>>The argument that pre-processors can be used to acheive this effect is
>>bull. It ignores the absolute fact that *no one* maintains, reads, or
>>is expected to understand the processed code. This is a null argument.
>
>Quite the contrary.  The whole idea of a pre-processor or translation
>tool is to remove the need to "read" the processed version.  How many
>...
>So why is it that defining a mapping from some pre-processor to Ada is
>met with such cynicism?  It simply provides an additional layer of
>abstraction,

Pre-processors are OK, if they don't appear to you as pre-processors.
For example you must make the debugger to work on the original code,
not what the pre-processor produces. Also, the pre-processor should
be genrally available, or else you will lose portability.

Many of Geoff Mendal's ideas are reasonable. Yet, I like to provide 
some examples you might long for an overloadable ":=".

When we declare our variables in blocks we often initiate them. This
makes us feel safe, we know that the variable has a defined value,
and we can deduce so by looking at the declaration part. Since ":="
is not overloadable, we cannot initiate a limited private type in a
declaration. E.g. (Text is from the Text_handler in 7.6 of the LRM.)
   A : Text := To_text("Test string");
is illegal.

My other point concerns generic parameters. I once wrote a generic
package for sorted binary trees. It's parameter list looks like this:

   Generic
      Type Data_type is limited private;
      With procedure Assign(A : in out Data_type;
                            B : in     Data_type);
      With function "<"(A, B : Data_type) return boolean is <>;
      With function ">"(A, B : Data_type) return boolean is <>;
   Package Binary_trees is

With an overloadable ":=" I could have declared the second parameter as

      With procedure ":="(A : in out Data_type;
                          B : in     Data_type) is <>;

This would save the user from declaring unnecessary Assign for types like
integer. This Assign procedure he has to write is simple, but is 100% noise 
to his code.
  (Of course I could make Data_type Private only, but in this case the user
would be unnecessarily restriced, since he would be able to instantiate
it for limited types.)

Again this was some examples since Geoff Mendall wanted some. None of
them shows that you "must" have overloadable ":=". Just some case  
there it would be nice.

Oh, someone thought that an user-defined ":=" should apply to parameter
passing as well. This is of course impossible. In that case ":=" should
define how the parameters were passed to itself. A true circular definition!
-- 
Erland Sommarskog
ENEA Data, Stockholm
sommar@enea.se
"Frequently, unexpected errors are entirely unpredictable" - Digital Equipment

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

* Re: Collective response to := messages
@ 1988-12-03 22:53 Erland Sommarskog
  1988-12-04 20:41 ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: Erland Sommarskog @ 1988-12-03 22:53 UTC (permalink / raw)


William Thomas Wolfe (billwolf@hubcap.clemson.edu) writes:
>     What is needed is a completion of the ADT paradigm, support for
>     which is the fundamental reason for the "limited private" feature.
>     Given that one must remember to destroy all non-predefined ADTs 
>     upon block exit, it is clear that the implications of this paradigm 
>     were not appropriately considered in the Ada 83 design. 

With other words, what you want is garbage collection. I'm quite
sure that the language designers knew about. Simula has had since
1967. Note that the language definition in no way forbids garbage
collection, but it does not require it. It says: 4.8(7) "An 
implementation may (but need not) reclaim the storage occupied by an 
object created by an allocator, once this object has become inaccessible".
In practice this means you must do all deallocating explictly if you
want to be partable.
  I think the reason why garbage collection is not required is that 
in some applications this is not very desireable from the point of 
view or performance. Typically you may not want it embedded real-time 
systems... Another thing is of course the implementation issue...

But as you point out, this is an important concept when implementing
abstract data types. I think that Ada should require garbage collection
and a pragma with which you could turn it off for critical code.
-- 
Erland Sommarskog
ENEA Data, Stockholm
sommar@enea.se
"Frequently, unexpected errors are entirely unpredictable" - Digital Equipment

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

* Re: Collective response to := messages
  1988-12-03 21:08 Erland Sommarskog
@ 1988-12-04 20:30 ` William Thomas Wolfe,2847,
  0 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-04 20:30 UTC (permalink / raw)


From article <4123@enea.se>, by sommar@enea.se (Erland Sommarskog):
> Oh, someone thought that an user-defined ":=" should apply to parameter
> passing as well. This is of course impossible. In that case ":=" should
> define how the parameters were passed to itself. A true circular definition!

    Recall the discussion.  The rule that the "old" version of assign
    would apply throughout any function named ":=", including parameter
    passing, handles this contingency.

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

* Re: Collective response to := messages
  1988-12-03 22:53 Collective response to := messages Erland Sommarskog
@ 1988-12-04 20:41 ` William Thomas Wolfe,2847,
  1988-12-05  5:47   ` Richard A. O'Keefe
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-04 20:41 UTC (permalink / raw)


From article <4125@enea.se>, by sommar@enea.se (Erland Sommarskog):
> William Thomas Wolfe (billwolf@hubcap.clemson.edu) writes:
>>     What is needed is a completion of the ADT paradigm, support for
>>     which is the fundamental reason for the "limited private" feature.
>>     Given that one must remember to destroy all non-predefined ADTs 
>>     upon block exit, it is clear that the implications of this paradigm 
>>     were not appropriately considered in the Ada 83 design. 
# 
# With other words, what you want is garbage collection.  
# [...]  I think the reason why garbage collection is not required is that 
# in some applications this is not very desireable from the point of 
# view of performance. Typically you may not want it embedded real-time 
# systems... Another thing is of course the implementation issue...

   No, I do NOT want garbage collection.  Since GC cannot handle the
   problems of circular-list garbage without outrageous time expenditures,
   and for all the other reasons you mentioned above, GC is NOT desirable.
   Furthermore, GC encourages sloppy programming.  I'd be very happy to see
   GC explicitly PROHIBITED.


                                       Bill Wolfe

                               wtwolfe@hubcap.clemson.edu

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

* Re: Collective response to := messages
  1988-12-02 19:31             ` William Thomas Wolfe,2847,
@ 1988-12-04 21:03               ` David S. Rosenblum
  1988-12-05  2:34                 ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-04 21:03 UTC (permalink / raw)


In article <3720@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
|From article <10918@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
|> 
|> The ADT-handling package may feel like leaving a component undefined, but
|> Ada doesn't feel like leaving variables undefined after an assignment.
|> That's why such a user-defined assignment violates Ada's strong typing.
|
|      Really?  Consider the following:
|
|         procedure FUN_WITH_UNDEFINED_VARIABLES is
|
|            A : INTEGER;    -- A is undefined...
|            B : INTEGER;    -- B is undefined...
|         
|         begin
|            A := B;   -- Quick, what value does A have? 
|         end FUN_WITH_UNDEFINED_VARIABLES;

Easy.  A has a value that satisfies the constraints on INTEGER, which
implies that B does also.  We splitting hairs here, but I'll give it
to you--A is still undefined.

Note that you're relying on INTEGER being implicitly initialized with a valid
value; this is probably considered erroneous (I don't have an LRM
on hand).

|
|      This compiles and executes under Alsys Ada.

I don't doubt it.  Do you seriously regard this as "proof" that assignment
doesn't incorporate type checking?


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-02 20:21       ` William Thomas Wolfe,2847,
@ 1988-12-04 21:15         ` David S. Rosenblum
  1988-12-04 23:27           ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-04 21:15 UTC (permalink / raw)


In article <3721@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
|From article <10917@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
|> In article <755@marvin.cme-durer.ARPA> leake@cme-durer.ARPA (Stephe Leake) writes:
|>>
|>>There seems to be a point of confusion concerning overloading of ":=".
|>>Some people assume that the (overloaded) semantics of ":=" apply to
|>>parameter passing. This seems to be a reasonable assumption, and I
|>>think the current Ada parameter passing semantics are equivalent to
|>>the current Ada assignment semantics.
|> 
|> They are not the least bit equivalent, for several reasons.  The most
|> obvious reason is that an implementation is free to pass composite
|> parameters by reference, although no implementation can "assign by
|> reference". 
|
|    Sure, for "in out" mode.  But for modes "in" and "out", failure to
|    use the ADT's assignment procedure causes major problems:
|
|      "out" mode:  Programmer assigns the parameter a value, and the
|                   value is copied back to the actual parameter.  
|                   Unfortunately, the portions of the actual parameter
|                   which were formerly accessible by pointers are now
|                   uncollectable garbage.
|
|       "in" mode:  Programmer assumes that this is a "pass by value"
|                   and makes modifications.  Since ADT contains pointers,
|                   modification echoes through to the actual parameter.
|                   Programmer could also invoke DESTROY, blowing away
|                   major portions of the actual parameter.

I'm terribly confused.  Are we still talking about Ada?  With this talk
about parameter passing invoking source-level assignment, I'm not so sure.
I'm not sure what your "out" mode comments refer to, but maybe you're
confusing what access values (pointers) can point to in Ada, or maybe you're
confusing how access values are passed as parameters in Ada--access values are
ALWAYS copied IN to their respective places in formal parameters, EVEN for
mode "out" formals.  Your "in" mode comments are also vague.  First of all,
"good" Ada programmers assume nothing about parameter passing behavior.
Second, an access value can be passed as a parameter, in which case the
language is concerned only with the access value during parameter passing,
NOT with the object designated by the access value.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-04 21:15         ` David S. Rosenblum
@ 1988-12-04 23:27           ` William Thomas Wolfe,2847,
  1988-12-05 14:46             ` David S. Rosenblum
  1988-12-07 17:15             ` Stephe Leake
  0 siblings, 2 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-04 23:27 UTC (permalink / raw)


From article <10960@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> |> They are not the least bit equivalent, for several reasons.  The most
> |> obvious reason is that an implementation is free to pass composite
> |> parameters by reference, although no implementation can "assign by
> |> reference". 
> |
> |    Sure, for "in out" mode.  But for modes "in" and "out", failure to
> |    use the ADT's assignment procedure causes major problems:
> |
> |      "out" mode:  Programmer assigns the parameter a value, and the
> |                   value is copied back to the actual parameter.  
> |                   Unfortunately, the portions of the actual parameter
> |                   which were formerly accessible by pointers are now
> |                   uncollectable garbage.
> |
> |       "in" mode:  Programmer assumes that this is a "pass by value"
> |                   and makes modifications.  Since ADT contains pointers,
> |                   modification echoes through to the actual parameter.
> |                   Programmer could also invoke DESTROY, blowing away
> |                   major portions of the actual parameter.
> 
> I'm terribly confused.  Are we still talking about Ada?  With this talk
> about parameter passing invoking source-level assignment, I'm not so sure.
> I'm not sure what your "out" mode comments refer to, but maybe you're
> confusing what access values (pointers) can point to in Ada, or maybe you're
> confusing how access values are passed as parameters in Ada--access values are
> ALWAYS copied IN to their respective places in formal parameters, EVEN for
> mode "out" formals.  

     OK.  Envision an ADT which just happens to be implemented as a pointer
     to a descriptor, which probably has more pointers to the "value".  Now
     our ADT user wishes to transfer an ADT "out".  The ADT user has no idea
     how the ADT is implemented.  Now when the procedure was invoked, let's 
     assume that the ADT supplied as an actual parameter had some value;
     hence, the pointer which represents the "ADT type" is not null, and 
     in fact constitutes the only known method for accessing a substantial
     amount of utilized memory.  Our ADT user sends the value "out", and
     Ada implements this by copying the value of a single pointer.  The old
     pointer value associated with the actual parameter is lost forever,
     and all the stuff it pointed to is now garbage.
 
> Your "in" mode comments are also vague.  First of all,
> "good" Ada programmers assume nothing about parameter passing behavior.

     Anything which is passed as an "in" parameter should be treatable as
     something which was passed in by value.  Anything which is passed as
     an "in out" parameter should be treatable as something which was passed
     by reference.  Anything which is passed as an "out" parameter should
     be treated as the target of a pass by value in the "outward" direction.

     If nothing can be assumed about parameter passing behavior, then 
     parameter passing is just too vaguely defined, and needs to be clarified.

> Second, an access value can be passed as a parameter, in which case the
> language is concerned only with the access value during parameter passing,
> NOT with the object designated by the access value.

     When what is being passed is known to the user as an access value,
     this is precisely what the programmer expects.  When what is being
     passed is known to the user as an ADT, this sort of behavior is
     totally counterintuitive.  It violates the abstraction.


                                          Bill Wolfe

                                  wtwolfe@hubcap.clemson.edu

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

* Re: Collective response to := messages
  1988-12-04 21:03               ` David S. Rosenblum
@ 1988-12-05  2:34                 ` William Thomas Wolfe,2847,
  1988-12-05 14:07                   ` David S. Rosenblum
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-05  2:34 UTC (permalink / raw)


From article <10959@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> In article <3720@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
> |From article <10918@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
> |> 
> |> The ADT-handling package may feel like leaving a component undefined, but
> |> Ada doesn't feel like leaving variables undefined after an assignment.
# |> That's why such a user-defined assignment violates Ada's strong typing.
# |
# |         [FUN_WITH_UNDEFINED_VARIABLES]
# 
# Easy.  A has a value that satisfies the constraints on INTEGER, which
% implies that B does also.  We splitting hairs here, but I'll give it
% to you--A is still undefined.
% 
% Note that you're relying on INTEGER being implicitly initialized with a valid
% value; this is probably considered erroneous (I don't have an LRM
@ on hand).
@ 
@ |
@ |      This compiles and executes under Alsys Ada.
@ 
@ I don't doubt it.  Do you seriously regard this as "proof" that assignment
@ doesn't incorporate type checking?

     Well, you are quoted above as saying (correct me if I'm wrong...) that
     Ada somehow required that a variable be defined after assignment, and
     that a user-defined assignment such as the one you described could leave
     a component undefined and therefore violate strong typing.  

     As far as I'm concerned, if we implemented your example as a user-defined
     ADT, the only problem that could occur would be failure of the implementor
     to properly respond to a request for the value of the denominator.  If the
     implementor handles the request properly, it wouldn't matter if there were
     undefined components; the user can never access them anyway, and in general
     will never know the difference.  In other words, the implementor may well
     view the state in which the denominator is undefined as a valid state of
     the ADT.  I see nothing wrong with that. 
  

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

* Re: Collective response to := messages
  1988-12-04 20:41 ` William Thomas Wolfe,2847,
@ 1988-12-05  5:47   ` Richard A. O'Keefe
  1988-12-05 12:45     ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: Richard A. O'Keefe @ 1988-12-05  5:47 UTC (permalink / raw)


In article <3733@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>   No, I do NOT want garbage collection.  Since GC cannot handle the
>   problems of circular-list garbage without outrageous time expenditures,

Are you up-to-date on this?  There has been a lot of work done on GC in
the last 5 years.

>   Furthermore, GC encourages sloppy programming.

How so?  Have you some data on this?  I very much prefer languages with
automatic storage management (Lisp, Pop, Prolog, Simula 67, SmallTalk, ...)
because there is a large class of mistakes you simply can't make (e.g.
referring to nonexistent storage) and the only real sacrifice in
expressiveness is that it is harder to write programs which crash when a
fixed-size buffer overflows (:-).  It would be a service if you could
elaborate on this:  if I knew what sort of sloppiness was encouraged I
could more effectively try to avoid it.

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

* Re: Collective response to := messages
@ 1988-12-05  6:53 Erland Sommarskog
  0 siblings, 0 replies; 64+ messages in thread
From: Erland Sommarskog @ 1988-12-05  6:53 UTC (permalink / raw)


William Thomas Wolfe (billwolf@hubcap.clemson.edu) writes:
>I said:
>> Oh, someone thought that an user-defined ":=" should apply to parameter
>> passing as well. This is of course impossible. In that case ":=" should
>> define how the parameters were passed to itself. A true circular definition!
>
>    Recall the discussion.  The rule that the "old" version of assign
>    would apply throughout any function named ":=", including parameter
>    passing, handles this contingency.

So there should be one rule for passing parameters to ":=" and another
to all other subprograms? That, if nothing else, shows that there is
something wrong with the idea. You expect all subprograms to behave
the same. What if ":=" is renamed? Should the rules change? And if
":=" calls another subprogram, what rules should be applied in this
case?
  Unless you don't want to fill the language definition with special
cases, and I don't, the idea to have a user-defined ":=" to implicitly
define parameter passing seems dead. If you really want it that way
you should think of some new syntactic device for defining assignment
of a limited type.
-- 
Erland Sommarskog
ENEA Data, Stockholm
sommar@enea.se
"Frequently, unexpected errors are entirely unpredictable" - Digital Equipment

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

* Re: Collective response to := messages
  1988-12-05  5:47   ` Richard A. O'Keefe
@ 1988-12-05 12:45     ` William Thomas Wolfe,2847,
  1988-12-06  1:54       ` Richard A. O'Keefe
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-05 12:45 UTC (permalink / raw)


From article <808@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> In article <3733@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>>   No, I do NOT want garbage collection.  Since GC cannot handle the
>>   problems of circular-list garbage without outrageous time expenditures,
> 
> Are you up-to-date on this?  There has been a lot of work done on GC in
> the last 5 years.

    No, I'm not, but I'll bet GC still can't be done in O(n) time 
    with regard to the number of items of garbage, with constants
    no greater than the overhead of a deallocation...

>>   Furthermore, GC encourages sloppy programming.
> 
> It would be a service if you could elaborate on this [...]

    The programmer is Johnny-on-the-spot.  He/she KNOWS whether or not
    a given object is no longer needed.  All that is necessary is an 
    indication of this fact via the command DESTROY (Unneeded_Object).

    If the programmer is sloppy and leaves garbage lying all over the place,
    the "maid" must do all the hard work of deciding what to keep 
    and what to throw out.  Furthermore, this price must be paid
    repeatedly at execution time.  This is a heavy price to pay for
    not simply designing it right the first time.  

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

* Re: Collective response to := messages
  1988-12-05  2:34                 ` William Thomas Wolfe,2847,
@ 1988-12-05 14:07                   ` David S. Rosenblum
  1988-12-07 17:26                     ` Stephe Leake
  0 siblings, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-05 14:07 UTC (permalink / raw)


In article <3736@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
|
|     Well, you are quoted above as saying (correct me if I'm wrong...) that
|     Ada somehow required that a variable be defined after assignment, and
|     that a user-defined assignment such as the one you described could leave
|     a component undefined and therefore violate strong typing.  

Yes, that was an exaggeration that I am more than happy to retract.  Replace
that statement with "Ada doesn't feel like allowing a variable to have
a value outside of its type after an assignment to the variable.  Your
example certainly didn't demonstrate any weaknesses in Ada's type checking
semantics, which has been the real crux of the whole discussion.

|
|     As far as I'm concerned, if we implemented your example as a user-defined
|     ADT, the only problem that could occur would be failure of the implementor
|     to properly respond to a request for the value of the denominator.  If the
|     implementor handles the request properly, it wouldn't matter if there were
|     undefined components; the user can never access them anyway, and in general
|     will never know the difference.  In other words, the implementor may well
|     view the state in which the denominator is undefined as a valid state of
|     the ADT.  I see nothing wrong with that. 
|  

For the umpteenth time, the point of my example was to show that user-definable
assignment is a means of circumventing type checking.  I was not concerned
with the mindset of the implementor or the user of the abstraction--we can
talk all day about what an ideal safe programmer would do.  If you
find such a weak semantics for := acceptable, then you are certainly entitled
to your opinion.  I'm just suggesting that you'll probably never see
such a semantics in Ada.

I'm afraid I've exhausted whatever supply of insight I may have been able
to offer on assignment overloading.  I feel I've spent more space quoting
the reference manual on language fundamentals than I have on arguing any
substantive points.  In short, Ada is not a language to consider using if you
desire (1) condoned mechanisms for circumventing type checking, (2) parameter
passing mechanisms defined in terms of assignment, as assignment is defined
at the source level.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-04 23:27           ` William Thomas Wolfe,2847,
@ 1988-12-05 14:46             ` David S. Rosenblum
  1988-12-05 21:23               ` William Thomas Wolfe,2847,
  1988-12-07 17:15             ` Stephe Leake
  1 sibling, 1 reply; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-05 14:46 UTC (permalink / raw)


In article <3734@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
|     OK.  Envision an ADT which just happens to be implemented as a pointer
|     to a descriptor, which probably has more pointers to the "value".  Now
|     our ADT user wishes to transfer an ADT "out".  The ADT user has no idea
|     how the ADT is implemented.  Now when the procedure was invoked, let's 
|     assume that the ADT supplied as an actual parameter had some value;
|     hence, the pointer which represents the "ADT type" is not null, and 
|     in fact constitutes the only known method for accessing a substantial
|     amount of utilized memory.  Our ADT user sends the value "out", and
|     Ada implements this by copying the value of a single pointer.  The old
|     pointer value associated with the actual parameter is lost forever,
|     and all the stuff it pointed to is now garbage.

The language already has a very nice feature to handle such situations.
It's called the "limited type".  By implementing your ADT as a limited
type, you deny the user of the ADT the ability to assign to variables and
in-out and out mode parameters of the type.  The only way to assign
to such a parameter or variable is to pass it to a subprogram that is
part of the implementation of the ADT.  That subprogram can then reclaim
the storage refernced by the access value if it decides to give the parameter
a new value.  Geoff Mendal did a nice paper on the encapsulation of storage
reclamation mechanisms inside user-defined ADTs in a paper he gave at a
recent SIGAda (you can get a copy from him).

|     Anything which is passed as an "in" parameter should be treatable as
|     something which was passed in by value.  Anything which is passed as
|     an "in out" parameter should be treatable as something which was passed
|     by reference.  Anything which is passed as an "out" parameter should
|     be treated as the target of a pass by value in the "outward" direction.
|
|     If nothing can be assumed about parameter passing behavior, then 
|     parameter passing is just too vaguely defined, and needs to be clarified.

You'll have to take this up with the Ada Language Maintenance Committee.
The language designers, and many Ada programmers, believe it to be as
clearly defined as it needs to be so that portable programs may be written.

|     When what is being passed is known to the user as an access value,
|     this is precisely what the programmer expects.  When what is being
|     passed is known to the user as an ADT, this sort of behavior is
|     totally counterintuitive.  It violates the abstraction.

Right.  So as I said above, define the ADT as limited private, so that
you (as the implementor of the ADT) can have complete control over the
use of the ADT.  That way the user of the ADT won't be able to violate the
abstraction.

Back to work.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Collective response to := messages
  1988-12-05 14:46             ` David S. Rosenblum
@ 1988-12-05 21:23               ` William Thomas Wolfe,2847,
  1988-12-07 17:33                 ` Stephe Leake
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-05 21:23 UTC (permalink / raw)


From article <10963@ulysses.homer.nj.att.com>, by dsr@hector.UUCP (David S. Rosenblum):
@ By implementing your ADT as a limited
@ type, you deny the user of the ADT the ability to assign to variables and
@ in-out and out mode parameters of the type.  The only way to assign
# to such a parameter or variable is to pass it to a subprogram that is
# part of the implementation of the ADT.  That subprogram can then reclaim
# the storage refernced by the access value if it decides to give the parameter
# a new value.  

   Sure, except for the circumvention of the provided ASSIGN routine which
   occurs every time the ADT is passed as an "in" or "out" parameter.

   There is no way to deny the user this particular method of circumventing
   your assignment routine, or even to have the compiler warn the user
   that a limited private ADT cannot be relied upon as a value parameter.
   
> |     When what is being passed is known to the user as an access value,
> |     this is precisely what the programmer expects.  When what is being
$ |     passed is known to the user as an ADT, this sort of behavior is
$ |     totally counterintuitive.  It violates the abstraction.
$ 
$ Right.  So as I said above, define the ADT as limited private, so that
% you (as the implementor of the ADT) can have complete control over the
% use of the ADT.  That way the user of the ADT won't be able to violate the
% abstraction.

    Except by way of the parameter passing mechanism.

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

* Re: Collective response to := messages
  1988-12-05 12:45     ` William Thomas Wolfe,2847,
@ 1988-12-06  1:54       ` Richard A. O'Keefe
  1988-12-06 20:43         ` William Thomas Wolfe,2847,
  1988-12-07 15:22         ` Collective response to := messa ron
  0 siblings, 2 replies; 64+ messages in thread
From: Richard A. O'Keefe @ 1988-12-06  1:54 UTC (permalink / raw)


In article <3740@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
>From article <808@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>> It would be a service if you could elaborate on this [...]

>    The programmer is Johnny-on-the-spot.  He/she KNOWS whether or not
>    a given object is no longer needed.  All that is necessary is an 
>    indication of this fact via the command DESTROY (Unneeded_Object).

This simply isn't true.  If I write a library routine which is passed
some linked data structure, I may be able to tell whether my traversal
of it has finished, but that leaves me with no idea whatsoever of
whether I was given the last reference to it (in which case now is the
time to delete it) or not.  Or suppose some "object" has references to
some other objects, and I DESTROY(..) the first object.  Should it
DESTROY(..) the other objects?  In that case it may destroy things which
other objects still refer to!  But if it doesn't, and it held the only
references to those objects, their space will not be reclaimed.  Is
Johnny on the spot?  NO!  The programmer who coded the implementation
of that object has _no_idea_ how other programmers will use it.  There
has been quite a lot of discussion about this in comp.lang.c++ .

     Let me apply billwolf@hubcap's general principle to another case:

	The programmer is Johnny-on-the-spot.  He/she KNOWS whether a
	given object is an integer or a float.  All that is necessary
	is an indication of this fact via the use of + for integers
	and #+ for floats.  We don't need any of this strong typing
	nonsense!

Automatic storage management, like automatic operator selection, means
that the programmer misses an opportunity to make a mistake.  There 
_are_ garbage collection methods around where the overhead of
garbage collection is a constant times the cost of allocation.

ADA was explicitly designed not to require garbage collection.
Since it was meant to be useful for real-time work, that was appropriate.

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

* Re: Collective response to := messages
  1988-12-06  1:54       ` Richard A. O'Keefe
@ 1988-12-06 20:43         ` William Thomas Wolfe,2847,
  1988-12-07 15:22         ` Collective response to := messa ron
  1 sibling, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-06 20:43 UTC (permalink / raw)


From article <812@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> In article <3740@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
>>From article <808@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
>>> It would be a service if you could elaborate on this [...]
> 
>>    The programmer is Johnny-on-the-spot.  He/she KNOWS whether or not
$>    a given object is no longer needed.  All that is necessary is an 
$>    indication of this fact via the command DESTROY (Unneeded_Object).
$ 
$ This simply isn't true.  If I write a library routine which is passed
$ some linked data structure, I may be able to tell whether my traversal
$ of it has finished, but that leaves me with no idea whatsoever of
$ whether I was given the last reference to it (in which case now is the
$ time to delete it) or not.  

      Whether or not the library routine should DESTROY its parameter
      depends on how the library routine is defined.  How about a
      more specific example?

# Or suppose some "object" has references to
# some other objects, and I DESTROY(..) the first object.  Should it
# DESTROY(..) the other objects?  In that case it may destroy things which
# other objects still refer to!  But if it doesn't, and it held the only
# references to those objects, their space will not be reclaimed.  

     Again, we need specifics here.  I hope you aren't talking about
     structural sharing here, which should NEVER be seriously contemplated.
 
% Is Johnny on the spot?  NO!  The programmer who coded the implementation
% of that object has _no_idea_ how other programmers will use it.  

     The implementor has no idea what *applications* the object will be
     used in, but has almost total control (the exceptions occur during
     parameter passing and block exit) over the operations of the ADT.

& There _are_ garbage collection methods around where the overhead of
& garbage collection is a constant times the cost of allocation.
 
     I specified O(n) with respect to the cost of each DEallocation,
     with the cost no higher than the overhead of doing the deallocation.
     This implies that the garbage collection routine has the ability to
     magically know the size and location of each and every piece of garbage,
     and has no need to examine any non-garbage. 

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

* Re: Collective response to := messa
  1988-12-06  1:54       ` Richard A. O'Keefe
  1988-12-06 20:43         ` William Thomas Wolfe,2847,
@ 1988-12-07 15:22         ` ron
  1988-12-11 19:11           ` Garbage Collection William Thomas Wolfe,2847,
  1 sibling, 1 reply; 64+ messages in thread
From: ron @ 1988-12-07 15:22 UTC (permalink / raw)



Garbage collection certainly does not come for free, but it is extremely
useful.  It frees the programmer from the need to repeatedly write
sophisticated ADT deallocate routines and to deal with the potentially
massive book-keeping requirements for determining whether an object is in
fact garbage.  In general, lack of GC forces a programmer to invest a lot of
effort addressing issues that are not fundamentally related to the problem
domain.  My experience has also shown that problems of "slow heap leakage"
are among the hardest errors to correct.

An earlier posting claimed that a programmer should know what is and isn't
garbage, and that GC is therefore not needed.  This argument would never be
made by a programmer with experience writing serious applications using both
GC'd and non-GC'd languages.  It's quite possible that those without GC'd
programming experience don't even recognize the additional burden for what
it is.

I am not saying that garbage collection should or shouldn't be added to Ada.
I haven't really thought about all of the issues; there are clearly pros and
cons.  However, the argument against GC loses much of its credibility if
it contains an outright denial of the many positive aspects of GC.

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

* Re: Collective response to := messages
  1988-12-01 14:54     ` David S. Rosenblum
  1988-12-02 20:21       ` William Thomas Wolfe,2847,
@ 1988-12-07 16:07       ` Stephe Leake
  1988-12-09  3:15         ` David S. Rosenblum
  1 sibling, 1 reply; 64+ messages in thread
From: Stephe Leake @ 1988-12-07 16:07 UTC (permalink / raw)


In article <10917@ulysses.homer.nj.att.com> dsr@hector.UUCP (David S. Rosenblum) writes:

   As I argued in the case of assignment, overloading of type conversion is
   overloading of a basic operation, and such a facility would allow
   one to circumvent type checking.  As you suggested above, we don't want
   to turn Ada into C.

Type checking _cannot_ be circumvented by overloading of type
conversion! Consider:

type DEGREES is digits 6 range 0.0 .. 360.0;
type RADIANS is digits 6;

function DEGREES (Item : in RADIANS) return DEGREES
is
begin
	return Item * 180.0 / PI;	-- range constraint is checked!
end;

Since the underlying Ada type checking is done on the function result,
no circumvention of type checking is possible.

On the other hand, the fact that type conversion is a basic operation
is significant; allowing overloading would mean changing it to a
normal operation (is "normal" the complement of "basic"?), with
corresponding changes in visibility. As I see it, there are two gains;
first, I get to name my type conversion functions the same as the
implicit type conversions (ie DEGREES instead of TO_DEGREES).  Second,
I get to hide the implicit conversion, which is appropriate in the
case of DEGREES and RADIANS. However, Ada provides limited types for
hiding purposes, so this second point is not really valid (although a
limited type seems like a lot of effort for such a simple thing,
remember that Ada was intended for maintainers, not programmers :-).
So it probably isn't worth persuing. (Sigh - one of these days I'll
have a really good idea :-).

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-12-01 21:31     ` Ray Trent
@ 1988-12-07 16:21       ` Stephe Leake
  0 siblings, 0 replies; 64+ messages in thread
From: Stephe Leake @ 1988-12-07 16:21 UTC (permalink / raw)



In article <24934@sri-unix.SRI.COM> trent@unix.SRI.COM (Ray Trent) writes:

   ... I mostly object
   to the internal inconsistancies of Ada...exceptions to the rules
   for "special" operators, the non-object status of certain types
   of procedural objects and not others, disallowing user definition
   of attributes, the wierdnesses inherent in the "use" clause that
   make it almost useless, the fact that Ada is supposed to 
   be strongly typed, but that uninitialized variables of a type
   are not required to contain a valid value in the range of that type,
   and are also not required to contain an *invalid* value, etc., etc.

That is the purpose of this discussion; to find the "inconsistencies"
in Ada, and propose solutions. So far, I don't think any of the
proposed solutions are better than what we already have. Certainly Ada
is more consistent than C! Also remember that Ada is very powerful,
and is _not_ simple; things that may appear inconsistent are actually
logical consequences of this power.

   LRM 11.6 [6] states: Similarly, additional freedom is left to an 
   implementation for the evaluation of numeric simple expressions. For
   the evaluation of a predefined operation, an implementation is 
   allowed to use the operation of a type that has a range wider than that of
   the base type of the operands, provided that this delivers the exact result,
   even if some intermediate results lie outside the range of the base type.

   They only explicitly allow this for predefined operations, though it's
   ambiguous enough that vendors are likely to allow it for user-defined
   operations as well. (and it's kind of hard to test) I object to "special"
   properties of language constructs that I am not "allowed" as a programmer
   to use or duplicate in my own types, subprograms, etc., in any event.

I don't see any ambiguity: "numeric simple expressions" and
"predefined operations" are very well defined, and user ADT's do not
fit the definitions!

On the other hand, I agree that this is a "special" exception to the
general rule. It has a very good justification, however; any hardware
must have only a few types (32 and 16 integers, 64 and 32 bit float,
for example) to be efficient (although I sometimes daydream about the
connection machine, where I could implement a 25 bit float if I wanted
to :-). Ada was intended to be a practical language, as well as an
abstract one.  Thus compromises are sometimes necessary.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-12-04 23:27           ` William Thomas Wolfe,2847,
  1988-12-05 14:46             ` David S. Rosenblum
@ 1988-12-07 17:15             ` Stephe Leake
  1 sibling, 0 replies; 64+ messages in thread
From: Stephe Leake @ 1988-12-07 17:15 UTC (permalink / raw)



In article <3734@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes:

	OK.  Envision an ADT which just happens to be implemented as a pointer
	to a descriptor, which probably has more pointers to the "value".  Now
	our ADT user wishes to transfer an ADT "out".  The ADT user has no idea
	how the ADT is implemented.  Now when the procedure was invoked, let's 
	assume that the ADT supplied as an actual parameter had some value;
	hence, the pointer which represents the "ADT type" is not null, and 
	in fact constitutes the only known method for accessing a substantial
	amount of utilized memory.  Our ADT user sends the value "out", and
	Ada implements this by copying the value of a single pointer.  The old
	pointer value associated with the actual parameter is lost forever,
	and all the stuff it pointed to is now garbage.

This is precisely the reason for limited private types; only functions
provide by the ADT package may have out parameters of the limited
type, so the ADT programmer can ensure correct behaviour, including
garbage collection and copying. This is a much simpler solution than
forcing parameter passing to use the ADT assignment operator.

	Anything which is passed as an "in" parameter should be treatable as
	something which was passed in by value.  Anything which is passed as
	an "in out" parameter should be treatable as something which was passed
	by reference.  Anything which is passed as an "out" parameter should
	be treated as the target of a pass by value in the "outward" direction.


	If nothing can be assumed about parameter passing behavior, then 
	parameter passing is just too vaguely defined, and needs to be clarified.

The program should be independent of the choice of parameter passing
implementation. (LRM 6.2 (7) says so).  What can be assumed about
parameter passing behaviour is precisely what the LRM says (mostly in
6.2,3,4); no more, and no less. If you want different semantics, use a
limited type (and document the semantics in the package spec).

   > Second, an access value can be passed as a parameter, in which case the
   > language is concerned only with the access value during parameter passing,
   > NOT with the object designated by the access value.

	When what is being passed is known to the user as an access value,
	this is precisely what the programmer expects.  When what is being
	passed is known to the user as an ADT, this sort of behavior is
	totally counterintuitive.  It violates the abstraction.

Once again, this is why limited types are available. It is up to the
ADT implementor to insure that abstraction violations are not
possible. This is not always easy.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-12-05 14:07                   ` David S. Rosenblum
@ 1988-12-07 17:26                     ` Stephe Leake
  0 siblings, 0 replies; 64+ messages in thread
From: Stephe Leake @ 1988-12-07 17:26 UTC (permalink / raw)



In article <10962@ulysses.homer.nj.att.com> dsr@hector.UUCP (David S. Rosenblum) writes:

   ... I feel I've spent more space quoting
   the reference manual on language fundamentals than I have on arguing any
   substantive points.  ...

I, for one, appreciate the time and the pointers. The LRM is complex
enough that it takes discussions like this to fully educate the user.

Thanks!

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-12-05 21:23               ` William Thomas Wolfe,2847,
@ 1988-12-07 17:33                 ` Stephe Leake
  0 siblings, 0 replies; 64+ messages in thread
From: Stephe Leake @ 1988-12-07 17:33 UTC (permalink / raw)



In article <3757@hubcap.UUCP> billwolf@hubcap.clemson.edu (William Thomas Wolfe,2847,) writes:

      Sure, except for the circumvention of the provided ASSIGN routine which
      occurs every time the ADT is passed as an "in" or "out" parameter.

A limited type CANNOT be passed as an out parameter!!!!
A limited type CANNOT be passed as an out parameter!!!!
(in a user routine) LRM 7.4.4 (4). Have you got the message now? And
for an in parameter, the only access to the object is thru the ADT
functions, which work as desired.

Do you have an explicit example where a limited type violates the
abstraction in the way you are discussing? If so, maybe you have found
a compiler bug.

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Collective response to := messages
  1988-12-07 16:07       ` Stephe Leake
@ 1988-12-09  3:15         ` David S. Rosenblum
  0 siblings, 0 replies; 64+ messages in thread
From: David S. Rosenblum @ 1988-12-09  3:15 UTC (permalink / raw)


In article <772@marvin.cme.nbs.gov> leake@cme.nbs.gov (Stephe Leake) writes:
>In article <10917@ulysses.homer.nj.att.com> dsr@hector.UUCP (David S. Rosenblum) writes:
>
>   As I argued in the case of assignment, overloading of type conversion is
>   overloading of a basic operation, and such a facility would allow
>   one to circumvent type checking.  As you suggested above, we don't want
>   to turn Ada into C.
>
>Type checking _cannot_ be circumvented by overloading of type
>conversion! Consider:
>
>type DEGREES is digits 6 range 0.0 .. 360.0;
>type RADIANS is digits 6;
>
>function DEGREES (Item : in RADIANS) return DEGREES
>is
>begin
>	return Item * 180.0 / PI;	-- range constraint is checked!
>end;
>
>Since the underlying Ada type checking is done on the function result,
>no circumvention of type checking is possible.

My comment did NOT have to do with checking the constraints of the
target type.  I hope anybody with a minimal familiarity with Ada knows
that type constraints are checked on function return values.  My point
was that overloading of type conversion will allow you to "covert" pointers
to integers, arrays to files, tasks to widgets, etc.  This is called "casting"
in C, better known as "anything goes".  To me such conversions are a
circumvention of Ada's strong typing model.

I'll try this just one more time.  By allowing the overloading of
basic operations, you may gain some flexibility in defining your
abstractions, but this gain will be achieved only at the (to me, unjustifiable)
cost of severely weakening Ada's strong typing strictures.  Any
proposal to increase flexibility in defining abstractions in Ada
MUST ("read my lips"--MUST) conform to the fundamental language philosophies
of Ada.

I would suggest two promising areas for making such improvements
in an "Ada-like" way.  (1) Allow user-specifiable initialization and
destruction routines for types.  Ray Trent and Bill Wolfe have been arguing
for a parameter passing semantics based on assignment.  Stroustrup, in his
C++ book, argues that you need initialization mechanisms, not assignment, for
parameter passing, and that initialization and assignment are
fundamentally different operations.  Initialization routines would
be appropriate for initializing parameters that are passed by copy, which
(at least for scalars) is the mandated parameter passing mechanism.
(2) Define a mechanism for allowing richer user-specified constraints
on types, e.g. "all objects of type EVEN must have even values", or "for
all objects of record type FOO, component BAR must always be greater than
component BAZ".  Then let Ada's inherent type checking mechanisms check
these constraints automatically.

In short, Ada has a very nice type checking framework.  We should try to
come up with proposals that improve that framework in ways that increases
its flexibility without decreasing its robustness; don't just propose tacking
on new language rules and band-aids that will cheaply rid you of your
frustrations with the current framework.


-------------------------------------------------------------------
David Rosenblum			UUCP: {ucbvax, decvax}!ulysses!dsr
AT&T Bell Laboratories		ARPA: dsr@ulysses.att.com
600 Mountain Ave.		      dsr%ulysses@att.arpa
Murray Hill, NJ 07974-2070
(201) 582-2906
-------------------------------------------------------------------

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

* Re: Garbage Collection
  1988-12-07 15:22         ` Collective response to := messa ron
@ 1988-12-11 19:11           ` William Thomas Wolfe,2847,
  1988-12-12  5:29             ` John Gateley
                               ` (2 more replies)
  0 siblings, 3 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-11 19:11 UTC (permalink / raw)


From article <124000026@inmet>, by ron@inmet.UUCP:
> 
> Garbage collection certainly does not come for free, but it is extremely
> useful.  It frees the programmer from the need to repeatedly write
> sophisticated ADT deallocate routines and to deal with the potentially
> massive book-keeping requirements for determining whether an object is in
> fact garbage.  In general, lack of GC forces a programmer to invest a lot of
> effort addressing issues that are not fundamentally related to the problem
> domain.  My experience has also shown that problems of "slow heap leakage"
> are among the hardest errors to correct.

   "Repeatedly" write sophisticated ADT deallocate routines??  The basic 
   idea is to write an ADT once and use it forever (i.e., until the next 
   language modification :-) ); where does "repeatedly" come in?

   Dealing with the details of allocation requires as much effort as  
   dealing with deallocation.  Perhaps you would say that any maintenance 
   of the structure used to represent your ADT is not fundamentally
   related to the problem domain.  If so, I will have to disagree.

   ADTs, and computer programs in general, are characterized by both
   time complexity and space complexity.  Making the tradeoffs between
   these forms of complexity is one of the most fundamental questions
   a programmer must deal with.  This is the topic of much, if not most, 
   of the literature regarding ADTs.

   Also, I disagree with the claim that a lot of effort is involved;
   in my experience, DESTROY routines are among the easiest to code.
   Usually, the ADT is defined recursively, lending itself to a very
   easy recursive destruction procedure; after that, just destroy
   any sub-ADTs in your descriptor, and from there it only takes one
   line of code to blow away the descriptor.  About the hardest part
   of the whole process is the tedium of looking through to see what
   fields are user-defined sub-ADTs, since they have to be explicitly
   destroyed due to Ada's lack of integration between UNCHECKED_DEALLOCATION
   and user-defined DESTROY procedures.


                                          Bill Wolfe

                                   wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-11 19:11           ` Garbage Collection William Thomas Wolfe,2847,
@ 1988-12-12  5:29             ` John Gateley
  1988-12-12 18:19               ` William Thomas Wolfe,2847,
  1989-01-02 17:51             ` ryer
  1989-01-06 16:58             ` ryer
  2 siblings, 1 reply; 64+ messages in thread
From: John Gateley @ 1988-12-12  5:29 UTC (permalink / raw)


In article <3832@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <124000026@inmet>, by ron@inmet.UUCP:
>> 
>> Garbage collection certainly does not come for free, but it is extremely
>> useful.  It frees the programmer from the need to repeatedly write
>> sophisticated ADT deallocate routines and to deal with the potentially
>> [...]
>   "Repeatedly" write sophisticated ADT deallocate routines?? [...]
>    where does "repeatedly" come in?

The repeatedly comes in because you write more than one ADT, each requiring
a/many deallocation routines.

>   Dealing with the details of allocation requires as much effort as  
>   dealing with deallocation. [...]

This is not true. When you allocate an object, all you need is "free"
memory. The allocator does not have to worry about whether or not the
object is in use etc. Deallocation, when done correctly, requires some
sort of checking to make sure no currently in use object refers to the
object being deallocated. This is a much more complicated problem.

>   [...]
>   Also, I disagree with the claim that a lot of effort is involved;
>   in my experience, DESTROY routines are among the easiest to code.
>   Usually, the ADT is defined recursively, lending itself to a very
>   easy recursive destruction procedure; [...]

This method is fine, as long as no structures are shared. But when you
share structure, then the problem is more complex. A sub adt-object
can be used in more than one object. Deleting an object which contains
this sub-object may or may not require deleteing the sub object. One
answer is "reference counting", adding a field to each object which says
how many people refer to it. Automating this gives reference count
garbage collection, which is slower than the GC techniques in current
use. So if your programming style never uses shared structure, then you
don't need GC. If it does, then GC is a valuable time saving tool.

>                                          Bill Wolfe
>                                   wtwolfe@hubcap.clemson.edu

John Gateley
gateley@tilde.csc.ti.com

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

* Re: Garbage Collection
  1988-12-12  5:29             ` John Gateley
@ 1988-12-12 18:19               ` William Thomas Wolfe,2847,
  1988-12-13  1:02                 ` Alexander Klaiber
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-12 18:19 UTC (permalink / raw)


From article <65475@ti-csl.CSNET>, by gateley@m2.csc.ti.com (John Gateley):
>>   Also, I disagree with the claim that a lot of effort is involved;
>>   in my experience, DESTROY routines are among the easiest to code.
>>   Usually, the ADT is defined recursively, lending itself to a very
>>   easy recursive destruction procedure; [...]
> 
> This method is fine, as long as no structures are shared. [...] 
> [...] if your programming style never uses shared structure, then you
> don't need GC. 

    Precisely.  

    Structural sharing is nothing more than a euphemism for hacking.  
    It is the spatial equivalent of what hackers enjoy doing with time 
    in the name of efficiency, in their unmitigated zeal to violate every
    form of abstraction, to throw all traces of readability and reliability 
    to the winds.  

    If GC were prohibited, it would infuriate all those who enjoy hacking
    with space as opposed to time.  Good.  Let them use C.  Ada is the
    language of those who appreciate that "abstraction is the fundamental
    tool with which complexity can be effectively managed", and recognize
    that to violate an abstraction (rather than design another which is
    more appropriate to their needs) is to be penny wise but pound foolish.

    Folks, space management in Ada is NOT that difficult.  I had problems with
    space management in Pascal, but Ada-based ADTs have basically made it
    into a non-issue.  The real challenges which remain are problems which
    are inherent in the language itself, such as getting local ADTs to be 
    properly destroyed as an automatic consequence of a block exit.

    I agree that existing tools for detecting space-wasting ADTs are 
    inadequate, but let's call for better debugging tools rather than
    going about advocating the practice of spewing garbage. 


    
                                        Bill Wolfe

                                 wtwolfe@hubcap.clemson.edu
 

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

* Re: Garbage Collection
  1988-12-12 18:19               ` William Thomas Wolfe,2847,
@ 1988-12-13  1:02                 ` Alexander Klaiber
  1988-12-13 18:37                   ` William Thomas Wolfe,2847,
  1988-12-13 20:22                   ` Garbage Collection William Thomas Wolfe,2847,
  0 siblings, 2 replies; 64+ messages in thread
From: Alexander Klaiber @ 1988-12-13  1:02 UTC (permalink / raw)



In article <3848@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <65475@ti-csl.CSNET>, by gateley@m2.csc.ti.com (John Gateley):
>> This method is fine, as long as no structures are shared. [...] 
>> [...] if your programming style never uses shared structure, then you
>> don't need GC. 
>    Precisely.  
>    Structural sharing is nothing more than a euphemism for hacking.  
>    It is the spatial equivalent of what hackers enjoy doing with time 
>    in the name of efficiency, in their unmitigated zeal to violate every
>    form of abstraction, to throw all traces of readability and reliability 
>    to the winds.  

Apart from the amount of cheap flames you've thrown in, do you think you
REALLY have thought this out?

Sure, structure-sharing *is* sometimes used with the goal of conserving
memory, but there are cases where it is vital; especially when you're doing
object-oriented like programming.

Assume I maintain mailing-lists of people and I represent the lists by
pointers to objects representing one person each; i.e.

type person is (some adt)
type mailinglist is new list(person);

Now if I have more than one mailing-list, obviously I have structure-sharing: 
a given person may appear on more than one list. And it is *NOT* very wise
to create one copy of each person for every mailing list that person appears
on: people can change the addresses and by having just *one* instance of
the person around, there is only *one* place where it needs to be changed
-- these changes will be completely transparent to the mailing lists or,
for that matter, *FOR ANY OTHER REFERENCES TO THE PERSON* that I might
later add to the system!

In a system such as this, I will need *some* form of keeping track just 
how many references to a given object (a person) exist, so I know when
I can safely deallocate it --- now one method is to have the programmer
take care of it, but that might require making the (mailinglist) and 
(person) know about each other, thus creating additional dependencies and
limiting further extensibility. The other method is to supply GC.

Now you *can* do without structure sharing by creating "deep copies" of
each reference to any given object --- but you will have to live with the
"updating problem" which is well-known in databases where multiple copies
of objects are kept.

The bottom line is that structure-sharing can be a valuable abstraction
tool, and one you apparently are not aware of.

>    If GC were prohibited, it would infuriate all those who enjoy hacking
>    with space as opposed to time.  Good.  Let them use C.  Ada is the

Why do you want to explicitly *prohibit* it?

>    Folks, space management in Ada is NOT that difficult.  

Depends on what kinds of applications you are writing.

Note that I do not ask that GC be *required* (obviously that would be rather
foolish in real-time applications), but it is sure nice to have it, since
it can greatly help to reduce the complexity of your programs by
eliminating all these storage-management chores and allowing you to
concentrate on the real problems.

It sure eliminates a *lot* of possibilities for errors and actually makes
programs much more reliable and readable. Maybe *you* are throwing
readability and reliability in the wind...



Alexander Klaiber
klaiber@june.cs.washington.edu


P.S.:
For complex applications as these, I tend to programm in Smalltalk
rather than in Ada, so I might be somewhat biased. But I *have* done
o-o programming in C++, and believe me, storage management can be
*nasty*!

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

* Re: Garbage Collection
  1988-12-13  1:02                 ` Alexander Klaiber
@ 1988-12-13 18:37                   ` William Thomas Wolfe,2847,
  1988-12-13 23:36                     ` Alexander Klaiber
                                       ` (2 more replies)
  1988-12-13 20:22                   ` Garbage Collection William Thomas Wolfe,2847,
  1 sibling, 3 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-13 18:37 UTC (permalink / raw)


From article <6702@june.cs.washington.edu>, by klaiber@june.cs.washington.edu (Alexander Klaiber):
> Assume I maintain mailing-lists of people and I represent the lists by
> pointers to objects representing one person each; i.e.
> 
> type person is (some adt)
> type mailinglist is new list(person);
> 
> Now if I have more than one mailing-list, obviously I have structure-sharing: 
> a given person may appear on more than one list. 

    No, this isn't structural sharing, because you are explicitly manipulating 
    a list of pointers.  Structural sharing occurs when you have two objects, 
    A and B, and making some modification to B causes a modification to A as 
    well, because they share a portion of their structure.  The structure
    of a pointer is simply the address field, and the address fields are not
    being shared.  Now if we had two ADTs, both implemented by *hidden*
    pointers, and assignment failed to result in a deep copy, then THAT 
    would be structural sharing. 

    In this particular instance, it would be best to store the key by which
    a person could be identified (social security number, for example) in
    the list, and then using the key to retrieve the current address from
    the Person database.  Thus, a mailing list would be a list of social
    security numbers. 
   

                                            Bill Wolfe

                                    wtwolfe@hubcap.clemson.edu
 

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

* Re: Garbage Collection
  1988-12-13  1:02                 ` Alexander Klaiber
  1988-12-13 18:37                   ` William Thomas Wolfe,2847,
@ 1988-12-13 20:22                   ` William Thomas Wolfe,2847,
  1988-12-14  6:40                     ` Richard A. O'Keefe
  1 sibling, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-13 20:22 UTC (permalink / raw)


From article <6702@june.cs.washington.edu>, by klaiber@june.cs.washington.edu (Alexander Klaiber):
> 
> Why do you want to explicitly *prohibit* it [garbage collection]?
> 

    Basically, I charge garbage collection with the same crime that
    the GOTO was charged with: its sole function is to facilitate
    UNDISCIPLINED programming.  From Tremblay and Sorenson, 1985:

       A common thought among proponents of the GOTO is: "I just
       might need it; something might come up".  The answer to
       this appears to be: "Nothing ever does".

    If this charge can be successfully prosecuted, then garbage
    collection will face the same penalty: the total elimination 
    of the facility, in favor of a more disciplined environment.



                                          Bill Wolfe

                                  wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-13 18:37                   ` William Thomas Wolfe,2847,
@ 1988-12-13 23:36                     ` Alexander Klaiber
  1988-12-14  3:26                       ` William Thomas Wolfe,2847,
                                         ` (2 more replies)
  1988-12-14 23:30                     ` John Gateley
  1988-12-16  0:49                     ` Keys are references, too (was Re: Garbage Collection) Badger BA 64810
  2 siblings, 3 replies; 64+ messages in thread
From: Alexander Klaiber @ 1988-12-13 23:36 UTC (permalink / raw)


In article <8812131536.AA08238@galaxy.compass.com> worley@compass.UUCP (Dale Worley) writes:
>I will add that garbage collection is one of the greatest aids to
>readabilty and reliability, because it takes a complicated and
>error-prone part of programming (reclaiming storage) and eliminates it
>completely.  It probably shouldn't be required in Ada, but as an aid
>in programmability, it's great.

Thank you very much, exactly my point. At least I'm not alone :-)

==========================================================================
In article <3861@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>    No, this isn't structural sharing, because you are explicitly manipulating 

Call it what you want, the fact is that multiple references exist to one
object, thus making explicit (i.e. by the programmer) storage management
a nightmare and an unnecessary chore. GC deals with this situation easily.

>    In this particular instance, it would be best to store the key by which
>    a person could be identified (social security number, for example) in
>    the list, and then using the key to retrieve the current address from
>    the Person database.  

That is, if you are willing to willing to pay the cost for the additional
data base lookup (usually an O(log n) operation), as well as the additional
complexity introduced in your program. 
I didn't say it couldn't be done without (what I call) structure sharing, 
I just wanted to point out that this would be a very intuitive approach 
and would probably lead to a very readable code.

The method of using key searches is, I believe, an unnecessary hack to
avoid multiple references. Why bother to include a full B-tree package
or such when we can do without? 

Clearly, there is a tradeoff between readability and efficiency. In my
version, I reduce efficiency by requiring garbage collection (although
there exist rather powerful and fast GC algorithms). Your proposal
would definitely increase the complexity of the program and, due to the
overhead of a DB-lookup, might actually run slower than the version with
GC --- depending on circumstances such as frequency of lookups in the 
database, size of the database (your program) vs. time required for GC, 
amount of garbage produced etc. (my program).

In my opinion, people tend to put too much emphasis on plain efficiency of
their programs and too little on issues such as readability, reliability
and extensibility --- and I contend that (depending on the application)
garbage collection *CAN* help to improve all of these.

Hence, it is *wrong* to flatly ignore GC; it sure has its place and,
especially in o-o systems, should be available as an option to the 
programmer. Now whether it should be required in *Ada* is a question of
just where Ada9x will go and not really my concern.



	Alexander Klaiber
	klaiber@june.cs.washington.edu

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

* Re: Garbage Collection
  1988-12-13 23:36                     ` Alexander Klaiber
@ 1988-12-14  3:26                       ` William Thomas Wolfe,2847,
  1988-12-14 17:16                       ` Stephe Leake
  1988-12-15 14:43                       ` Thomas P. Morris
  2 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-14  3:26 UTC (permalink / raw)


From article <6713@june.cs.washington.edu>, by klaiber@june.cs.washington.edu (Alexander Klaiber):
> In article <8812131536.AA08238@galaxy.compass.com> worley@compass.UUCP (Dale Worley) writes:
>>I will add that garbage collection is one of the greatest aids to
>>readabilty and reliability, because it takes a complicated and
>>error-prone part of programming (reclaiming storage) and eliminates it
>>completely.  

    I don't see storage reclamation as being complicated or error-prone,
    but maybe that's because I'm so accustomed to dealing with it that
    it comes almost automatically.  Probably the most important reason,
    though, is that the ADT paradigm provides such a powerful mechanism
    for simplifying the situation.  I'm doing an ADT implementation
    right now (mergeable priority queues implemented as binomial forests),
    and I find it hard to believe that anyone could sit there and do an
    ADT implementation without being able to visualize the structure
    in question as the code is being generated.  Given that the implementor
    can visualize the structure, the process of destroying it seems trivial.

> In article <3861@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>>    No, this isn't structural sharing, because you are explicitly manipulating 
> 
> Call it what you want, the fact is that multiple references exist to one
> object, thus making explicit (i.e. by the programmer) storage management
> a nightmare and an unnecessary chore. GC deals with this situation easily.

    There's an even easier way to deal with it:

       *** Never let a pointer out of your sight ***

    Given that one is doing this, the question is reduced to managing
    local pointers to a local structure, which is quite easy.

>>    In this particular instance, it would be best to store the key by which
>>    a person could be identified (social security number, for example) in
>>    the list, and then using the key to retrieve the current address from
>>    the Person database.  
> 
> That is, if you are willing to willing to pay the cost for the additional
> data base lookup (usually an O(log n) operation)

     Not necessarily.  If all you're doing is insertions, deletions,
     and retrievals, a hashing implementation would give better results.

> I didn't say it couldn't be done without (what I call) structure sharing, 
> I just wanted to point out that this would be a very intuitive approach 
> and would probably lead to a very readable code.

     I'd contest both claims; as a maintainer, I wouldn't want anything
     to get in the way of being able to pin down the state of that program
     precisely, with regard to both time AND SPACE.  For one who is
     accustomed to being able to nail down the precise state of a program,
     code from which it is impossible to "complete the picture" is
     highly counterintuitive, and will probably wind up being rewritten.

> The method of using key searches is, I believe, an unnecessary hack to
> avoid multiple references. Why bother to include a full B-tree package
> or such when we can do without? 

     How can you possibly analyze the space complexity of your program
     when you can't pin down the precise status of every entity???  You
     can't just wave your hands and say "Well, I'm using this much space,
     plus there's a bunch of space that may or may not be occupied..."!!

     And let's not forget the pure hell of doing a time analysis given
     that you can be interrupted unpredictably for garbage collection,
     the timing and duration of which is totally beyond your control,
     particularly in that it depends on how much memory happens to be
     currently installed on the executing system!!

> In my opinion, people tend to put too much emphasis on plain efficiency of
> their programs and too little on issues such as readability, reliability
> and extensibility 

     At last, something we can ALL agree on.  (I hope...!)


                                     
                                       Bill Wolfe

                                wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-13 20:22                   ` Garbage Collection William Thomas Wolfe,2847,
@ 1988-12-14  6:40                     ` Richard A. O'Keefe
  1988-12-14 17:43                       ` William Thomas Wolfe,2847,
  0 siblings, 1 reply; 64+ messages in thread
From: Richard A. O'Keefe @ 1988-12-14  6:40 UTC (permalink / raw)


In article <3865@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
>    Basically, I charge garbage collection with the same crime that
>    the GOTO was charged with: its sole function is to facilitate
>    UNDISCIPLINED programming.  From Tremblay and Sorenson, 1985:

This is completely back-to-front.  Doing your own storage management
is like doing your own stack management instead of using procedure calls.
If you want to compare garbage collection with a control structure,
compare it with resursive procedures.

>    If this charge can be successfully prosecuted, then garbage
>    collection will face the same penalty: the total elimination 
>    of the facility, in favor of a more disciplined environment.

I think it would be very hard to accuse functional programming languages
like ML of providing an _un_disciplined environment.  Yet automatic storage
control is vital to them.  A word about the history of ML may make this
clearer.  ML was originally the MetaLanguage of Edinburgh LCF, a system
for doing proofs about computations.  It is strongly typed, because it
was important that anything the system claimed to be a proof should be a
valid proof.  There is a basic set of proof-forming operations which are
known to be valid.  The language cannot permit changes to elements of a
data structure, otherwise the arguments to a proof might be changed after
the proof was constructed, rendering it invalid.  "deallocate" simply
doesn't make sense in that kind of environment.  Storage management is
particularly easy in a language without side effects to data structures.

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

* Re: Garbage Collection
  1988-12-13 23:36                     ` Alexander Klaiber
  1988-12-14  3:26                       ` William Thomas Wolfe,2847,
@ 1988-12-14 17:16                       ` Stephe Leake
  1988-12-15 14:43                       ` Thomas P. Morris
  2 siblings, 0 replies; 64+ messages in thread
From: Stephe Leake @ 1988-12-14 17:16 UTC (permalink / raw)



In article <6713@june.cs.washington.edu> klaiber@june.cs.washington.edu (Alexander Klaiber) writes:

   Clearly, there is a tradeoff between readability and efficiency. In my
   version, I reduce efficiency by requiring garbage collection (although
   there exist rather powerful and fast GC algorithms). Your proposal
   would definitely increase the complexity of the program and, due to the
   overhead of a DB-lookup, might actually run slower than the version with
   GC --- depending on circumstances such as frequency of lookups in the 
   database, size of the database (your program) vs. time required for GC, 
   amount of garbage produced etc. (my program).

You are not reducing the complexity of the program; you are merely
hiding it in the vendor-supplied memory management package. If the
program is written correctly, the complexity can be hidden in a
user-supplied memory management package. Then there is no difference
in the readability of the application code, and the programmer has the
chance to tailor the garbage collection algorithm to the application.
Since there are many garbage collection algorithms (each posting here
seems to mention another one), it is clear that each will be suited to
certain applications. Better to require the programmer to choose the
algorithm, than to be tempted to "live with" the single vendor
supplied one. There is no way the vendor can take into account the
trade-offs you mention, but you can!

Stephe Leake 	(301) 975-3431 		leake@cme.nbs.gov
National Institute of Standards and Technology
(formerly National Bureau of Standards)
Rm. B-124, Bldg. 220
Gaithersburg, MD  20899

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

* Re: Garbage Collection
  1988-12-14  6:40                     ` Richard A. O'Keefe
@ 1988-12-14 17:43                       ` William Thomas Wolfe,2847,
  0 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-14 17:43 UTC (permalink / raw)


From article <864@quintus.UUCP>, by ok@quintus.uucp (Richard A. O'Keefe):
> In article <3865@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
>>    Basically, I charge garbage collection with the same crime that
>>    the GOTO was charged with: its sole function is to facilitate
>>    UNDISCIPLINED programming.  From Tremblay and Sorenson, 1985:
> 
> This is completely back-to-front.  Doing your own storage management
> is like doing your own stack management instead of using procedure calls.

     Procedure calls are used to manage the complexity of creating the
     structure and of maintaining it.  They should also be used to
     manage its destruction.  This is clear and consistent, and promotes
     readable and reliable operations on a well-defined structure with
     well-defined space/time properties.

> I think it would be very hard to accuse functional programming languages
> like ML of providing an _un_disciplined environment.  [...] 
> Storage management is particularly easy in a language without 
> side effects to data structures.

     OK, try getting a referentially transparent language to
     handle systems which are not static, but change over time.

     With increased power comes increased responsibility.   


                                      Bill Wolfe

                              wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-13 18:37                   ` William Thomas Wolfe,2847,
  1988-12-13 23:36                     ` Alexander Klaiber
@ 1988-12-14 23:30                     ` John Gateley
  1988-12-15 19:25                       ` William Thomas Wolfe,2847,
  1988-12-16  0:49                     ` Keys are references, too (was Re: Garbage Collection) Badger BA 64810
  2 siblings, 1 reply; 64+ messages in thread
From: John Gateley @ 1988-12-14 23:30 UTC (permalink / raw)


A good example of when garbage collection is needed for readability:
An infinite precision integer arithmatic package (or ADT, or module,
or whatever you want to call it). Infinite precision integers will
take up an unknown amount of memory to represent. Either you have to
explicitly deallocate them when you are done, or let GC take care of them.
But now consider the uses of integers in programs, they are used all over
the place, with no regard for careful deallocation. Converting a program
to use infinite precision integers will be very difficult, since it is
hard to figure exactly when the program is 'finished' with a particular
number.

John

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

* Re: Garbage Collection
  1988-12-13 23:36                     ` Alexander Klaiber
  1988-12-14  3:26                       ` William Thomas Wolfe,2847,
  1988-12-14 17:16                       ` Stephe Leake
@ 1988-12-15 14:43                       ` Thomas P. Morris
  2 siblings, 0 replies; 64+ messages in thread
From: Thomas P. Morris @ 1988-12-15 14:43 UTC (permalink / raw)


In article <6713@june.cs.washington.edu>, klaiber@june.cs.washington.edu (Alexander Klaiber) writes:
> The method of using key searches is, I believe, an unnecessary hack to
> avoid multiple references. Why bother to include a full B-tree package
> or such when we can do without? 
> 
You mean to tell us that you =intend= to keep your "mailing" lists
=permanently in memory=? You're =never= going to write them to a permanent
file system/disk? Or that your never going to keep a list larger than can
be kept in memory? Really!  The method of using key searches is a useful
aid to designing a program to read from a database larger than you can
keep in memory, which needs to be permanent, and which ought to be well-
behaved in terms of no =clobbering= other processes' performance!

:-) Yeah, I know that the mailing list abstraction was only for an example.
But a fairly poor example if you wish to justify structure sharing, which
*has* its proper place...

> Clearly, there is a tradeoff between readability and efficiency. In my
> version, I reduce efficiency by requiring garbage collection (although
> there exist rather powerful and fast GC algorithms). Your proposal
> would definitely increase the complexity of the program and, due to the
> overhead of a DB-lookup, might actually run slower than the version with
> GC --- depending on circumstances such as frequency of lookups in the 
> database, size of the database (your program) vs. time required for GC, 
> amount of garbage produced etc. (my program).
> 
For something like a database system (i.e. mailing lists, again), I would
have to disagree that a keyed-search DB-lookup paradigm is necessarily
less readable or understandable or complex than having to pre-process
the databases (to create your structure sharing) to have direct access,
which might not be reasonable or possible with a *large* database.

Your points about speed of access are well taken, but consider the end
user aspects: how many folks are going to wait 10, or 20, or 30 minutes
for you to read in the external data, build your structure sharing
structures, and =then= process their mailing list (personnel records,
widget manufacturing data, etc), rather than using a relational database
paradigm, using keyed access to those external permanent files?

> In my opinion, people tend to put too much emphasis on plain efficiency of
> their programs and too little on issues such as readability, reliability
> and extensibility --- and I contend that (depending on the application)
> garbage collection *CAN* help to improve all of these.

  Yes and yes. The mailing list example is and unfortunate choice perhaps.
And some of us put also put an emphasis on how well a system works for
its intended end-users!
-----------------------------------------------------------------------------
Tom Morris                                 BITNET: TOM@UNCSPHVX
UNC School of Public Health                UUCP  : ...!mcnc!ecsvax!tpmsph
-----------------------------------------------------------------------------
-- 
-----------------------------------------------------------------------------
Tom Morris                                 BITNET: TOM@UNCSPHVX
UNC School of Public Health                UUCP  : ...!mcnc!ecsvax!tpmsph
-----------------------------------------------------------------------------

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

* Re: Garbage Collection
  1988-12-14 23:30                     ` John Gateley
@ 1988-12-15 19:25                       ` William Thomas Wolfe,2847,
  1988-12-19 16:12                         ` John Gateley
  0 siblings, 1 reply; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-15 19:25 UTC (permalink / raw)


From article <65713@ti-csl.CSNET>, by gateley@m2.csc.ti.com (John Gateley):
> A good example of when garbage collection is needed for readability:
> An infinite precision integer arithmatic package (or ADT, or module,
> or whatever you want to call it). Infinite precision integers will
> take up an unknown amount of memory to represent. Either you have to
> explicitly deallocate them when you are done, or let GC take care of them.
> But now consider the uses of integers in programs, they are used all over
> the place, with no regard for careful deallocation. Converting a program
> to use infinite precision integers will be very difficult, since it is
> hard to figure exactly when the program is 'finished' with a particular
> number.

     The deallocation of every object in the local environment is
     performed as an automatic service when a procedure, function,
     or local block is exited.  This is not garbage collection,
     because the programmer has implicitly directed that the 
     destruction be performed.  

     Unfortunately, Ada does not provide a means of integrating ADT 
     destruction algorithms into the mechanism providing this service.  
     This is Language Issue 35 of the Ada Language Issues Working Group; 
     it is presently under editorial review, a step which is usually followed 
     by approval and then by submission to ADA-COMMENT, according to the 
     ALIWG handout I obtained at Tri-Ada '88.


                                         Bill Wolfe

                                 wtwolfe@hubcap.clemson.edu

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

* Keys are references, too (was Re: Garbage Collection)
  1988-12-13 18:37                   ` William Thomas Wolfe,2847,
  1988-12-13 23:36                     ` Alexander Klaiber
  1988-12-14 23:30                     ` John Gateley
@ 1988-12-16  0:49                     ` Badger BA 64810
  1988-12-18 18:42                       ` William Thomas Wolfe,2847,
  2 siblings, 1 reply; 64+ messages in thread
From: Badger BA 64810 @ 1988-12-16  0:49 UTC (permalink / raw)


In article <3861@hubcap.UUCP> wtwolfe@hubcap.clemson.edu writes:
>From article <6702@june.cs.washington.edu>, by klaiber@june.cs.washington.edu (Alexander Klaiber):
>> Assume I maintain mailing-lists of people and I represent the lists by
>> pointers to objects representing one person each; i.e.
>> type person is (some adt)
>> type mailinglist is new list(person);
>> Now if I have more than one mailing-list, obviously I have structure-sharing: 
>> a given person may appear on more than one list. 
>
> No, this isn't structural sharing, because you are explicitly manipulating 
> a list of pointers.  Structural sharing occurs when you have two objects, 
> A and B, and making some modification to B causes a modification to A as 
> well, because they share a portion of their structure.  The structure
> of a pointer is simply the address field, and the address fields are not
> being shared.  Now if we had two ADTs, both implemented by *hidden*
> pointers, and assignment failed to result in a deep copy, then THAT 
> would be structural sharing. 
>
> In this particular instance, it would be best to store the key by which
> a person could be identified (social security number, for example) in
> the list, and then using the key to retrieve the current address from
> the Person database.  Thus, a mailing list would be a list of social
> security numbers. 
>   
>
>                                            Bill Wolfe
>
>                                    wtwolfe@hubcap.clemson.edu
Mr. Wolfe does not (here) recognize the social security number (SSN) as 
another form of access mechanism.  *Any* means by which a symbol can be 
introduced to stand in as the ``name'' of the actual object will introduce 
the ability to ``share'' the object by mentioning the name in two places.  
Just because the SSN is not a memory address pointer, does not mean that 
sharing is not taking place.  (As an aside, the Ada LRM is careful not to call
access types ``pointers'' for a similar reason:  access types may turn out
to *not* be implemented as a memory pointer.)

Another key thing that Mr. Wolfe does not address is the problem of deciding
*when* to destroy an object.  Sure, it's easy enough, in most cases, to write 
a destruction routine, but you can't always wait until passing out of the 
scope of the visibility of the ADT to clean up.  This is where all the 
reference counts and other garbage collection mechanisms come in:  determining
that it is *SAFE* to reclaim storage.  Mr. Wolfe's database design has the 
same problem:  It's easy to remove the personnel record, but you may only 
do so when the SSN is not referenced any more.  

Leaving this decision up to the clients of the ADT, say by providing explicit
DESTROY(X) calls, just pushes this burden on the programmer of the client.  
In many cases, there is a clear and efficient way to determine when it is 
safe to destroy objects.  Fine!  Those cases can be explicitly managed by 
the programmer. A good garbage collector should not waste time  attemting 
to garbage-collect over programmer-managed data.  Perhaps a pragma(NO_GC,type);
would be helpful to the compiler.  

You have to show that GC is *never* worthwhile to justify *prohibiting* it 
from the language.  It seems to me that investing a lot of serious effort to 
get a really good GC algorithm built into the language would be much better 
than expecting "average" programmers to correctly implement proper storage 
reclamation for each ADT they'd like to use which requires memory allocation.
Even if not every compiler vender has ``the world's best'' memory reclamation,
it will be easier to select one that does, based on professional reviews, 
than to implement it yourself.



Bernard A. Badger Jr.	407/984-6385          |``Use the Source, Luke!''
Secure UNIX Products                          |It's not a bug; it's a feature!
Harris GISD, Melbourne, FL                    |Buddy, can you paradigm?
Internet: bbadger@cobra@trantor.harris-atd.com|Recursive:  see Recursive.

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

* Re: Keys are references, too (was Re: Garbage Collection)
  1988-12-16  0:49                     ` Keys are references, too (was Re: Garbage Collection) Badger BA 64810
@ 1988-12-18 18:42                       ` William Thomas Wolfe,2847,
  0 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1988-12-18 18:42 UTC (permalink / raw)


From article <1407@trantor.harris-atd.com>, by bbadger@x102c.uucp (Badger BA 64810):
> Mr. Wolfe does not (here) recognize the social security number (SSN) as 
> another form of access mechanism.  *Any* means by which a symbol can be 
> introduced to stand in as the ``name'' of the actual object will introduce 
> the ability to ``share'' the object by mentioning the name in two places.  

    If I have an object A, and pointers to that object P1 and P2, then
    I have three distinct objects, none of which share structure.

    If I have objects B and C, such that a modification to B results also
    in a modification of C, then this is structural sharing.  

> Another key thing that Mr. Wolfe does not address is the problem of deciding
> *when* to destroy an object.  Sure, it's easy enough, in most cases, to write 
> a destruction routine, but you can't always wait until passing out of the 
> scope of the visibility of the ADT to clean up.  

    This is why users can explicitly call DESTROY when the object is 
    no longer needed.

> Mr. Wolfe's database design has the 
> same problem:  It's easy to remove the personnel record, but you may only 
> do so when the SSN is not referenced any more.  

    Not true.  If the SSN refers to a person who is dead, then that fact 
    can be delivered as the database's response.  If the SSN refers to a
    person who has been deleted from or never existed in the database, then
    this can be delivered as the database's response, perhaps by raising an
    exception.  The database manager must decide how keys are to be managed, 
    and users of those keys must follow the database manager's directives.

> Leaving this decision up to the clients of the ADT, say by providing explicit
> DESTROY(X) calls, just pushes this burden on the programmer of the client.  

    If the programmer wishes to maximize space efficiency, explicit calls
    to DESTROY can be made when appropriate.  The block exit mechanism
    provides a convenient mechanism by which this directive can be given
    implicitly but unambiguously, with precisely known timing.

> It seems to me that investing a lot of serious effort to 
> get a really good GC algorithm built into the language would be much better 
> than expecting "average" programmers to correctly implement proper storage 
> reclamation for each ADT they'd like to use which requires memory allocation.

    Implementing proper storage allocation is the responsibility of the
    person who designs the ADT.  I think average, below average, and
    barely-above-brain-dead programmers can all comprehend the fact that
    objects must be both created and destroyed; they are created upon 
    declaration, and destroyed either by calling DESTROY or as an implicit
    consequence of block exit.

> Even if not every compiler vender has ``the world's best'' memory reclamation,
> it will be easier to select one that does, based on professional reviews, 
> than to implement it yourself.

    OK, all those who think it's just TERRIBLE to have to actually program 
    for reuseability can *purchase* generic ADTs, a/k/a software components.

    Then you can select the components you need, based on professional
    reviews, rather than implementing them yourself.  (Satisfied?)

    Wizard Software and Lib Systems are two vendors which supply such ADTs;
    anyone considering such a purchase should seek out professional reviews,
    since I write my own ADTs and therefore I have absolutely no experience 
    with and do not in any way endorse either firm's products.

    I might add that Jean Ichbiah explicitly predicted, long ago, the
    emergence of a software components industry, based upon the generic
    features of the (then-new) Ada language.  Slowly but surely, his 
    prediction is being fulfilled.



                                            Bill Wolfe

                                    wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-15 19:25                       ` William Thomas Wolfe,2847,
@ 1988-12-19 16:12                         ` John Gateley
  1988-12-20 19:34                           ` Bill Wolfe
  0 siblings, 1 reply; 64+ messages in thread
From: John Gateley @ 1988-12-19 16:12 UTC (permalink / raw)


In article <3918@hubcap.UUCP> billwolf@hubcap.clemson.edu writes:
>From article <65713@ti-csl.CSNET>, by gateley@m2.csc.ti.com (John Gateley):
>> [I say infinite precision arithmetic is a good example of why GC is needed
>>  sometimes].
>
>     The deallocation of every object in the local environment is
>     performed as an automatic service when a procedure, function,
>     or local block is exited.  This is not garbage collection,
>     because the programmer has implicitly directed that the 
>     destruction be performed.  

But, integers are not always deallocated. They may be returned as the
result of a function, assigned to global variables, placed in the 
heap as parts of other data objects etc. When you try and do the same
with infinite precision integers, then the deallocation you describe
does not work! You can always copy them for these purposes, but this
can be very space/time inefficient. It also requires extra effort (remembering
to copy them), unless Ada provides some technique for doing this automatically.
So, GC is a good way to handle this problem.

>     Unfortunately, Ada does not provide a means of integrating ADT 
>     destruction algorithms into the mechanism providing this service.  
>     This is Language Issue 35 of the Ada Language Issues Working Group; 
>     ...

Integers, however, are not deallocated when a block is exited (if they
have been saved elsewhere). So, I don't think this language issue
applies to the infinite precision integer case.

John
gateley@tilde.csc.ti.com

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

* Re: Garbage Collection
  1988-12-19 16:12                         ` John Gateley
@ 1988-12-20 19:34                           ` Bill Wolfe
  0 siblings, 0 replies; 64+ messages in thread
From: Bill Wolfe @ 1988-12-20 19:34 UTC (permalink / raw)


In article <65914@ti-csl.CSNET>, gateley@m2.csc.ti.com (John Gateley) writes:
> >> [I say infinite precision arithmetic is a good example of why GC is needed
> >>  sometimes].
> >
> >     The deallocation of every object in the local environment is
> >     performed as an automatic service when a procedure, function,
> >     or local block is exited.  This is not garbage collection,
> >     because the programmer has implicitly directed that the 
> >     destruction be performed.  
> 
> But, integers are not always deallocated. They may be returned as the
> result of a function, assigned to global variables, placed in the 
> heap as parts of other data objects etc. 

    What we are (presumably) discussing here is the space management 
    applying to literals and/or anonymous values of some arbitrary type.  
    During compilation, the compiler will evaluate each literal as 
    an anonymous value of the appropriate type.  Anonymous values differ 
    from named values only in that the programmer cannot explicitly refer 
    to them by name.

    Typically, literals are used in the construction of anonymous
    expressions which will ultimately serve as a value to be assigned.
    They are then being supplied as "in" parameters, and we have already
    discussed the proper method by which compilers should handle anonymous
    values passed as "in" parameters: they should be passed by handoff;
    since no external name exists, there is no need to set any external
    object to "undefined".  Since anonymous values cannot simply exist
    in mid-air, and must always be consumed in the course of some statement,
    we know that they will always be consumed.  By the rules of Ada, they
    cannot be supplied as "in out" or "out" parameters; hence, the mechanism
    described for handling anonymous values which are being passed as "in"
    parameters in a space-efficient manner serves to cover all cases, if
    we treat assignment as a procedure requiring an "in" parameter for the
    source value; otherwise, the extension to this case is straightforward. 

    Thus, we have completely described the space management applicable to
    literals and other anonymous values, such that these values can be
    managed effectively without any need for recourse to garbage collection.

    All that is needed is a tighter definition of what happens to an 
    anonymous value which is passed as an "in" parameter.  Note that
    this analysis does not depend upon the amount of space which must
    be used to contain any given anonymous value.



                                           Bill Wolfe

                                   wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-11 19:11           ` Garbage Collection William Thomas Wolfe,2847,
  1988-12-12  5:29             ` John Gateley
@ 1989-01-02 17:51             ` ryer
  1989-01-05  8:31               ` William Thomas Wolfe,2847,
  1989-01-06 16:58             ` ryer
  2 siblings, 1 reply; 64+ messages in thread
From: ryer @ 1989-01-02 17:51 UTC (permalink / raw)



Currently, Ada neither requires nor precludes garbage collection.  For 
example, the Symbolics Ada compiler provides it (as well they should), but
none of the eight cross-compilers for the 1750A computer does (as they 
shouldn't).

What are you (any of you) proposing?  That ALL Ada compilers should have
garbage collection?  Than no Ada compilers should be allowed to have it?
Pragmas?

Each day I find a new collection of comments on this note, debating the
goodness of garbage collection in the abstract.  I think that the Ada 
language has already taken the only defensible position, and would be
happy to explain why if anyone wants to take a different concrete position.

Mike "speaking only for myself" Ryer
Intermetrics, Inc.

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

* Re: Garbage Collection
  1989-01-02 17:51             ` ryer
@ 1989-01-05  8:31               ` William Thomas Wolfe,2847,
  0 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1989-01-05  8:31 UTC (permalink / raw)


From article <124000028@inmet>, by ryer@inmet.UUCP:
> Currently, Ada neither requires nor precludes garbage collection.  [...] 
> What are you (any of you) proposing?  That ALL Ada compilers should have
> garbage collection?  Than no Ada compilers should be allowed to have it?
> Each day I find a new collection of comments on this note, debating the
> goodness of garbage collection in the abstract.  I think that the Ada 
> language has already taken the only defensible position, and would be
> happy to explain why if anyone wants to take a different concrete position.

    OK, I'll take the position that Ada should be defined such that
    no Ada compilers should be allowed to have garbage collection.

    I charge that GC encourages the production of sloppy code which
    is difficult to maintain and which compiles into permanently inefficient
    programs, that code can be written by space-conscious programmers
    at least as fast as by those who use GC as a crutch, and that such
    code will require less debugging time due to the more complete 
    understanding of the problem which is possessed by a programmer 
    who comprehends all aspects (both space and time) of his/her code,
    and that GC retards portability by making code non-reuseable from
    the perspective of real-time programmers.

    For all these reasons, I conclude that GC should be prohibited, 
    just as the GOTO should be (but unfortunately, is not yet) prohibited. 
    
    Your turn.



                                            Bill Wolfe

                                    wtwolfe@hubcap.clemson.edu

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

* Re: Garbage Collection
  1988-12-11 19:11           ` Garbage Collection William Thomas Wolfe,2847,
  1988-12-12  5:29             ` John Gateley
  1989-01-02 17:51             ` ryer
@ 1989-01-06 16:58             ` ryer
  1989-01-08 19:24               ` William Thomas Wolfe,2847,
  2 siblings, 1 reply; 64+ messages in thread
From: ryer @ 1989-01-06 16:58 UTC (permalink / raw)



Why some Ada compilers should be allowed to perform garbage collection:

a. Because they are to generate code that coexists in an environment with
languages like LISP where garbage collection is assumed.  They want to
operate on data structures shared with other languages.

b. Because the current world supply of "reusable" Ada components have
not all been written carefully for space management, and in prototyping
any reusable component (that works) may be better than none.

c. Because some users are very unconcerned with the efficiency or
reusability of their programs.  This applies to the run-only-once
programs such as in a training environment, or where a computer is used
as an oversized desk calculator just to obtain numeric answers.  It may
be that all computer science students should become careful implementers
of ADTs.  I doubt that all particle physicists need to develop this
discipline even though they may write substantial programs.

d. It Is FEASIBLE for the computer to do a good job of garbage collection
automatically and it does reduce the size of the source code which does
tend to reduce the life cycle cost of owning that code.  It may increase
execution time but some users will prefer this tradeoff.

Therefore, garbage collection should not be prohibited, even though it
is inappropriate and harmful in some cases.  Different applications
can benefit from different compilers.

Mike Ryer
Intermetrics

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

* Re: Garbage Collection
  1989-01-06 16:58             ` ryer
@ 1989-01-08 19:24               ` William Thomas Wolfe,2847,
  0 siblings, 0 replies; 64+ messages in thread
From: William Thomas Wolfe,2847, @ 1989-01-08 19:24 UTC (permalink / raw)


From article <124000031@inmet>, by ryer@inmet.UUCP:
> 
> Why some Ada compilers should be allowed to perform garbage collection:
> 
> a. Because they are to generate code that coexists in an environment with
> languages like LISP where garbage collection is assumed.  They want to
> operate on data structures shared with other languages.

     Assume that the Ada code cleans up after itself.  Then that code
     can exist perfectly in a Lisp environment; since it does not
     contribute to the garbage problem, the Ada code will be a
     very welcome guest indeed.  

> b. Because the current world supply of "reusable" Ada components have
> not all been written carefully for space management, and in prototyping
> any reusable component (that works) may be better than none.

     However, I'll bet that most have.  At any rate, once New Ada
     emerges, you can bet there will be an immediate upgrading
     taking place among all the component vendors; the upgraded
     components will be available long before the New Ada compilers.

> c. Because some users are very unconcerned with the efficiency or
> reusability of their programs.  This applies to the run-only-once
> programs such as in a training environment, or where a computer is used
> as an oversized desk calculator just to obtain numeric answers.  It may
> be that all computer science students should become careful implementers
> of ADTs.  I doubt that all particle physicists need to develop this
> discipline even though they may write substantial programs.

     Let's face it: with generics, multitasking, and so on, Ada is
     a language for professionals.  Most nonprofessionals should be using
     application-specific languages, which are implemented in... Ada. 

     Particle physicists usually require high-performance software,
     and they should therefore turn to professional application developers.

> d. It Is FEASIBLE for the computer to do a good job of garbage collection
> automatically and it does reduce the size of the source code which does
> tend to reduce the life cycle cost of owning that code.  It may increase
> execution time but some users will prefer this tradeoff.

     The reduction in size is trivial.  Additionally, I contend that there
     are positive side effects with regard to a more complete programmer
     understanding of the problem, which leads to better overall code.

     Furthermore, the use of the ADT paradigm, in conjunction with 
     the automatic destruction of local environments, means that
     application programmers will almost never have to deal with deallocation
     on an explicit basis anyway.  This will provide positive incentive
     to use professionally designed ADTs, leading once again to higher-
     quality code.

> Therefore, garbage collection should not be prohibited, even though it
> is inappropriate and harmful in some cases. 

     I'll heartily agree that GC is inappropriate and harmful, but
     you still haven't proven your case.


                                     Bill Wolfe

                              wtwolfe@hubcap.clemson.edu

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

end of thread, other threads:[~1989-01-08 19:24 UTC | newest]

Thread overview: 64+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1988-12-03 22:53 Collective response to := messages Erland Sommarskog
1988-12-04 20:41 ` William Thomas Wolfe,2847,
1988-12-05  5:47   ` Richard A. O'Keefe
1988-12-05 12:45     ` William Thomas Wolfe,2847,
1988-12-06  1:54       ` Richard A. O'Keefe
1988-12-06 20:43         ` William Thomas Wolfe,2847,
1988-12-07 15:22         ` Collective response to := messa ron
1988-12-11 19:11           ` Garbage Collection William Thomas Wolfe,2847,
1988-12-12  5:29             ` John Gateley
1988-12-12 18:19               ` William Thomas Wolfe,2847,
1988-12-13  1:02                 ` Alexander Klaiber
1988-12-13 18:37                   ` William Thomas Wolfe,2847,
1988-12-13 23:36                     ` Alexander Klaiber
1988-12-14  3:26                       ` William Thomas Wolfe,2847,
1988-12-14 17:16                       ` Stephe Leake
1988-12-15 14:43                       ` Thomas P. Morris
1988-12-14 23:30                     ` John Gateley
1988-12-15 19:25                       ` William Thomas Wolfe,2847,
1988-12-19 16:12                         ` John Gateley
1988-12-20 19:34                           ` Bill Wolfe
1988-12-16  0:49                     ` Keys are references, too (was Re: Garbage Collection) Badger BA 64810
1988-12-18 18:42                       ` William Thomas Wolfe,2847,
1988-12-13 20:22                   ` Garbage Collection William Thomas Wolfe,2847,
1988-12-14  6:40                     ` Richard A. O'Keefe
1988-12-14 17:43                       ` William Thomas Wolfe,2847,
1989-01-02 17:51             ` ryer
1989-01-05  8:31               ` William Thomas Wolfe,2847,
1989-01-06 16:58             ` ryer
1989-01-08 19:24               ` William Thomas Wolfe,2847,
  -- strict thread matches above, loose matches on Subject: below --
1988-12-05  6:53 Collective response to := messages Erland Sommarskog
1988-12-03 21:08 Erland Sommarskog
1988-12-04 20:30 ` William Thomas Wolfe,2847,
1988-11-28 22:19 Geoff Mendal
1988-11-29 14:39 ` Dennis Doubleday
1988-11-29 21:08 ` Ray Trent
1988-11-30 14:37   ` Stephe Leake
1988-12-01 14:54     ` David S. Rosenblum
1988-12-02 20:21       ` William Thomas Wolfe,2847,
1988-12-04 21:15         ` David S. Rosenblum
1988-12-04 23:27           ` William Thomas Wolfe,2847,
1988-12-05 14:46             ` David S. Rosenblum
1988-12-05 21:23               ` William Thomas Wolfe,2847,
1988-12-07 17:33                 ` Stephe Leake
1988-12-07 17:15             ` Stephe Leake
1988-12-07 16:07       ` Stephe Leake
1988-12-09  3:15         ` David S. Rosenblum
1988-12-01 21:31     ` Ray Trent
1988-12-07 16:21       ` Stephe Leake
1988-11-30 16:29   ` David S. Rosenblum
1988-11-30 18:29     ` William Thomas Wolfe,2847,
1988-11-30 22:28       ` David S. Rosenblum
1988-12-01  3:09         ` William Thomas Wolfe,2847,
1988-12-01 15:16           ` David S. Rosenblum
1988-12-02 19:31             ` William Thomas Wolfe,2847,
1988-12-04 21:03               ` David S. Rosenblum
1988-12-05  2:34                 ` William Thomas Wolfe,2847,
1988-12-05 14:07                   ` David S. Rosenblum
1988-12-07 17:26                     ` Stephe Leake
1988-12-01 18:31     ` Ray Trent
1988-12-02 14:49       ` David S. Rosenblum
1988-11-30 18:24   ` Robert Eachus
1988-12-02 14:58     ` David S. Rosenblum
1988-12-02 19:34   ` Mark C. Adolph
1988-11-29 21:44 ` William Thomas Wolfe,2847,

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