* Initialization
@ 1990-06-14 16:37 Michael Feldman
1990-06-14 17:38 ` Initialization Robert Firth
1990-06-14 19:37 ` Initialization Mike Murphy
0 siblings, 2 replies; 6+ messages in thread
From: Michael Feldman @ 1990-06-14 16:37 UTC (permalink / raw)
I have a rationale-type questions regarding an apparent irregularity
in Ada, namely in the area of default initializations.
- We know that a _variable_ can be initialized in its declaration, e.g.
X: T := some_expression;
where some_expression need not even be static. [digression: over-use of
this can be risky IMHO because of nastiness if some_expression manages to
propagate an exception - the point is that initialization is permitted].
- We know that the components of a _record_ type can be default-initialized
in the definition of the record type, e.g.
type R is record
F1 : T1 := something;
F2 : T2 := something_else;
end record;
where some thing something_else can be e.g. aggregates.
I don't remember having seen any discussion on the group about why other
types cannot be default-initialized, e.g.
type Little is range -10 .. 10 := 0;
or
type Vector is array (1..10) of float := (1..10 => 0.0);
or even
type Vector is array (integer range <>) of float := (others => 0.0);
The last 3 examples are not permitted; it's obvious at least to me that
there would be great benefit in permitting them. What are the costs?
Can someone speak authoritatively about why this irregularity exists? The
Ada Rationale gives a nice justification of default initializations (for
record types, of course) but doesn't say boo about why, if they are so
valuable, they are not allowed uniformly. I'm one of these guys who always
wonders why irregularities in _designed_ languages exist. There is usually
a pretty good reason, but in this case it certainly isn't obvious.
(Irregularities even in natural languages often have good linguistic reasons).
Thanks for whatever enlightenment is forthcoming.
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
+1-202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Initialization
1990-06-14 16:37 Initialization Michael Feldman
@ 1990-06-14 17:38 ` Robert Firth
1990-06-14 22:28 ` Initialization Michael Feldman
1990-06-14 19:37 ` Initialization Mike Murphy
1 sibling, 1 reply; 6+ messages in thread
From: Robert Firth @ 1990-06-14 17:38 UTC (permalink / raw)
In article <1957@sparko.gwu.edu> mfeldman@seas.gwu.edu (Michael Feldman) writes:
>I have a rationale-type questions regarding an apparent irregularity
>in Ada, namely in the area of default initializations.
There is no good reason for the irregularity. Since a record
component can be of any type, the implementation of
record
Component : Thing := Initial_Value;
end record;
is no more and no less difficult than the implementation of
type Thing is Type_Definition := Initial_Value;
would be. There are no serious parsing difficulties with the
above syntax, and no additional semantic issues.
The reason for the irregularity is historical. In the original
Green language, the syntax of a record type definition read
record_type_definition ::= RECORD component_list END RECORD
component_list ::= {object_declaration} [variant_part] | NULL ;
Because the syntax of object_definition was reused, the ability to
initialise the component got carried over automatically. When this
was noticed, it was decided that this was a useful thing to have.
I recall asking Jean why he didn't make the type model more regular
by allowing all types to have initialisation expressions, and his
reply was that you could always achieve this effect by nesting the
type you wanted in a record, and he didn't want to add extra syntax.
Please do not ask me to defend this position.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Initialization
1990-06-14 17:38 ` Initialization Robert Firth
@ 1990-06-14 22:28 ` Michael Feldman
0 siblings, 0 replies; 6+ messages in thread
From: Michael Feldman @ 1990-06-14 22:28 UTC (permalink / raw)
In article <7540@fy.sei.cmu.edu> firth@sei.cmu.edu (Robert Firth) writes:
>
> I recall asking Jean why he didn't make the type model more regular
> by allowing all types to have initialisation expressions, and his
> reply was that you could always achieve this effect by nesting the
> type you wanted in a record, and he didn't want to add extra syntax.
> Please do not ask me to defend this position.
Don't worry. If this is the extent of the reasoning, it's entirely
indefensible IMHO. That's the way it goes. Sigh...
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
+1-202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Initialization
1990-06-14 16:37 Initialization Michael Feldman
1990-06-14 17:38 ` Initialization Robert Firth
@ 1990-06-14 19:37 ` Mike Murphy
1990-06-14 22:43 ` Initialization Michael Feldman
1 sibling, 1 reply; 6+ messages in thread
From: Mike Murphy @ 1990-06-14 19:37 UTC (permalink / raw)
In article <1957@sparko.gwu.edu> mfeldman@seas.gwu.edu (Michael Feldman) writes:
>I don't remember having seen any discussion on the group about why other
>types cannot be default-initialized, e.g.
> type Little is range -10 .. 10 := 0;
>or
> type Vector is array (1..10) of float := (1..10 => 0.0);
>or even
> type Vector is array (integer range <>) of float := (others => 0.0);
I question how useful type initialization is given that we can easily
initialize variables, but I agree that it is an irregularity to only
allow it for record types. When I first read this question I thought,
yea, that should be easy to do. But then I thought of some complications.
To take your above example, suppose we later said:
subtype PosLittle is Little range 1..10;
p : PosLittle;
What is p initialized to?
If we implicitly initialize p to 0 we should raise constraint_error;
is that acceptable?
A related issue is initializing unconstrained arrays; either we limit
the initialization to the others clause, or we have situations like:
type Vector is array (integer range <>) of float :=
(0 => 0.0, others => 1.0);
v : Vector(1..10);
What happens here? Either we could raise constraint_error because there
is an initialization to a component outside the range of v, or we could
treat it like a variant part of a record that is not used and just ignore
that part of the initialization. Which brings up the fact that type
initialization is not free; it often requires building an implicit
procedure that the compiler calls to dynamically decide how to initialize
the object.
A last case is initializing access types; is anything other than "null"
a legal initial value, e.g.
type astring is access string := new string'("void");
a : astring(1..3); -- constraint_error?
-- Mike Murphy
-- UUCP: sun!decwrl!mips!murphy or murphy@mips.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Initialization
1990-06-14 19:37 ` Initialization Mike Murphy
@ 1990-06-14 22:43 ` Michael Feldman
0 siblings, 0 replies; 6+ messages in thread
From: Michael Feldman @ 1990-06-14 22:43 UTC (permalink / raw)
In article <39390@mips.mips.COM> murphy@mips.COM (Mike Murphy) writes:
>
> To take your above example, suppose we later said:
> subtype PosLittle is Little range 1..10;
> p : PosLittle;
> What is p initialized to?
> If we implicitly initialize p to 0 we should raise constraint_error;
> is that acceptable?
Sure. Sounds OK to me. But you're right - the subtype issue does complicate
matters a bit.
>
> A related issue is initializing unconstrained arrays; either we limit
> the initialization to the others clause, or we have situations like:
> type Vector is array (integer range <>) of float :=
> (0 => 0.0, others => 1.0);
> v : Vector(1..10);
I'm sure a counterexample could be found, but I guess I would allow only
"others" aggregates for unconstrained array types. Explicitly supplying an
index for something whose index range is undefined is not a sensible
thing to do, it seems to me.
> [ . . . ] Which brings up the fact that type
> initialization is not free; it often requires building an implicit
> procedure that the compiler calls to dynamically decide how to initialize
> the object.
Indeed. But there are many areas requiring this sort of dynamic decision
anyway.
>
> A last case is initializing access types; is anything other than "null"
> a legal initial value, e.g.
> type astring is access string := new string'("void");
Hmmm. I'd advocate against this kind of dynamic initialization even if
it were a variable declaration. If Storage_Error were raised, for example,
the exception would undoubtedly propagate to an undesirable place.
(since it would be raised in an elaboration, the current frame's handler
can't handle, therefore the exception propagates).
Might be legal, but not a good idea. This is what I argued in my last
posting: initializations can be good, but can be too powerful for their
own good if used over-zealously.
> a : astring(1..3); -- constraint_error?
^^^^^^^ Hmmm. I wasn't aware that one could supply a
constraint this way. For a string, sure. For an "access to string", is
this legal Ada (i.e. the implicit "new")? If so, I just learned a new style.
Mike Feldman
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pre-condition vs. Post-condition
@ 1991-03-24 21:23 stt
1991-03-25 16:00 ` Arthur Evans
0 siblings, 1 reply; 6+ messages in thread
From: stt @ 1991-03-24 21:23 UTC (permalink / raw)
Re: Should documentation on exception be preconditions or postconditions
This is pretty much of a style issue in my view, but
I much prefer Norm Cohen's approach for general readability.
That is, document the preconditions for normal action,
and then document the result of violating the preconditions.
I don't see why it really matters whether the exception is raised
explicitly or implicitly, or whether it is a predefined or user-defined
exception, for in Ada, the nearly universal result of violating preconditions
is an exception, whether you state it or not.
Seeing exceptions as the result of violating preconditions emphasizes
their "exceptional" nature, and properly discourages using
exceptions as a kind of "status code." A good rule (subject to the
usual exceptions that prove it!) is that any exception raised at
run-time represents a program bug or an external failure, and the only
reason to have user-defined exceptions is to provide better diagnostics
in post-mortem debugging of what are essentially unrecoverable errors.
Exceptions might trigger recovery, but probably only at a high level
(e.g., in an interactive program, they would flush the current
activity and reprompt the human operator; in a fault-tolerant system
they might cause the failing task to be decommissioned, or reset
and reelaborated.)
I realize this is a pretty extreme view of exceptions, namely that
they are primarily a debugging tool, not a programming tool, but
it is consistent with the "extreme prejudice" for efficient non-exceptional
execution speed over exception-handling speed.
Another implication of this view of exceptions is that surrounding
a single subprogram call with an exception handler is generally a bad
idea, since it implies that an exceptional condition is in fact
expected to happen! Further, it implies that design rules stating that
undocumented exceptions should never be propagated are possibly misguided,
since handling "others" and raising some catch-all exception
is throwing away information which may be critical to post-mortem debugging.
Of course, once a subsystem gets to the point of being "fully" debugged,
and is being reused more and more, all exceptions which can be
propagated should be documented, though it may still be more appropriate
to document certain exceptions on a subsystem-wide basis, rather
than trying to identify each individual subprogram which could propagate them.
The exception handler attempting the recovery (if any), probably does
not "know" which particular subprogram call failed anyway, and it
may be more useful to know what is a reasonable recovery strategy
(e.g., how to "reset" the subsystem so as to allow clients to continue
to use it), than to know exactly which subprograms can cause the
subsystem to enter its exceptional state.
Therefore, if an exception is intended to be used for recovery
rather than simply debugging, the most important thing is that
the particular exception raised identifies which subsystem failed,
in what error state (if any) it is now, and what sort of reset
operation is appropriate. If the exception
simply indicates that a bad parameter was passed in somewhere,
there is probably no obvious recovery strategy other than to
take two aspirin and fire up the source-level debugger in the morning...
S. Tucker Taft stt@inmet.inmet.com
Intermetrics, Inc.
Cambridge, MA 02138
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pre-condition vs. Post-condition
1991-03-24 21:23 Pre-condition vs. Post-condition stt
@ 1991-03-25 16:00 ` Arthur Evans
1991-03-25 17:05 ` Michael Feldman
0 siblings, 1 reply; 6+ messages in thread
From: Arthur Evans @ 1991-03-25 16:00 UTC (permalink / raw)
Cc: stt
Tucker Taft (stt@inmet.inmet.com) states that, in general, exceptions
should be used only for serious errors, and that it is rarely proper to
provide local handling. I disagree,
In many cases, a programming is continually processing data, and (as
others have already remarked) it is almost as hard to determine in
advance if the data are flawed as it is to do the processing. Examples:
- An aplication is processing radar data. The code might determine
that a plane has moved 100 miles since the last report a few
milliseconds ago, or changed altitude by 4000 feet, both impossible.
Probably the problem is noise in the returned radar data, and the
best way to deal with it is to raise a BAD_RADAR_DATA exception.
The calling code can note the problem and ignore the data, if the
problem is infrequent. It might report frequent errors in a trouble
report. In any case, though, the code processing the data can best
serve the application by just saying (in effect), "These data are no
good. Do something about the problem."
- Consider reading a text file in which each line contains formatted
data. The caller would check for EOF before calling the routine
which reads the next line and processes it. Again, invalid data
might be reported by a BAD_DATA exception. However, a bad input
file might be manifested in the processing code by an unexpected EOF
-- a line with missing trailing fields or a missing line-terminator.
The data processing routine would probably find it most convenient
to catch the EOF exception and reflect it to the caller as BAD_DATA.
We have here a mixture of checking for the EOF by the caller, for
whom it is an expected event, and catching an EOF exception in the
line processor, for whom it represents incorrect data.
I think most dogmatic statements about how exceptions should be used
turn out to have so many exceptions as to be useless. (Sorry about
that.) Exceptions represent yet another tool in the hands of the
application designer; as with other tools, they must be used with care
and taste.
Art Evans
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pre-condition vs. Post-condition
1991-03-25 16:00 ` Arthur Evans
@ 1991-03-25 17:05 ` Michael Feldman
1991-03-26 4:31 ` Jim Showalter
0 siblings, 1 reply; 6+ messages in thread
From: Michael Feldman @ 1991-03-25 17:05 UTC (permalink / raw)
In article <23141@as0c.sei.cmu.edu> ae@sei.cmu.edu (Arthur Evans) writes:
>Tucker Taft (stt@inmet.inmet.com) states that, in general, exceptions
>should be used only for serious errors, and that it is rarely proper to
>provide local handling. I disagree,
>
...lots of good stuff deleted
>
>I think most dogmatic statements about how exceptions should be used
>turn out to have so many exceptions as to be useless. (Sorry about
>that.) Exceptions represent yet another tool in the hands of the
>application designer; as with other tools, they must be used with care
>and taste.
I couldn't agree more. On the other hand, that there is no much discussion
and controversy about the proper use of exceptions - as there always is
about any language feature - testifies to the value of threads like this
on the net. As is the case with all tools, different people and different
projects have differing ideas about what constitutes "care" and "taste."
In the end, a consistent project-level convention about exceptions - a
well-thought out and careful design - will of course be the best policy.
This thread started with a discussion of pre- and post-conditions, to which
I'd like to return. It seems that we are using two different definitions
of preconditions. One is
(1) "A precondition is my requirement that must be met by the client, and my
program can detect whether or not it is met."
The other is
(2) "A precondition is my requirement that must be met by the client, and my
program CANNOT ALWAYS detect whether or not it is met."
The nastiest precondition is the one that requires that IN parameters be
initialized. This is an implicit precondition on ALL subprograms - indeed,
on all expressions - that CANNOT be tested reliably. We say - glibly -
that an uninitialized variable contains "garbage." But garbage is still
a bit pattern, AND THE BIT PATTERN MAY HAPPEN TO LIE IN THE RANGE OF
THE VARIABLE. If it does, there's no way to raise an exception on it.
In some recent discussions with folks close to Ada9x, I have discovered that
one of the proposals is to allow default initial values for all types and
subtypes. As you know, Ada83 allows default initial values only for objects,
not for types, except for fields in a record. It has come to my attention
that this is a controversial proposal; it's not clear if it will survive
review.
If Ada allowed default initial values for all types and subtypes, e.g.
SUBTYPE Little IS Integer RANGE -100..100 := 0;
or even
TYPE Vector IS ARRAY (IndexType RANGE <>) OF Integer := (OTHERS => 0);
it would be much easier for projects to require that all project types be
initialized, which would greatly simplify design, since that nasty
precondition could be met globally for the whole project. (Of course
Ada could not check whether the project rule was being followed, but at
least the humans could...)
I can't think of anything that would make this harder to implement than
default _object_ initialization, and therefore it's a fairly small change
with a big potential payoff.
If you agree that default initialization of types is an important
feature for Ada9x, write to ada9x@ajpo.sei.cmu.edu about it.
Mike Feldman
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pre-condition vs. Post-condition
1991-03-25 17:05 ` Michael Feldman
@ 1991-03-26 4:31 ` Jim Showalter
1991-03-26 10:21 ` Richard A. O'Keefe
0 siblings, 1 reply; 6+ messages in thread
From: Jim Showalter @ 1991-03-26 4:31 UTC (permalink / raw)
I was one of the submitters to 9x of the proposal that all types
have default initialization. This seems so obviously right I
can't see why it wouldn't survive review. Why should records
be singled out for special treatment?--it's one of those annoying
"gotchas" that piss people off when they're trying to learn the
language. I'm tired of seeing the user-view of the language--the
only one the user cares about--distorted by concerns for the language
implementers. Compiler writers are SUPPOSED to have a hard job so
that the user community has an easy job--consider the relative
percentages of time saved! One week of additional compiler writer
time is probably worth 50 years of additional programmer time.
An even more radical proposal would be to introduce constructors,
a la C++.
--
***** DISCLAIMER: The opinions expressed herein are my own. Duh. Like you'd
ever be able to find a company (or, for that matter, very many people) with
opinions like mine.
-- "When I want your opinion, I'll read it in your entrails."
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Pre-condition vs. Post-condition
1991-03-26 4:31 ` Jim Showalter
@ 1991-03-26 10:21 ` Richard A. O'Keefe
1991-03-27 21:32 ` Initialization Paul Stachour
0 siblings, 1 reply; 6+ messages in thread
From: Richard A. O'Keefe @ 1991-03-26 10:21 UTC (permalink / raw)
In article <jls.669961889@rutabaga>, jls@rutabaga.Rational.COM (Jim Showalter) writes:
> I was one of the submitters to 9x of the proposal that all types
> have default initialization. This seems so obviously right I
> can't see why it wouldn't survive review. Why should records
> be singled out for special treatment?
It is obviously a good idea to make the language consistent with itself.
I must admit, though, that I really like Dijkstra's notation, in which
it is simply impossible to have an uninitialised variable, the language
(and the array data structure) being designed that every "location" has
to be initialised explicitly before it can come into existence. I
recently spent rather more time than I wanted to helping someone fix a
C program. We eventually discovered that an initialisation routine that
had the job of allocating a bunch of arrays was being called BEFORE the
global variables with the desired array sizes were initialised. Now C
has this helpful little rule that global variables are initialised to
0 (0.0, NIL, ASCII.NUL, FALSE, or whatever the equivalent happens to be).
Precisely *because* the variables were initialised to a "sensible" value
the error was unexpectedly hard to detect.
I would rather see features that help people detect or avoid the error
of using an uninitialised variable rather than features which define
the problem away. For example, if arrays with fill pointers were a
standard part of the language (perhaps defined as a standard package),
then we'd be close enough to Dijkstra's arrays to get some of the
protection without being too far from the kind of array already present.
Don't expect default initial values for types to be an unmixed blessing.
--
Seen from an MVS perspective, UNIX and MS-DOS are hard to tell apart.
^ permalink raw reply [flat|nested] 6+ messages in thread
* Initialization
1991-03-26 10:21 ` Richard A. O'Keefe
@ 1991-03-27 21:32 ` Paul Stachour
0 siblings, 0 replies; 6+ messages in thread
From: Paul Stachour @ 1991-03-27 21:32 UTC (permalink / raw)
ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) writes:
>I would rather see features that help people detect or avoid the error
>of using an uninitialised variable rather than features which define
>the problem away. For example, if arrays with fill pointers were a
>standard part of the language (perhaps defined as a standard package),
>then we'd be close enough to Dijkstra's arrays to get some of the
>protection without being too far from the kind of array already present.
>Don't expect default initial values for types to be an unmixed blessing.
As one who has programmed regularly in more than an half-dozen languages,
and has worked on teams that have implemented 3 compilers for different
lanauges, I agree.
If you have a variable that is unitialized, then a good flow anyalysis
tool (we had some inside one of the compilers) can follow your
control-flow and give you "used before set" messages. When you do
have something initialized, it is, by definition, set. Thus the
flow-analysis gives you nothing.
I long for the (ancient) FORTRAN II compiler I used on an IBM 7074
in the mid-1960s. It set all of the words in the machine to an
"invalid pattern" before beginning your program. And then if you
fetched anything that hadn't been set, you took a hardware fault and
the run-time told what you were doing wrong.
Much like Saber-C and other good c-interpreters can do today,
but with hardware support.
One problem is when you have an uninitialized item as a component
of a struacture and you assign one instance of the structre to another.
Do you get a fault or not. You really aren't "using" the item yet.
Enjoy. ...Paul
--
Paul Stachour SCTC, 1210 W. County Rd E, Suite 100
stachour@sctc.com Arden Hills, MN 55112
[1]-(612) 482-7467
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~1991-03-27 21:32 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1990-06-14 16:37 Initialization Michael Feldman
1990-06-14 17:38 ` Initialization Robert Firth
1990-06-14 22:28 ` Initialization Michael Feldman
1990-06-14 19:37 ` Initialization Mike Murphy
1990-06-14 22:43 ` Initialization Michael Feldman
-- strict thread matches above, loose matches on Subject: below --
1991-03-24 21:23 Pre-condition vs. Post-condition stt
1991-03-25 16:00 ` Arthur Evans
1991-03-25 17:05 ` Michael Feldman
1991-03-26 4:31 ` Jim Showalter
1991-03-26 10:21 ` Richard A. O'Keefe
1991-03-27 21:32 ` Initialization Paul Stachour
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox