CVS difference for ai05s/ai05-0177-1.txt
--- ai05s/ai05-0177-1.txt 2010/10/19 03:51:18 1.3
+++ ai05s/ai05-0177-1.txt 2010/10/21 03:06:01 1.4
@@ -1,13 +1,24 @@
-!standard 13.11.1(3/2) 10-06-13 AI05-0177-1/02
+!standard 3.1(3/2) 10-10-20 AI05-0177-1/03
+!standard 3.11.1(1/1)
+!standard 6.1(20)
+!standard 6.1(30)
+!standard 6.7(2/3)
+!standard 6.7(3/2)
+!standard 6.7(5/2)
+!standard 6.8(0)
+!standard 8.3(18/2)
+!standard 8.3.1(3/2)
+!standard 13.14(8/1)
+!standard 13.14(10.1/3)
!class Amendment 09-10-29
!status work item 09-10-29
!status received 09-03-15
!priority Medium
!difficulty Easy
-!subject Parameterized expressions
+!subject Expression functions
!summary
-A parameterized expression can define the body of a function, even in a package
+A expression function can define the body of a function, even in a package
specification. They act like default expressions for
freezing and evaluation purposes.
@@ -32,11 +43,11 @@
!proposal
- parameterized_expression ::=
+ expression_function ::=
[overriding_indicator]
function_specification is (<*parameterized_*expression>);
-[Note: The parens are needed to clearly (?) separate a parameterized expression
+[Note: The parens are needed to clearly (?) separate a expression function
from the start of a normal function body. Perhaps it would be
better to use a keyword somewhere to make it crystal-clear.]
@@ -49,29 +60,176 @@
The dynamic semantics are the same as a function whose body contains nothing but
"return parameterized_expression".
-A parameterized expression can be used as a declaration or as the completion of
+A expression function can be used as a declaration or as the completion of
a function specification. If used as a completion, the completion can be
given anywhere in the same package (if the declaration is a package). Specifically,
-parameterized expressions in a private part can complete function declarations
+expression functions in a private part can complete function declarations
from the visible part.
-For consistency of syntax, we also allow null procedures to complete declarations
-in the same way as parameterized expressions. [Editor's note: I think we should
-be able to use the same wording for that purpose.]
-
Freezing: The renamed expression would freeze as does a default expression. That
is, freezing would only be performed at the point of a call of the function,
with the expression essentially in-lined at that point. (Of course, if that call
is in a default expression, the freezing would be deferred again.)
!wording
+
+Add expression_function_declaration to the list of basic_declarations in 3.1(3/2).
+
+Modify the AARM Note 3.11(10.a.1/1):
+A subprogram can be completed by a renaming-as-body{, a null_procedure_declaration, or
+an expression_function_declaration}, and we need ...
+
+[Editor's note: This makes it clear that null procedures and expression functions used as completions
+might need an Elaboration_Check.]
+
+Modify the last sentence of 3.11.1(1/1):
+
+A body is a body, an entry_body, {a null_procedure_declaration or
+an expression_function_declaration that completes another declaration}, or a renaming-as-body (see 8.5.4).
+
+
+Change 6.1(20):
+... A completion is not allowed for an abstract_subprogram_declaration{,} [or] a
+null_procedure_declaration (see 6.7){, or a expression_function_declaration (see 6.8)}.
+
+Add to the end of 6.1(30):
+
+Finally, a function defined by an expression_function_declaration is an expression
+function; a function declared by a subprogram_declaration is not. See 6.8, "Expression Functions".
+
+Add after 6.7(2/3):
+
+Legality Rules
+
+A null_procedure_declaration need not be the completion of a previous declaration, but if a null_procedure_declaration
+is a completion, it shall be the completion of a subprogram_declaration or generic_subprogram_declaration.
+The profile of a null_procedure_declaration that completes a declaration shall conform fully to that of the declaration.
+
+[Editor's note: This is mostly copied from the text for subprogram bodies, some redundancy removed.]
+
+Modify 6.7(3/2):
+
+A null_procedure_declaration declares a null procedure. A completion is not allowed for a null_procedure_declaration{,
+however a null_procedure_declaration can complete a previous declaration}.
+
+Modify 6.7(5/2):
+
+The elaboration of a null_procedure_declaration has no {other} effect {than to establish that the
+expression function can be called without failing the Elaboration_Check}.
+
+Add a new clause:
+
+6.8 Expression functions
+
+An expression_function_declaration provides a shorthand to declare a function that returns a single expression.
+
+Syntax
+
+expression_function_declaration ::=
+ [overriding_indicator]
+ function_specification is
+ (*parameterized_*expression)
+ [aspect_specification];
+
+Name Resolution Rules
+
+The expected type for the *parameterized_*expression of an expression_function_declaration is
+the result type (see 6.5) of the function.
+
+Legality Rules
+
+An expression_function_declaration need not be the completion of a previous declaration, but if an expression_function_declaration
+is a completion, it shall be the completion of a subprogram_declaration or generic_subprogram_declaration.
+The profile of a expression_function_declaration that completes a declaration shall conform fully to that of the declaration.
+
+[Editor's note: We don't need to repeat any of the Legality Rules for return statements since none of them can fail here:
+the implicit return statement has to apply to this function (and isn't nested), there clearly is a return statement in this function,
+and none of the accessibility rules can fail because there can be no local declarations here.]
+
+Static Semantics
+
+An expression_function_declaration declares an expression function. A completion is not allowed for an expression_function_declaration,
+however an expression_function_declaration can complete a previous declaration.
+
+Dynamic Semantics
+
+The execution of an expression function is invoked by a subprogram call. For the execution of a
+subprogram call on an expression function, the execution of the subprogram_body is equivalent to a
+function body containing only a simple_return_statement that returns the *parameterized_*expression.
+
+AARM Discussion: The last sentence effectively means that all of the dynamic wording in 6.5 applies as
+needed, and we don't have to repeat it here.
+
+The elaboration of a expression_function_declaration has no other effect than to establish that the
+expression function can be called without failing the Elaboration_Check.
+
+Examples
+
+function Is_Origin (P : in Point) return Boolean is -- see 3.9
+ (P.X = 0 and P.Y = 0);
+
+
+Modify 8.3(18/2):
+
+* For a package_declaration, task declaration, protected declaration, generic_package_declaration, [or] subprogram_body{, or
+ expression_function_declaration}, the declaration is hidden from all visibility only until the reserved word is of the declaration;.
+
+[Editor's note: We need this to make the parameters visible in the *parameterized_*expression of
+an expression_function_declaration.]
+
+Add expression_function_declaration into the list of 8.3.1(3/2), after null_procedure_declaration.
+
+Modify 13.14(8/1):
+
+A static expression causes freezing where it occurs. An object name or nonstatic expression causes freezing
+where it occurs, unless the name or expression is part of a default_expression, a default_name,
+{the *parameterized_*expression of an expression function,} or a per-object expression of a component's
+constraint, in which case, the freezing occurs later as part of another construct.
+
+Modify 13.14(10.1/3) [as added by AI05-0019-1]:
-** TBD **
-[Lack of time prevented creating wording. The model is fairly well
-understood. - RLB]
+At the place where a function call causes freezing, the profile of the function is frozen. Furthermore,
+if a parameter of the call is defaulted, the default_expression for that parameter causes freezing.
+{If the function call is to an expression function, the *parameterized_*expression for the expression
+function causes freezing.}
+AARM Ramification: Freezing of the *parameterized_*expression only needs to be considered when the
+expression function is in the same compilation unit and there are no intervening bodies; the end of a
+declarative_part or library package freezes everything in it, and a body freezes everything declared
+before it.
+
+
!discussion
+Naming:
+
+These have been variously called expression renaming, parameterized expressions,
+and expression functions. Parameterized expressions best explains the intended
+use, but we named these expression functions as that works better with the existing
+wording. The primary issue is that an expression function either declares a
+subprogram or completes a subprogram. The vast majority of rules that apply to
+functions and more generally subprograms also apply to expression functions.
+If we called them parameterized expressions, neither the word "subprogram" nor
+"function" would appear; that would mean that additional wording would be needed
+to ensure that they are properly included in "function" and "subprogram" rules.
+
+We did "borrow" the parameterized expression name to mean the actual expression
+of an expression function. This simplifies some of the wording and re-enforces
+the usage intent.
+
+---
+
+A goal for expression functions is that they represent a subset of the capabilities
+of null subprograms in terms of the use as subprogram. If we didn't do that, we would
+have added another kind of subprogram, whose usages would be subtlely different than
+the existing kinds. That seems bad.
+
+In order to accomplish this, we added the capability of a null subprogram to represent
+a completion. This is not an important capability, but it increases the consistency
+of the various kinds of subprogram declaration.
+
+---
+
One could imagine these functions (when visible) to be used in
static expressions if the inlined expression would be static. This would
definitely allow abstracting expressions that currently are written as a
@@ -80,7 +238,7 @@
---
-It has been suggested to allow parameterized expressions as generic formal
+It has been suggested to allow expression functions as generic formal
subprogram defaults. This would increase the analogy with null procedures.
I didn't include this for three reasons:
@@ -107,9 +265,9 @@
!example
-** TBD **
+(See wording.)
---!corrigendum 4.5.1(0)
+--!corrigendum 6.8(0)
!ACATS test
@@ -2537,10 +2695,10 @@
spectrum here, but I think you (Bob) and I are on somewhat different places on
this spectrum.
-So for me, if a feature has more "potential for abuse"
-than some other feature, I will favor the one with less such potential, and not
-surprisingly that will sometimes "crimp" someone's style. If it doesn't do that
-now and then, it is probably too lax in my book.
+So for me, if a feature has more "potential for abuse" than some other feature,
+I will favor the one with less such potential, and not surprisingly that will
+sometimes "crimp" someone's style. If it doesn't do that now and then, it is
+probably too lax in my book.
****************************************************************
@@ -2603,6 +2761,689 @@
": constant <type> :=" when "=" will do.
****************************************************************
+
+From: Robert Dewar
+Date: Saturday, May 1, 2010 2:09 PM
+
+> You could perhaps use "with...do" instead of "let ... in"
+>
+> (with A = <expression>, B = <expression>, ... do ...)
+
+I like this one, reads very nicely to me
+
+> If these are all constants, I don't see the need for
+> ": constant <type> :=" when "=" will do.
+
+I never mind Ada getting closer to Algol-68 :-)
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Saturday, May 1, 2010 2:48 PM
+
+If this is introduced into the language, the need for renamed expressions (or
+function statements :-)!) disappears. You can just use such a form directly in
+pre- and post-conditions. They are part of the family of new expression forms:
+conditional, quantified, case, and now these. I guess their name is NOT
+let-expressions!
+
+****************************************************************
+
+From: Tucker Taft
+Date: Saturday, May 1, 2010 3:07 PM
+
+The need for parameterized expressions remains because of private types. The
+precondition has to be in the visible part, while the expression would need to
+be in the private part if it refers to properties of the full type.
+
+In fact the whole point here is private types, where you have relatively simple
+preconditions on some primitive operation, say, such as "Is_Open(File)" for a
+file Read. The File_Type is an IN parameter, and if Is_Open checks something in
+the File_Type to determine whether the file is open, multiple sequential calls
+on an operation with an Is_Open precondition can proceed with at most the first
+one requiring an actual test. E.g.:
+
+ procedure Open(File : in out File_Type; ...)
+ with Post => Is_Open(File);
+
+ procedure Read(File : in File_Type; ...)
+ with Pre => Is_Open(File);
+
+ procedure Close(File : in out File_Type)
+ with Post => not Is_Open(File);
+
+ private
+
+ type File_Record;
+ type File_Type is access File_Record;
+
+ function Is_Open(File : in File_Type) return Boolean
+ is (File /= null);
+
+ ...
+
+With the above, all run-time checks associated with the precondition on Read can
+likely be omitted, presuming the call on Open is visible.
+
+This illustrates a situation where it would be nice to associate a postcondition
+with default initialization somehow. E.g.:
+
+ type File_Type is limited private
+ with Post => not Is_Open(File_Type);
+
+where the "Post" here refers to the postcondition on default initialization. Or
+alternatively:
+
+ type File_Type is limited private
+ with Default => not Is_Open(File_Type);
+
+Examples are often illuminating...
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 8:48 PM
+
+> With the above, all run-time checks associated with the precondition
+> on Read can likely be omitted, presuming the call on Open is visible.
+
+This example illustrates my puzzlement as to why one would want the
+implementation of Is_Open to be "exposed".
+
+The reasoning of a tool is: Open implies Is_Open, so Read is OK thereafter.
+That doesn't depend on the null-ness of File. And anyway, for that, we need to
+see the body of Open (which presumably sets File to non-null).
+
+I just don't see how putting Is_Open in the private part (but not putting the
+implementation of Open and Read in the private part) buys anthing useful.
+
+> This illustrates a situation where it would be nice to associate a
+> postcondition with default initialization somehow. E.g.:
+>
+> type File_Type is limited private
+> with Post => not Is_Open(File_Type);
+>
+> where the "Post" here refers to the postcondition on default
+> initialization. Or alternatively:
+>
+> type File_Type is limited private
+> with Default => not Is_Open(File_Type);
+
+Yes, I think you're right that we need some way to assert things about default
+values.
+
+****************************************************************
+
+From: Tucker Taft
+Date: Saturday, May 1, 2010 10:06 PM
+
+...
+> The reasoning of a tool is: Open implies Is_Open, so Read is OK
+> thereafter. That doesn't depend on the null-ness of File. And
+> anyway, for that, we need to see the body of Open (which presumably
+> sets File to non-null).
+
+This isn't necessarily true because Is_Open could depend on a global, or
+something that is at a level of indirection and hence writable by some operation
+that takes the File_Type as an "in" parameter.
+
+> I just don't see how putting Is_Open in the private part (but not
+> putting the implementation of Open and Read in the private part) buys
+> anthing useful. ...
+
+Because you then learn that Is_Open depends only on data that is directly in the
+"File_Type" object, so can't be affected by calls that pass the File_Type object
+as an "in" parameter. Without that knowledge, you really have no idea what are
+the properties of Is_Open.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Saturday, May 1, 2010 3:16 PM
+
+> If this is introduced into the language, the need for renamed
+> expressions (or function statements :-)!) disappears. You can just use
+> such a form directly in pre- and post-conditions. They are part of
+> the family of new expression forms: conditional, quantified, case, and
+> now these.
+
+Well yes, you can use it but the functional abstraction is still useful,
+consider something like
+
+ function Glob (A, B : Float) return Float;
+
+ ...
+
+ function Glob (A, B : Float) return Float
+ renames (with X = A**2 + B**2 do X*X + X);
+
+and now in a precondition we have
+
+ precondition (Glob (Arg1) >= Glob (Arg2));
+
+Sure you could right the precondition expression as a giant single expression,
+but you would end up duplicating code and so it is nice to have the functional
+abstraction).
+
+> I guess their name is NOT let-expressions!
+
+I would call them WITH expressions
+
+Do we want to allow a list
+
+ (with X = A*A, Y = B*B do X*Y + X + Y)
+
+or require nesting
+
+ (with X = A*A do (with Y = B*B do X*Y + X + Y))
+
+if we leave out the type, what's the resolution rule for the constant, I guess
+it's type must be self-evident without needing any context? Like the expression
+in a conversion.
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Saturday, May 1, 2010 3:34 PM
+
+No type inference please, resolution should proceed as for a block, and the
+bound variables need explicit types. We need a separator, and it would be
+confusing for it to be a semicolon, so a comma would be OK.
+
+***************************************************************
+
+From: Tucker Taft
+Date: Saturday, May 1, 2010 3:49 PM
+
+Type inference is used already
+for named numbers, for array and loop
+indices, for case expressions,
+and for operands of a
+type conversion. Why not here?
+
+This seems the clear place where
+you want to avoid unnecessary syntactic
+overhead. You can always use a
+qualified expression if there is
+ambiguity.
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Saturday, May 1, 2010 4:04 PM
+
+well, in all the above cases except conversions there is at least a class of
+types to which the expression must belong. But you are right that saying that
+the value is a complete context (as for a conversion) does not add any
+complication to the analysis.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Saturday, May 1, 2010 4:12 PM
+
+I am in favor of making this a complete context and not requiring a type. but
+isn't there one problem, what about
+
+ (with Days = 365 do Days*Days + Days)
+
+that would be ambiguous, is that annoying?
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Saturday, May 1, 2010 6:39 PM
+
+By analogy, this would be of type Universal_Integer, some preference rule in
+action.
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 6:48 PM
+
+Presumably:
+
+ (with Days = Day_Count'(365) do Days*Days + Days)
+
+would be legal.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Saturday, May 1, 2010 6:48 PM
+
+> By analogy, this would be of type Universal_Integer, some preference
+> rule in action.
+
+Interesting, so I suppose
+
+ type X = mod 2 ** 64;
+
+ y : x := x (2 ** 64 - 1);
+
+must cause an overflow?
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 7:55 PM
+
+No, I don't see why it would cause an overflow.
+And I don't see what it has to do with Ed's comment.
+Please explain what you're getting at.
+
+(It must cause a syntax error, but I assume "=" is supposed to be "is".)
+
+****************************************************************
+
+From: Robert Dewar
+Date: Sunday, May 2, 2010 6:21 AM
+
+>> Interesting, so I suppose
+>>
+>> type X = mod 2 ** 64;
+>>
+>> y : x := x (2 ** 64 - 1);
+>>
+>> must cause an overflow?
+>
+> No, I don't see why it would cause an overflow.
+
+Well isn't 2 ** 64 -1 interpreted as universal integer?
+If so, that value is out of range of this type, which is a signed type with
+bounds -2**63 .. +2**63-1.
+
+But in fact it does not cause overflow at run time, so I am confused on the
+treatment of universal integers and conversions like this one.
+
+> And I don't see what it has to do with Ed's comment.
+> Please explain what you're getting at.
+>
+> (It must cause a syntax error, but I assume "=" is supposed to be
+> "is".)
+
+
+yes, oops
+
+****************************************************************
+
+From: Bob Duff
+Date: Sunday, May 2, 2010 8:47 AM
+
+> Well isn't 2 ** 64 -1 interpreted as universal integer?
+
+The literals are of type universal_integer, and are implicitly converted to
+root_integer. The operators return root_integer. So 2**64-1 is of type
+root_integer. This is then converted explicitly to X.
+
+> If so, that value is out of range of this type, which is a signed type
+> with bounds -2**63 .. +2**63-1.
+
+Static expressions are always evaluated without overflow.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Sunday, May 2, 2010 9:08 AM
+
+> Static expressions are always evaluated without overflow.
+
+Ah yes, of course, what is peculiar about the case we are talking about
+
+ (with X = 23 + 45 do X*X)
+
+is that there is no immediate type for X to be converted to, so I guess we just
+assume this is a named number?
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Sunday, May 2, 2010 9:31 AM
+
+Yes, the expression is equivalent to an attribute that returns
+Universal_Integer, so the context of the call determines some eventual type for
+it, and within the body of this " expression function" X is a named number.
+
+****************************************************************
+
+From: Bob Duff
+Date: Sunday, May 2, 2010 9:33 AM
+
+> is that there is no immediate type for X to be converted to, so I
+> guess we just assume this is a named number?
+
+Yeah, that probably works. If not, I wouldn't mind outlawing such cases -- I
+mean, if they cause some semantic or implementation difficulties.
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 8:02 PM
+
+> Do we want to allow a list
+>
+> (with X = A*A, Y = B*B do X*Y + X + Y)
+
+Yes.
+
+> or require nesting
+>
+> (with X = A*A do (with Y = B*B do X*Y + X + Y))
+
+No. The whole point is a "shorthand", so requiring longer shorthands is not a
+good idea.
+
+> if we leave out the type, what's the resolution rule for the constant,
+> I guess it's type must be self-evident without needing any context?
+> Like the expression in a conversion.
+
+Yes.
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 8:14 PM
+
+> one of the following
+>
+> (A * A + (A - 1) with A : constant Integer := 23)
+
+Among the various syntax suggestions, I'd like to squeltch this one -- the decl
+of A really needs to come first!
+
+But I very much like the idea of a lightweight syntax for declaring objects
+within expressions.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Sunday, May 2, 2010 6:23 AM
+
+> Among the various syntax suggestions, I'd like to squeltch this one --
+> the decl of A really needs to come first!
+
+Well most functional languages have both forms. From a conceptual point of view,
+it is reasonable to refine the meaning with a post-definition, but I agree that
+this is very un-Ada which has this annoying rule that things have to be defined
+before they are used. In that respect I much prefer Algol-68 or PL/1 or COBOL
+for that matter.
+
+In particular it is really annoying having to declare refinement procedures
+before they are used.
+
+But I wander off-topic :-)
+
+Indeed for Ada it would be wrong to use the "where" form, and we should require
+A to be declared before its use, even if that is a bit hostile to abstraction in
+some cases.
+
+****************************************************************
+
+From: Bob Duff
+Date: Saturday, May 1, 2010 8:40 PM
+
+> Well, here we differ.
+
+Apparently. But not much, I think. For 3.5 years, I watched you design Ada 9X,
+and I noticed many times, where Distinguished Reviewers complained "but that
+could be abused" and you took my side (i.e., "yeah it could be, but so what?
+It's a useful feature, so it should be in the language, and by the way don't
+abuse it".
+
+In a few cases (such as this one), you've inexplicably taken the opposite view.
+
+>...I believe that part of
+> good language design is "encouraging" the programmer to make wise
+>choices, by making some things easier than others.
+
+OK, but the case in question is not "making some things easier or harder", but
+simply forbidding some things.
+
+>...Just giving programmers free
+> and uniform license to do whatever they want is a design philosophy,
+>but it isn't mine. Of course there is a spectrum here, but I think
+>you (Bob) and I are on somewhat different places on this spectrum.
+
+I don't see any spectrum. I think that in every case, "can be abused" is
+irrelevant. But as I said earlier, "can be accidentally misused" is an
+important point.
+
+I am taking "can be abused" to mean "...by malicious or incompetent
+programmers". Deliberately.
+
+> So for me, if a feature has more "potential for abuse"
+> than some other feature, I will favor the one with less such
+> potential, and not surprisingly that will sometimes "crimp" someone's
+> style. If it doesn't do that now and then, it is probably too lax in
+> my book.
+
+****************************************************************
+
+From: Robert Dewar
+Date: Sunday, May 2, 2010 6:30 AM
+
+> In a few cases (such as this one), you've inexplicably taken the
+> opposite view.
+
+to me it is not at all inexplicable, as Tuck said, it is a balance. A proposed
+new feature has to be evaluated for
+
+a) the positive value it adds to the language
+
+b) the negative value it subtracts from the language.
+
+Every new feature has an entry in b) for enlarging the language and increasing
+complexity, so for starters the value must exceed that factor (it is that
+comparison that lead many features to be omitted from Ada 9X). Failure to do
+this balancing leads to the kitchen sink effect as in PL/1. That's the "well you
+don't have to use it if you don't like it argument".
+
+But also in the b) column can come potential for abuse, and this has to be
+measured against the value added. That's the "but this feature could be
+seriously abused" argument
+
+So to me the inexplicable position is to refuse to do this balancing, and take
+an absolute point of view that you will never count potential for abuse as a
+negative.
+
+> I don't see any spectrum. I think that in every case, "can be abused"
+> is irrelevant. But as I said earlier, "can be accidentally misused"
+> is an important point.
+
+Right, and I find this absolute position inexplicable :-)
+
+For example, suppose we propose the following
+
+It is really annoying that when you write A := B, the type of B has to match. We
+propose an extension to the language that says that if the types do not match
+according to the current rule, then if the type of A is unambiguous, there is an
+implicit unchecked conversion of the right side to B, and the statement is
+considered legal.
+
+Well that's useful in some cases perhaps, if we can find even one case where it
+is useful, then Bob with his absolute position would ignore the immense
+potential for abuse.
+
+> I am taking "can be abused" to mean "...by malicious or incompetent
+> programmers". Deliberately.
+
+Well all programmers are incompetent to some degree. Almost no one knows all of
+Ada reliably.
+
+****************************************************************
+
+From: Bob Duff
+Date: Sunday, May 2, 2010 9:05 AM
+
+> > I don't see any spectrum. I think that in every case, "can be
+> > abused" is irrelevant. But as I said earlier, "can be accidentally
+> > misused" is an important point.
+>
+> Right, and I find this absolute position inexplicable :-)
+
+I did explain:
+
+ - It doesn't work (doesn't prevent misuse).
+
+ - It prevents useful things. (It must, because if whatever
+ feature is useless, then that's enough to keep it out
+ of the language -- no need to worry about abuse.)
+
+If you can give me just one example, I'll change my opinion from "every case" to
+"most cases".
+
+> For example, suppose we propose the following
+>
+> It is really annoying that when you write A := B, the type of B has to
+> match. We propose an extension to the language that says that if the
+> types do not match according to the current rule, then if the type of
+> A is unambiguous, there is an implicit unchecked conversion of the
+> right side to B, and the statement is considered legal.
+>
+> Well that's useful in some cases perhaps, if we can find even one case
+> where it is useful, then Bob with his absolute position would ignore
+> the immense potential for abuse.
+
+But I can easily argue against this malfeature without using the concept of
+deliberate abuse:
+
+ - This mailfeature will clearly cause accidental
+ mistakes (assigning things to the wrong type).
+ You and I (who are surely competent) would trip
+ over this every day!
+
+ - Readability: We would lose the useful property that
+ the powerful (and therefore dangerous) tool called
+ Unchecked_Conversion is explicit in the code,
+ and looks different from other features.
+
+> > I am taking "can be abused" to mean "...by malicious or incompetent
+> > programmers". Deliberately.
+>
+> Well all programmers are incompetent to some degree. Almost no one
+> knows all of Ada reliably.
+
+I don't think you need to understand every corner of Ada to be "competent". In
+the case of bodies-in-specs, "incompetent" means "don't understand the point of
+separating visible parts from implementations". That sort of person will make
+poorly-designed packages no matter what we language designers do.
+
+I am genuinely interested in hearing an example where a restriction is a good
+idea, and that's based ONLY on "potential for deliberate abuse". The above one
+doesn't work.
+
+Yesterday, you gave the example of untyped pointers, which I didn't respond to.
+My response is, we have that feature, it's called System.Address (along with
+Address_To_Access_Conversions). It has a huge potential for abuse, and we've
+both seen it abused, but we NEED some sort of feature along the lines of
+System.Address. It would make no sense to eliminate it, unless we can come up
+with a safer feature that still gets those low-level jobs done.
+
+Care to try another example?
+
+****************************************************************
+
+From: Bob Duff
+Date: Monday, May 3, 2010 12:05 PM
+
+I'm not sure if I already made this clear, but for the record:
+
+I had been opposed to "parameterized expressions"
+(whatever they're called) being standardized.
+
+But if we add "let" expressions (perhaps called "with" expressions?), then I
+turn 180 degrees, and I am in favor of having both parameterized expressions and
+"let" expressions. "Let" expressions seem quite simple and quite useful in
+their own right, and alleviate most of my concerns about parameterized
+expressions (which are also quite simple -- I never said otherwise).
+
+****************************************************************
+
+From: Robert Dewar
+Date: Monday, May 3, 2010 12:20 PM
+
+I fully agree with this position, can we agree on this tentative syntax as the
+best choice *if* we put them in
+
+ WITH_EXPRESSION ::= (with DECL {, DECL} in EXPRESSION)
+
+ DECL ::= IDENTIFIER = EXPRESSION
+
+with parens being omittable as for conditional expressions?
+
+I think calling these WITH-expressions is a reasonable choice.
+
+Of course the usual semantic perusal by the usual gang of suspects will be
+required :-)
+
+****************************************************************
+
+From: Tucker Taft
+Date: Monday, May 3, 2010 12:27 PM
+
+I don't think "in" works syntactically, but perhaps "do".
+
+****************************************************************
+
+From: Edmond Schonberg
+Date: Monday, May 3, 2010 12:28 PM
+
+Definitely in favor of these. Can we also say that they can appear in the
+private part and work as renames_as_body for contracts?
+
+****************************************************************
+
+From: Tucker Taft
+Date: Monday, May 3, 2010 12:36 PM
+
+I agree that a parameterized expression should be allowed in a private part as a
+completion of a function spec in the visible part. Otherwise, they don't have
+much value.
+
+****************************************************************
+
+From: Bob Duff
+Date: Monday, May 3, 2010 12:53 PM
+
+> Definitely in favor of these. Can we also say that they can appear in
+> the private part and work as renames_as_body for contracts?
+
+Not sure what "they" refers to.
+
+Parameterized expressions should be allowed anywhere a declaration is allowed --
+including in private parts. They are like renamings, in that they can serve as
+the spec or the body. (One proposed syntax used "renames", but Tuck proposed a
+different syntax.) This feature has been variously called "parameterized
+expressions", "renamings of expressions" and "expression functions".
+
+with_expressions should be allowed whereever an expression is allowed, which
+includes "in a parameterized expression that is in a private part".
+
+****************************************************************
+
+From: Gary Dismukes
+Date: Monday, May 3, 2010 12:55 PM
+
+> Definitely in favor of these. Can we also say that they can appear in
+> the private part and work as renames_as_body for contracts?
+
+Presumably "with_expressions" are just another flavor of expression and can
+occur wherever expressions can occur, so in particular can be used in expression
+functions. As for expression functions, it seems reasonable that those can be
+used as renaming-as-bodies.
+
+> > I fully agree with this position, can we agree on this tentative
+> > syntax as the best choice *if* we put them in
+> >
+> > WITH_EXPRESSION ::= (with DECL {, DECL} in EXPRESSION)
+> >
+> > DECL ::= IDENTIFIER = EXPRESSION
+
+Do we really want to use "=" for these rather than ":="?
+The assignment operator seems much more sensible to me.
+
+****************************************************************
-[Editor's note: There are another 120 messages in this thread; ran out of
+[Editor's note: There are another 80 messages in this thread; ran out of
time to get them filed. They'll appear soon...]
Questions? Ask the ACAA Technical Agent