CVS difference for ai12s/ai12-0190-1.txt

Differences between 1.10 and version 1.11
Log of other versions for file ai12s/ai12-0190-1.txt

--- ai12s/ai12-0190-1.txt	2019/01/09 04:12:05	1.10
+++ ai12s/ai12-0190-1.txt	2019/01/09 06:41:00	1.11
@@ -1,4 +1,4 @@
-!standard 4.4(7/3)                                  18-12-13  AI12-0190-1/06
+!standard 4.4(7/3)                                  18-12-18  AI12-0190-1/07
 !standard 4.5.9(0)
 !class Amendment 16-06-02
 !status Amendment 1-2012 18-12-10
@@ -12,38 +12,36 @@
 !summary
 
 Provide an ability to construct a local anonymous function at the point
-of a call on a subprogram that has an access-to-function parameter,
-or in an instantiation with a formal subprogram parameter, or other
-contexts where the expected type is an access-to-function type,
-or there is an expected profile for a function.
+of a call on a subprogram that has an anonymous access-to-function parameter,
+or in an instantiation with a formal subprogram parameter.
 
 !problem
 
-We added anonymous access-to-subprogram parameters to allow
+We added anonymous access-to-subprogram parameters in Ada 2005 to allow
 locally-declared subprograms to be passed to other programs which might
 iterate over some data structure, applying the passed subprogram
 multiple times, perhaps as part of a search, or an update, or a
-transformation of some sort.  Being able to pass local subprograms to
+transformation of some sort. Being able to pass local subprograms to
 other subprograms is a fundamental part of "functional" programming, but
 also appears in other programming paradigms, including old fashioned
 numeric integration packages, etc.
 
 To enhance the utility of this feature, it is convenient if the
 subprogram being passed can be constructed at the point of call, rather
-than requiring a separate declaration.  AI12-0189 addresses the case
+than requiring a separate declaration. AI12-0189 addresses the case
 where a procedure (as opposed to a function) is to be passed as the
-actual parameter.  We would like to provide something similar for
+actual parameter. We would like to provide something similar for
 passing a locally-constructed function as a parameter.
 
 !proposal
 
-An anonymous_function can be used in a context where the expected type is a
-single access-to-function type (or as the actual parameter for a formal
-function). It is roughly equivalent to using the name'Access (or simply
-name) of an expression function which is declared at the point of use,
-with parameter types, modes, etc. taken from that of the expected
-access-to-function type (or the formal function). Only the formal
-parameter names come from the anonymous_function.
+An anonymous_function can be used in a context where the expected type
+is a single anonymous access-to-function type, or as the actual
+parameter for a formal function. It is roughly equivalent to using the
+name'Access (or simply name) of an expression function which is declared
+at the point of use, with parameter types, modes, etc. taken from that
+of the expected access-to-function type (or the formal function). Only
+the formal parameter names come from the anonymous_function.
 
     primary ::= anonymous_function
 
@@ -54,9 +52,9 @@
       ( identifier { , identifier } ) | formal_part
 
 We allow only a single expression as the body of the
-anonymous_function.  Given that we now have "if" expressions and "case"
-expressions, this is not a serious limitation.  (The possible addition
-of "declare expressions" would be a welcome enhancement.)
+anonymous_function. Given that we now have "if" expressions and "case"
+expressions, this is not a serious limitation. The proposed addition
+of "declare expressions" provides even more flexibility if needed.
 
 !wording
 
@@ -70,12 +68,12 @@
 
 Add section after 4.5.8:
 
-  4.5.9 Function Expressions
+  4.5.9 Anonymous Functions
 
-  Function expressions provide a way to define a function at a point
-  where an access-to-function type is the expected type, or in a generic
-  instantiation as an actual parameter corresponding to a formal subprogram
-  parameter.
+  Anonymous functions provide a way to define a function at a point
+  where an access-to-function type is the expected type, or where
+  there is an expected function profile determined by a generic formal
+  subprogram parameter.
 
               Syntax
 
@@ -90,13 +88,13 @@
   In a context where there is an expected type rather than an expected
   profile for an anonymous_function, the expected type shall be a single
   anonymous access-to-function type, and the profile of this type is considered
-  the expected profile for the anonymous_function.  The result type of
+  the expected profile for the anonymous_function. The result type of
   the expected profile of the anonymous_function is the expected type
   for the expression of the anonymous_function. If there is no
   function_formal_parameter_list, the expected profile shall have no
-  parameters.  If the function_formal_parameter_list is a formal_part,
+  parameters. If the function_formal_parameter_list is a formal_part,
   then it shall be subtype conformant to the expected profile if there
-  is an expected type, or merely mode conformant otherwise.  If the
+  is an expected type, or merely mode conformant otherwise. If the
   function_formal_parameter_list is a sequence of identifiers, the
   number of identifiers in the sequence shall be the same as the number
   of formal parameters in the expected profile.
@@ -105,7 +103,11 @@
 
   When used in a context where there is an expected type, the
   anonymous_function shall be an actual parameter in a call, or a
-  parameter default for a callable entity.
+  parameter default for a callable entity. When used in a context
+  where there is only an expected profile, the anonymous_function
+  shall be a generic actual parameter in a generic_instantiation for a
+  formal subprogram parameter, or as the subprogram_default for such a formal
+  subprogram parameter.
 
            Static Semantics
 
@@ -116,27 +118,28 @@
   attribute_reference of this locally defined function; otherwise, the
   anonymous_function is equivalent to such a local declaration with the
   anonymous_function replaced by a name denoting this locally defined
-  function.  The profile of this locally defined function has a result
+  function. The profile of this locally defined function has a result
   type determined by the expected profile, and a formal part determined
   by the formal_part, if provided in the anonymous_function, or by the
   formal part of the expected profile otherwise, but with the name of
   each formal parameter of the expected profile replaced by the
-  corresponding identifier in the sequence of identifiers.  The expression
+  corresponding identifier in the sequence of identifiers. The expression
   of this locally defined expression function is that of the
   anonymous_function.
 
   AARM To Be Honest: Depending on the nature of the innermost enclosing
-  declarative region, this equivalence might violate the normal syntax rules
-  which would not permit such an expression_function_declaration in such a
-  region.
+  declarative region, this equivalence might violate the normal syntax
+  rules which would not permit such an expression_function_declaration
+  in such a region.
 
-
 !discussion
 
 We are using the reserved words FUNCTION and RETURN rather than defining
-a new reserved word such as LAMBDA.  We put them surrounding the (optional)
+a new reserved word such as LAMBDA. We put them surrounding the (optional)
 parameter list, as that is their normal place in the syntax for declaring a
-named function.
+named function. We use RETURN rather than IS because we believe the
+RETURN helps indicate that the expression takes the place of the result
+type, taking advantage of the result type being provided from context.
 
 We considered other names such as "lambda expressions," "function
 literals," and "function expressions."  We ultimately went with
@@ -146,35 +149,37 @@
 We allow, but do not require, a full formal part as part of the
 anonymous_function. Requiring a full formal part seems unnecessary and
 verbose, since the parameter (and result) types are always provided by the
-profile of the formal access-to-function parameter.
+expected profile determined by the formal parameter.
 
 We are only supporting defining anonymous functions using this proposed
-"anonymous_function" construct.  Anonymous procedures are nicely
-handled with the loop-body proposal (AI12-0189).  In any case, mixing
-statements inside expressions seems like a bad idea.  Also, we don't
-have "expression procedures" so it doesn't seem so bad that we don't
-have "procedure expressions" ;-).
+"anonymous_function" construct. Anonymous procedures are nicely
+handled with the loop-body proposal (AI12-0189). In any case, mixing
+statements inside expressions seems like a bad idea.
 
-One place where it might be nice to allow a "anonymous procedure" would
+One place where it might be nice to allow "anonymous procedures" would
 be when you want to pass in a do-nothing procedure, which is not
-uncommon when instantiating a generic with a formal procedure.  We allow
+uncommon when instantiating a generic with a formal procedure. We allow
 using "null" as the default for a formal procedure, as well as when
-defining a null procedure.  It would seem pretty reasonable to allow
+defining a null procedure. It would seem pretty reasonable to allow
 "null" as the actual parameter for a formal procedure, meaning a
-"do-nothing" procedure.
+"do-nothing" procedure. We leave that to some other AI, if there is
+interest in that possibility.
 
-We limit this to cases of anonymous access-to-subprogram types used
-as function parameters.  Other cases, like access discriminants and
-stand-alone access objects seemed like more trouble that they are worth,
-since those generally occur in contexts where declaring a local subprogram
-is not a burden.
+We limit this to cases of anonymous access-to-function types used for
+formal parameters to callable entities. Other cases, like access discriminants
+and stand-alone access objects seem like more trouble that they are
+worth given the potential accessibility level issues, and furthermore
+those constructs generally occur in contexts where declaring a local
+subprogram is not a burden.
+
+Similarly we limit uses with only an expected profile to generic actuals
+and defaults. Function renames and function-valued aspects also provide
+an expected profile, but could represent an implementation burden without
+clear value. A later revision could choose to relax some of these
+limitations.
 
 !example
 
-    --  Replace control chars with '?'
-    Ada.Strings.Fixed.Translate
-      (Str, (function (C) return (if C < ' ' then '?' else C)));
-
     --  Procedure for plotting a function
     procedure Plot_Graph
       (Fun : access function (X : Float) return Float;
@@ -186,6 +191,20 @@
     Plot_Graph (Fun => (function (Z) return Z**2),
                 Start => 1.0, Stop => 20.0);
 
+
+    -- Function for accumulating some statistic over some subset
+    -- of the records of a database
+    function Database_Query (DB : Database_Handle;
+       Select  : access function (Rec : DB_Rec_Type) return Boolean;
+       Combine : access function
+                   (Accum : Float; Rec : DB_Rec_Type) return Float);
+      ...
+    --  Compute the sum of squares of the records with a large Value field.
+    Large_Val_Sum_Of_Squares := Database_Query
+       (My_Database,
+        Select => (function (Rec) return (Rec.Value >= N),
+        Combine => (function (Accum, Rec) return Accum + Rec.Value ** 2));
+
 !comment The following were for the version approved and then recended in
 !comment December 2018, except to replace "function_expression" with
 !comment "anonymous_function" globally.
@@ -208,7 +227,7 @@
 
 @dinsc
 
-Function expressions provide a way to define a function at a point
+Anonymous functions provide a way to define a function at a point
 where an access-to-function type is the expected type, or in a generic
 instantiation as an actual parameter corresponding to a formal subprogram
 parameter.
@@ -232,7 +251,7 @@
 @fa<function_formal_parameter_list>, the expected profile shall have no
 parameters. If the @fa<function_formal_parameter_list> is a @fa<formal_part>,
 then it shall be subtype conformant to the expected profile if there
-is an expected type, or merely mode conformant otherwise.  If the
+is an expected type, or merely mode conformant otherwise. If the
 @fa<function_formal_parameter_list> is a sequence of identifiers, the
 number of identifiers in the sequence shall be the same as the number
 of formal parameters in the expected profile.
@@ -2953,51 +2972,1243 @@
 
 ****************************************************************
 
+From: Bob Duff
+Sent: Thursday, December 13, 2018  5:59 PM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+> Here is an update incorporating some of these discussions.
+
+Thank you!  Looks good, except:
 
+> Add section after 4.5.8:
+>
+>   4.5.9 Function Expressions
+>
+>   Function expressions provide a way to define a function at a point
+
+Oops.  Our esteemed editor can no-doubt correct that.
+
 ****************************************************************
 
+From: Randy Brukardt
+Sent: Thursday, December 13, 2018   6:23 PM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+> > ...
+> > > It does sound like some more discussion of this (approved) AI is
+> > > needed.
+> >
+> > This seems like a "reopen" rather than a "fix-up" situation, because
+> > (A) there is a lot of issues that were not resolved - including the
+> > name of the thing, (B) resolving those issues might cause people to
+> > change their vote on the feature as a whole (that is, it originally
+> > looked very simple, but it is not looking so simple now), and (C) it
+> > might take more time than we have to resolve these issues.
+> > (Admittedly, (C) probably won't be the case, but fixing this AI
+> > could take time from more important things below it on the agenda
+> > [for example, Bignums].)
+...
+> Re: (B) above: I never thought this feature was simple in terms of
+> implementation.  It's pretty simple conceptually, though.
+
+I agree in that I never thought it was simple, either. But it now is looking
+like a nightmare, especially in corner cases (where the function accesses outer
+expression objects - quantified/declare). I certainly didn't think about the
+implementation in any detail until I was in the shower the other day. I was
+thinking about your argument about the complications of implementing
+declare_expressions for all of the corner cases supported for
+conditional_expressions. And that led me to thinking about the possible
+implementation issues of these guys.
+
+We never talked about implementation costs (at least at this meeting), like we
+did when deferring generic type defaults. (And the concern there seems less
+valid, since everything that can happen there can already happen in a generic
+instantiation; there's nothing new like declaring a function in the middle of a
+parameter list.)
+
+We also never talked about the impact on readability. Our justification for @
+was in part improved readability by elimination of duplication. But nothing
+about this proposal really improves readability, since the nesting is very hard
+to read. At best the readability is a wash, and if someone writes one of these
+with a multiline result expression, the readability is much worse. Additionally,
+since the types of the parameters are typically omitted, you usually still will
+have to look at a separate declaration somewhere else to figure out what is
+going on. That also harms readability.
+
+We never really got an answer on what this is good for, either. The only thing I
+heard was Tucker saying that every other language has added this. That seems
+like a "lemming" excuse, but it doesn't actually answer what it is good for.
+Given that every such function can be by definition written as an expression
+function, this seems mainly to allow saving one line and a few names (of the
+function and of the types of the parameters). That seems almost exclusively
+aimed at making it easier to write code -- and that has never, ever been a goal
+of Ada.
+
+The use case that caused me to abstain is the quickie "<" or "=" operator in a
+generic instance. But I had forgotten that Ada 2012 allows expression functions
+everywhere, so nowadays you can always declare an expression function on the
+line in front of an instance. That's good enough for me, and the readability is
+not going to be impacted by that. In Ada 95, of course, you had to put the body
+of this new function somewhere else. And if there is new functionality here, it
+is essentially based on using the closure, an idea that I rather hope never
+makes it into Ada.
+
+As most of you remember, I strongly advocate the elimination of access type from
+client interfaces. While that alone isn't a reason to reject something, it does
+mean that I have no interest in making it easier to use something that I'd
+prefer you don't use in the first place.
+
+Ergo, once I think about this idea in detail, it's clear to me that the value of
+the proposal is far less than the cost. Indeed, there almost is no value at all,
+which means there is no amount of cost reduction which could make it worth it.
+
+And honestly, I never really prepared an argument about the value of it since I
+thought that no one really was supporting it anyway without some sort of closure
+ability. So I wasn't prepared the other day. That's on me, sorry. (And now that
+some closures are leaking into it, via quantified/declare identifiers, we're
+already on the slippery slope to garbage collection hell.)
+
+P.S. Richard, I can reargue this point now that I got the AI reopened for
+technical issues. I was fully prepared to eat this complaint for all time, but
+at least for the time being I don't have to.
 
 ****************************************************************
 
+From: Erhard Ploedereder
+Sent: Thursday, December 13, 2018  9:06 PM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+> Anybody object to "anonymous function"?
+
+In favor of it.
 
+(and against calling them lambdas, since lambda usually can do a lot more, e.g.,
+currying and calling curried versions, returning composed lambdas and naming
+them, etc.)
+
 ****************************************************************
 
+From: Tucker Taft
+Sent: Thursday, December 13, 2018  9:22 PM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+...
+> We never really got an answer on what this is good for, either. The only
+> thing I heard was Tucker saying that every other language has added this.
+
+Lambda expressions have been around since the earliest LISP days.  The value of
+lambda expressions is that they ease the use of "higher-order" programming,
+where you use various operators that apply functions to the elements of
+composite data structures and then produce new sorts of results.  This is not
+new.  What is new is that more and more programmers have become comfortable with
+this sort of higher-order programming, and have found it is useful even in
+languages that are not strictly "functional" programming languages.
+
+We are working to attract a new generation of programmers to Ada.  These
+programmers are growing up with higher-order programming as an important part of
+how they solve complex problems.  But the need to create a local declare block
+with a local function declaration and then pass in Blah'Access as part of this
+sort of higher-order programming makes the whole process much heavier weight.
+There is also a lot of redundancy in that process requiring producing a complete
+formal part with parameter and result types that are copied directly from the
+declaration of the access-to-function parameter of the higher-order function.
+And finally there is the separation between the declaration of this local
+"helper function" and the use of the helper function in the higher-order
+operation.  So that now the "higher-order" operation becomes so heavyweight and
+spread out that it becomes harder to understand what the programmer was trying
+to do in the first place.
+
+You are certainly right that the same thing can be accomplished by creating a
+local declare block with a locally declared function (whose name is generally
+just noise), and passing 'Access of it.  But the same thing could be said about
+the container iterators, or protected objects instead of explicit lock/unlock,
+or generalized references, etc.  The fact is that appropriate "syntactic sugar"
+can change the game significantly, and make certain paradigms easy and natural
+enough that more complex problems can be tackled.
 
+...
+> As most of you remember, I strongly advocate the elimination of access type
+> from client interfaces. While that alone isn't a reason to reject something,
+> it does mean that I have no interest in making it easier to use something
+> that I'd prefer you don't use in the first place.
+
+Anonymous access-to-subprogram types should really not be considered access
+types at all.  They are really just a way to pass subprograms as parameters.
+They have none of the issues that access-to-object types have, and really
+shouldn't be grouped into the same bucket at all.
+
 ****************************************************************
 
+From: Randy Brukardt
+Sent: Thursday, December 13, 2018  11:36 PM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+>>...
+>>We never really got an answer on what this is good for, either. The
+>>only thing I heard was Tucker saying that every other language has added this.
+
+>Lambda expressions have been around since the earliest LISP days.  The
+>value of lambda expressions is that they ease the use of "higher-order"
+>programming, where you use various operators that apply functions to
+>the elements of composite data structures and then produce new sorts of
+results.
+
+That is, spaghetti code. :-)
+
+>This is not new.  What is new is that more and more programmers have become
+>comfortable with this sort of higher-order programming, and have found it is
+>useful even in languages that are not strictly "functional" programming
+>languages.
+
+I don't think this is new either.
+
+>We are working to attract a new generation of programmers to Ada.
+>These programmers are growing up with higher-order programming as an
+>important part of how they solve complex problems.
+
+Fine.
+
+>But the need to create a local declare block with a local function
+>declaration and then pass in Blah'Access as part of this sort of
+>higher-order programming makes the whole process much heavier weight.
+
+No, it makes it *readable*. You know, the number 1 priority of Ada programming
+language design...
+
+>There is also a lot of redundancy in that process requiring producing a
+>complete formal part with parameter and result types that are copied
+>directly from the declaration of the access-to-function parameter of
+>the higher-order function.
+
+Which again helps readability of the function, otherwise one has to look
+elsewhere to understand what it means. There are very few places in Ada where
+types are inferred, and adding new ones take a very high bar. (I'm somewhat
+uncomfortable even doing for renames, I'd be much happier requiring the names to
+be meaningful, but I know that's impossible because of compatibility.)
+
+>And finally there is the separation between the declaration of this
+>local "helper function" and the use of the helper function in the
+>higher-order operation.
+
+For a generic instantiation, they will be (or at least can be) directly next to
+each other.
+
+>So that now the "higher-order" operation becomes so heavyweight and
+>spread out that it becomes harder to understand what the programmer was
+>trying to do in the first place.
+
+And putting it all in one place leads to LISP (in the bad way): Lots of
+Irritating Stupid Parentheses. Figuring out what belongs to what becomes near
+impossible. If the syntax of expressions was more readable, I would be less
+concerned, but it is an unintelligable mess. It took a long time to write that
+conformance example the last night, counting parens to figure out if it was
+right. And you have the same thing with a compiler, since it can only guess at
+which paren is missing or extra -- and those guesses only are right about half
+of the time.
+
+>You are certainly right that the same thing can be accomplished by
+>creating a local declare block with a locally declared function whose
+>name is generally just noise), and passing 'Access of it.
+
+No declare block, because an instance already allows the declaration.
+Anonymous access-to-subprogram are just pure evil, please avoid them.
+
+In any case, this construct makes a call or instance itself many times harder to
+read. The extra spacing and keywords helps that readability a lot, and certainly
+makes it possible to figure out what the function and the call do individually.
+That's necessary if you need to figure out an error -- otherwise you have a
+write-only language.
+
+>But the same thing could be said about the container iterators, or
+>protected objects instead of explicit lock/unlock, or generalized
+>references, etc.
+
+Nope, each of them clearly makes the program *easier* to read. Some of them
+arguably cover up too much dynamic semantics, but they surely make the program
+*more* understandable. Nested constructs, OTOH, especially when not set off by
+syntax, really have the opposite effect. This is a problem with all of the Ada
+complex expression syntax, but at least those bring useful new capabilities
+(especially to static expressions). Not so here.
+
+>The fact is that appropriate "syntactic sugar" can change the game
+>significantly, and make certain paradigms easy and natural enough that
+>more complex problems can be tackled.
+
+Sure, but this "sugar" is making the program completely unintelligable. Indeed,
+that is a problem any time a subprogram is passed as a parameter, thus it is a
+technique that ought to be used very sparingly. And the primary use I've had for
+it (iterators) is better handled in Ada 2012 anyway.
+
+>>...
+>>As most of you remember, I strongly advocate the elimination of access type
+>>from client interfaces. While that alone isn't a reason to reject something,
+>>it does mean that I have no interest in making it easier to use
+>>something that I'd prefer you don't use in the first place.
+
+>Anonymous access-to-subprogram types should really not be considered access
+>types at all.  They are really just a way to pass subprograms as parameters.
+>They have none of the issues that access-to-object types have, and
+>really shouldn't be grouped into the same bucket at all.
+
+I agree, they should be avoided on their own merits. ;-)
+
+They too severely harm readability of subprogram specifications. Nested
+parameter lists get unreadable very quickly. I hadn't really realized how bad it
+is until I was trying to write ACATS tests checking the various renaming null
+exclusion rules. The subprograms passing anonymous access-to-functions are
+complete messes, regardless of how you format them, as soon as they don't fit on
+one line (and that was true for even relatively simple functions just using
+Natural everywhere). Once you want to pass a function taking a functional
+parameter to a third function, there is no hope (and that's pretty common in
+higher-order programming).
+
+Moreover, they are actively harmful in our goals of advancing correctness, since
+they can't be given any contracts of their own -- so the writer of the
+specification cannot communicate any requirements to the caller, and the caller
+can't tell if they respected them. Trying to add those contracts to the
+subprograms (as was once suggested by you) would make things even more
+confusing, by mingling the contracts for the parameters and the base
+subprograms.
+
+In order to make these things readable, they *must* have some sort of named
+type, which automatically would allow proper contracts and get rid of this
+unreadable nesting. And if we did that, perhaps we could find a way to a
+shorthand for making calls to these things. But it's really too late for this
+round to engage in this sort of new feature invention.
+
+In any case, multiplying the use of one unreadable feature by adding another
+unreadable feature seems completely the wrong way to go for Ada. This whole area
+requires more thought and a complete plan (for all sides of the question) and
+not just a piece-meal approach.
+
+
+In any case, my question was "what is this good for IN ADA". I don't care a lot
+about adding some feature to attract "younger programmers" or "functional
+programmers" or whatever kind of programmers you want, because I've heard that
+line dozens of times in my many years of working in Ada. And I have yet to find
+a single instance where adding something has had any real effect. People are
+either attracted to Ada because of its readability and rigor and correctness, or
+they aren't. And if they want to use it, they'll get around the occasional thing
+that they find clunky. And otherwise, they'll use those clunky things as a
+convenient excuse for not using Ada (when they never really would have used it
+anyway).
+
+And I know that a lot of people come to understand the virtues behind Ada's
+declare everything explicitly philosophy, and it's emphasis on readability, and
+so on. They might even appreciate that the stuff that they initially missed
+isn't really as important as they thought.
+
+So I view any feature for which the justification is "to attract more xxx
+programmers to Ada" as having no justification at all. That is simply something
+which only fools pursue.
+
+Features have to make sense *for Ada*, otherwise they are a waste of effort. If
+new features have some extra benefit of attracting new customers to Ada (as
+contracts seem to have had), that's great, but we can't know that until after
+the fact, so it should have no weight in whether or not to add features to Ada.
+
+P.S. Note that generic formal type defaults is a similar sort of shorthand. But
+that has a clear use in Ada: making ADTs easier to use and more readable for
+clients (by eliminating the irrelevant from instantiations) - the idea behind
+*every* shorthand that I've supported (and even some that I haven't).
+
+****************************************************************
+
+From: Jean-Pierre Rosen
+Sent: Friday, December 14, 2018  12:27 AM
 
+> Well, a natural implementation of this quantified expression puts Idx
+> into a register temporary. External code, like this function here,
+> would have no way to access such an Idx, as it would have no access to
+> how the register temporary ends up getting mapped by the code
+> generator (to a hardware register, to a spill location, or some combination).
+>
+> So the implementation would to recognize this special case and
+> allocate a real memory location for it.
+
+Disclaimer: it's been a very long time since I put my hands into a code
+generator, but...
+
+It seems to me that you first allocate variables to everything, and then the
+optimizer decides to eliminate the variable for a register if possible. What you
+describe doesn't seem to me to be a "natural implementation": there can be other
+reasons that prevent the index from being a register.
+
 ****************************************************************
 
+From: Randy Brukardt
+Sent: Friday, December 14, 2018  2:05 AM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+Sorry if I wasn't clear. A "register temporary" is a entity that is requested to
+be put into a register if possible, or spilled to backing store if not. The code
+generator ultimately decides what to do.
+
+Ada has a lot of constructs that really cannot be implemented efficiently if the
+intermediate parts have to be written to memory. For instance, think an others
+clause in an array aggregate -- the working addresses need to stay in a register
+if the code is to make any sense. (In most modern machines, performance is
+roughly equivalent to the number of memory operations; that is a very good first
+approximation.)
+
+Additionally, code generators are written by different teams at different times,
+have to deal with all of the oddities of the target architecture, and thus tend
+to not be very similar. But every code generator has to deal with register
+allocation, and the criteria is essentially the same for all targets -- get the
+most used expressions into registers.
+
+Since the loop index of a loop is always the most used expression for that loop,
+it's automatic to put it into a register. The only reason that you wouldn't want
+to do that would be if some optimization blocker like an accept statement or
+exception handler appears in the loop -- but that can't happen for a quantified
+expression. So why even bother with any other form of code generation?
+
+I can't say what solution is given to other compilation systems, but our
+solution was to pull as much as possible of the shared operations into the
+front-end and optimizer, so that the code generator is essentially a peephole
+operation - it only works on very local criteria. Thus, we essentially tell the
+code generator what should be put into registers and what shouldn't. That saved
+each code generator writing a complex register allocator, which would
+approximate the existing common subexpression optimizer anyway. There's a
+package of target-specific information to tailor that better to the target (that
+was always there, as some code that appears simpler generates worse code in our
+relatively simple code generators anyway; also some optimizations need to be
+suppressed for some code generators [when the "code" generated is just the input
+to another compiler, for instance, that's how we did the Unisys compiler.]).
+
+In any case, implementation cost is always going to vary from compiler to
+compiler. Arguments from it are always weak (which is one reason I'm getting
+more and more upset over rejecting AI12-0205-1 solely for that reason).
 
 ****************************************************************
 
+From: Edmond Schonberg
+Sent: Friday, December 14, 2018  7:31 AM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+...
 
+> Moreover, they are actively harmful in our goals of advancing
+> correctness, since they can't be given any contracts of their own --
+> so the writer of the specification cannot communicate any requirements
+> to the caller, and the caller can't tell if they respected them.
+> Trying to add those contracts to the subprograms (as was once
+> suggested by you) would make things even more confusing, by mingling
+> the contracts for the parameters and the base subprograms.
+
+This is probably the strongest argument against the introduction of anonymous
+functions in the language. The Lots of Irritating Stupid Parentheses are not the
+issue, but rather the fact that they make it much harder to describe the purpose
+of a construct. If the anonymous function has a simple body it might as well be
+written nearby as an expression function; if its body is complex the code
+becomes impenetrable and this damages what seems to be the future of the
+language, namely amenability to formal verification. Its introduction would be
+additional complication not just for compiler writers (no big deal, they like
+this sort of thing) but might just make programs harder to analyze by tools such
+as SPARK, make compilers harder to certify, and lead developers to define
+subsets of the language that exclude anonymous functions! Not clear to me that
+the gains outweigh these problems.
+
 ****************************************************************
 
+From: Tucker Taft
+Sent: Friday, December 14, 2018  8:26 AM
 
-From: Brad Moore
-Sent: Thursday, December 13, 2018  11:32 PM
+Readability is best assessed by examples.  Presume we have a search function
+that takes a predicate:
+
+   function Search
+      (C : Container;
+       Predicate : access function (Elem : Element) return Boolean)
+   return Element;
+
+We would like to use it to search for, say, any element in a container that has
+a value >= Min_Value:
+
+  Put_Line ("Found element with value >= Min_Value: " &  Elem_Image
+      (Search (My_Container,
+                    Predicate => (function (E) return Value(E) >= Min_Value))));
+
+vs.
+
+   declare
+        function Predicate (E : Element) return Boolean is (Value(E) >= Min_Value);
+   begin
+        Put_Line ("Found element with value >= Min_Value: " &  Elem_Image
+           (Search (My_Container, Predicate => Predicate'Access)));
+   end;
+
+Seems like a lot of "noise" in that second version, without any additional
+"signal."
+
+****************************************************************
+
+From: John Barnes
+Sent: Friday, December 14, 2018  11:38 AM
+
+I would vote for lambda expression. It was widespread in the course I went to at
+Oxford in 1962.
+
+It wouldn't be a whole chapter just a section but a majestic title.
+
+****************************************************************
+
+From: Jeff Cousins
+Sent: Friday, December 14, 2018  1:41 PM
+
+A shame I had to miss this part of the recent meeting.
+
+Anonymous function is certainly an improvement in the name over function
+expression, though I’m afraid that abstain would be as positive as I could be
+about the whole idea.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Friday, December 14, 2018  3:48 PM
+
+> Seems like a lot of "noise" in that second version, without any
+> additional "signal."
+
+I'd actually agree. But the problem here is this is the absolute best case for
+this feature:
+  (1) There's no need for comments in the function;
+  (2) The result expression of the anonymous function fits in a handful of
+      characters;
+  (3) There's no need for contracts on the function (for which predicate
+      functions are pretty much the sole example);
+  (4) There's only a single parameter, so you can get away with calling it "E".
+  (5) Your using it in a subprogram call rather than the more typical generic
+      instantiation, so you need the "noise" of the declare block.
+
+Typical Ada programming style would suggest that (1) and (4) should be rare,
+(3) is rare as I noted, and (2) isn't that common either. (5) depends on your
+programming style, but I'd expect that much of the time there is a nearby
+declarative part that you could use instead.
+
+As soon as any of these aren't true, the readability plummets.
+
+Try this example with a more typical function with two parameters and a 3-line
+conditional expression. You can't even read the initial function declaration,
+much less the call. (A quick look to find the type of the function result has a
+50-50 chance of turning up the wrong one.) If we're actually going to expect
+people to use this feature extensively, even the existing stuff needs an
+overhaul.
+
+Aside: When I read this message on my phone this morning, the word wrapping made
+the code into a mess; even the function declaration got split into multiple
+parts. I see the Outlook quoting system did the same above. This just shows what
+happens to readability when the lines get longer.
+
+I think I started out by saying that the readability is at best a wash, and this
+is that case -- you've gained by eliminating the name and lost due to the
+nesting. And if you have trouble understanding passing functions in the first
+place (like me), the nesting makes it worse (the presence of 'Access cues me to
+the fact that something unusual is going on).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Sunday, December 16, 2018  9:20 AM
 
+>Typical Ada programming style would suggest that (1) and (4) should be rare,
+
+I think you are missing the point -- typical Ada style can be too heavyweight
+for the common straightforward cases where functional programming streamlines
+things.  Functional programming in my experience is built on functions that
+capture variability that might otherwise need to be captured in multiple
+parameters and complex interfaces.  Rather than passing in lots of parameters to
+control how a data structure should be processed, you pass in one or two
+functions with simple interfaces (i.e. one or two parameters), which incorporate
+within their body all the variability that is needed.
+
+For example, imagine a database management system, which wants to provide an
+ability to select a bunch of records, and then combine them in some useful way.
+This implies a selection function, and a combination function.  The selection
+function would take in a record and return True or False (i.e., filtering), and
+the combination function would take in a record and a combination value and
+return the new combination value (i.e., reduction).  What you are really doing
+is passing in "parameterized expressions," which can be as simple as:
+
+    (rec) such that (rec.value >= N)
+and:
+    (accum, rec) producing (accum + rec.value ** 2)
+
+Hence, this maps very nicely to something like:
+
+    Large_Val_Sum_Of_Squares := Database_Query
+       (My_Database,
+        Select => (function (Rec) return (Rec.Value >= N),
+        Combine => (function (Accum, Rec) return Accum + Rec.Value ** 2));
+
+Finding or creating an appropriate declare block to declare these expressions as
+separate functions, potentially somewhat distant from the invocation of the
+database operation, can defeat the purpose of having this sort of database
+abstraction.
+
+Of course if you have something significantly more complicated, there is no
+requirement to use these short-hands.  That is a major advantage of "syntactic
+sugar" in my view.  The short-hand is not introducing some fundamentally new
+capability, but rather making the existing functionality more usable and
+readable for the frequent simple case.  The underlying capability is always
+available for those who find the short-hand less readable in some complex case,
+while the short-hand is available when it makes the functionality of the
+relatively simple case more readable.
+
+****************************************************************
+
+From: Arnaud Charlet
+Sent: Sunday, December 16, 2018  10:00 AM
+
+> I think you are missing the point -- typical Ada style can be too
+> heavyweight for the common straightforward cases where functional
+> programming streamlines things.  Functional programming in my
+> experience is built on
+
+Fully agreed. Trying to argue on style and on what people would do today in Ada
+isn't really appropriate for new features. Best is to look at how people use
+similar features in languages where these features already exist.
+
+And yes, there are many cases where these shorthands make a lot of sense for
+relatively small expressions and this is where people will typically use them.
+
+Arguing that some people will misused this feature with more complex cases is
+missing the usefulness of the feature: yes, any feature can be misused by
+people, that's what style  guides and coding standards are for, and this isn't
+what a language standard should be about (anymore anyway, we're well past that
+point at this stage).
+
+In addition:
+
+> I'd actually agree. But the problem here is this is the absolute best
+> case for this feature:
+>  (1) There's no need for comments in the function;
+
+That's typically the case for this kind of shorthand.
+
+>  (2) The result expression of the anonymous function fits in a handful
+> of characters;
+
+Same.
+
+>  (3) There's no need for contracts on the function (for which
+> predicate functions are pretty much the sole example);
+
+Again, this kind of simple function is precisely where people would *not* put
+contracts on anyway. People already do not put contracts on similar simple
+functions today, this is our experience with SPARK.
+
+>  (4) There's only a single parameter, so you can get away with calling
+> it "E".
+
+One or a few parameters is the typical use case for this feature.
+
+> Typical Ada programming style would suggest that (1) and (4) should be
+> rare,
+
+Not in our experience these days.
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Monday, December 17, 2018  4:54 PM
+
+..
+> > Typical Ada programming style would suggest that (1) and
+> > (4) should be rare,
+>
+> Not in our experience these days.
+
+Really? You're saying that code rarely needs comments or good naming to be
+understandable?
+
+My personal experience is that when maintaining old code, even if I wrote it
+originally (but many years previous), many things that I considered "obvious"
+and not needing comments then are very difficult to understand now. I can only
+imagine how much harder it is when it is necessary to maintain someone else's
+code.
+
+The only code that doesn't need good comments is throwaway code (code that is
+literally not going to be used again). I'd expect that there is very little
+throwaway code written in Ada (and even when I've written such code, I've often
+went back to it in the future to repurpose it). In any case, throwaway code
+doesn't need readability, so it's clearly not a focus of Ada.
+
+And the only real advantage of this particular proposal is the avoidance of the
+need to pick a good name for the function. If picking good names don't really
+matter in your code, then that is not a problem and there is even less value to
+this proposal than it appears.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Monday, December 17, 2018  5:30 PM
+
+> Really? You're saying that code rarely needs comments or good naming
+> to be understandable?
+
+Again, the point is that the individual "parameterized expression" isn't the
+place where you would necessarily want to put the comment.  Instead, on the
+enclosing call to, for example, the Database_Query operation, you would put a
+comment about what you are trying to accomplish overall.
+
+And as usual, if you really want to comment the parameterized expression, feel
+free!
+
+****************************************************************
+
+From: Arnuad Charlet
+Sent: Tuesday, December 18, 2018   1:49 AM
+
+>>> Typical Ada programming style would suggest that (1) and
+>>> (4) should be rare,
+>>
+>> Not in our experience these days.
+>
+> Really?
+
+Yes
+
+> You're? saying that code rarely needs comments or good naming to be
+> understandable?
+
+No, you read my comment out of context. In the context of these small helper
+functions (such as expression functions in Ada 2012), these are much more common
+since the code is in effect acting as a formal specification.
+
+> My personal experience is that when maintaining old code, even if I
+> wrote it originally (but many years previous), many things that I
+> considered "obvious" and not needing comments then are very difficult
+> to understand now. I can only imagine how much harder it is when it is
+> necessary to maintain someone else's code.
+
+I doubt these include Ada 2012 expression functions, hence my « these days »
+comment.
+
 ****************************************************************
 
+From: Randy Brukardt
+Sent: Tuesday, December 18, 2018  2:24 AM
+
+...
+> > You're? saying that code rarely needs comments or good naming to be
+> > understandable?
+>
+> No, you read my comment out of context. In the context of these small
+> helper functions (such as expression functions in Ada 2012), these are
+> much more common since the code is in effect acting as a formal
+> specification.
+>
+> > My personal experience is that when maintaining old code, even if I
+> > wrote it originally (but many years previous), many things that I
+> > considered "obvious" and not needing comments then are very
+> > difficult to understand now. I can only imagine how much harder it
+> > is when it is necessary to maintain someone else's code.
+>
+> I doubt these include Ada 2012 expression functions, hence my < these
+> days > comment.
+
+Really? Replacing three keywords with parens somehow changes the need to
+document??
+
+Whatever you are trying to say, it doesn't have anything to do with the form of
+the declaration!
+
+If you have a function, you have to explain what it does and why you're using
+the formula given in it. The form of the declaration has nothing to do with
+that.
+
+If you can't explain what a function is for, then it shouldn't be a function at
+all; find some other way to decompose the program.
+
+P.S. I've written plenty of expression functions, including tonight. Lots of my
+existing code would use them, to, if my compiler supported them.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Tuesday, December 18, 2018  1:43 AM
+
+Here's a comment/question about one aspect of the proposal (see below).
+
+> !wording
+>
+> ...
+>
+>   In a context where there is an expected type rather than an expected
+>   profile for an anonymous_function, the expected type shall be a single
+>   anonymous access-to-function type, and the profile of this type is considered
+>   the expected profile for the anonymous_function.  The result type of
+
+In the first sentence above, why is the expected type being limited to an
+*anonymous* access-to-function type?  Don't we intend to allow this feature for
+use with formals of named access-to-function types as well, and if not, why not?
+BTW, one of the examples involves a named type.
+
+> !discussion
+>
+> ...
+>
+> We limit this to cases of anonymous access-to-subprogram types used as
+> function parameters.  Other cases, like access discriminants and
+> stand-alone access objects seemed like more trouble that they are
+> worth, since those generally occur in contexts where declaring a local
+> subprogram is not a burden.
+
+This !discussion paragraph also seems to indicate that the feature is limited to
+cases where the type is anonymous.  I don't see why it would be limited that
+way, is this really intended?  (And that should presumably say
+"access-to-function types".)
+
+Also, it says "used as function parameters", but surely that should be "used as
+subprogram parameters", since we also allow them to be passed as parameters in
+procedure calls.
+
+> !example
+>
+>     --  Replace control chars with '?'
+>     Ada.Strings.Fixed.Translate
+>       (Str, (function (C) return (if C < ' ' then '?' else C)));
+>
+
+The second parameter of Translate is a named access-to-function type (type
+Character_Mapping_Function).
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 18, 2018  12:27 AM
+
+>>  In a context where there is an expected type rather than an expected
+>> profile for an anonymous_function, the expected type shall be a
+>> single  anonymous access-to-function type, and the profile of this
+>> type is considered  the expected profile for the anonymous_function.
+>> The result type of
+>
+> In the first sentence above, why is the expected type being limited to
+> an *anonymous* access-to-function type?  Don't we intend to allow this
+> feature for use with formals of named access-to-function types as
+> well, and if not, why not?
+
+Because a named access type has an accessibility level, and these anonymous
+functions are declared more locally than any named access type.
+
+>  BTW, one of the examples involves a named type.
+
+Good point, the Ada.Strings.Fixed.Translate example should be replaced, perhaps
+with one of the Database_Query examples mentioned in this (endless) e-mail
+chain.
+...
+
+> This !discussion paragraph also seems to indicate that the feature is
+> limited to cases where the type is anonymous.  I don't see why it
+> would be limited that way, is this really intended?  (And that should
+> presumably say "access-to-function types".)
+
+Yes, as indicated above, accessibility rules require that the formal parameter
+be of an anonymous access-to-function type.
+
+>
+> Also, it says "used as function parameters", but surely that should be
+> "used as subprogram parameters", since we also allow them to be passed
+> as parameters in procedure calls.
+
+Yes, good point.  Should say subprogram parameters.
+
+>>
+>> !example
+>>
+>>    --  Replace control chars with '?'
+>>    Ada.Strings.Fixed.Translate
+>>      (Str, (function (C) return (if C < ' ' then '?' else C)));
+>>
+>
+> The second parameter of Translate is a named access-to-function type
+> (type Character_Mapping_Function).
+
+Agreed -- this example should be replaced.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Tuesday, December 18, 2018  2:30 PM
+
+> Because a named access type has an accessibility level, and these anonymous
+> functions are declared more locally than any named access type.
+
+Ah right, I should have thought of that. :-)
+
+BTW, the !summary should perhaps be changed to say "that has an {anonymous}
+access-to-function parameter" (also first paragraph of !proposal).  And should
+the part that says ", or other contexts where the expected type is an
+access-to-function type," be removed, since these are basically only allowed for
+subprogram calls (according to the legality rule that you added), or are there
+actually other legal contexts involving expected types that I'm missing?
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 18, 2018  2:58 PM
+
+> BTW, the !summary should perhaps be changed to say "that has an
+> {anonymous} access-to-function parameter" (also first paragraph of
+> !proposal).  And should the part that says ", or other contexts where
+> the expected type is an access-to-function type," be removed, since
+> these are basically only allowed for subprogram calls (according to
+> the legality rule that you added),
+
+All good suggestions.
+
+> or are
+> there actually other legal contexts involving expected types that I'm missing?
+
+We simplified by limiting this to access parameter cases, since discriminants
+and stand-alone access objects of an anonymous type just hurt too much to think
+about. ;-)
+
+****************************************************************
+
+From: Steve Baird
+Sent: Tuesday, December 18, 2018  8:13 PM
+
+The proposed wording generally looks good to me.
+I've got a couple of questions.
+
+Is it clear from the proposed wording that the only contexts in which an
+anonymous function can occur are either
+    a) in a context where an access-to-function type is the expected
+       type; or
+    b) as an actual in an instance corresponding to a formal subprogram ?
+
+We have the introductory wording
+>   Anonymous functions provide a way to define a function at a point
+>   where an access-to-function type is the expected type, or in a generic
+>   instantiation as an actual parameter corresponding to a formal subprogram
+>   parameter.
+
+but that's not usually how we do this kind of thing (I'm not suggesting changing
+that wording - only augmenting it elsewhere).
+
+I think we need a clearer rule stating that these guys cannot be renamed, cannot
+occur in an aspect specification in a context where a name denoting a function
+is expected, etc.
+
+I assume we want to prevent
+     for T'Input use (<some anonymous function>); or
+    function F (X : T) return T renames (<some anonymous function>); .
+
+====
+
+We've got
+
+>   An anonymous_function used in a context where there is an expected
+>   type is equivalent to an expression_function_declaration (see
+>   6.8) declared within the innermost declarative region with the
+>   anonymous_function replaced by an Access
+>   attribute_reference of this locally defined function
+
+and similarly for the actual-subprogram-of-an-instance case.
+
+Do we want a TBH note clarifying that it wouldn't always be possible for users
+to declare this "equivalent" expression function at the source level (e.g., if
+it occurs within a quantified expression or an iterated component association)?
+
+Maybe this is unnecessary, but intuitively the above rule seems to suggest that
+this is a more of a "syntactic sugar" construct that it really is.
+
+====
+
+Do we need to update the accessibility rules to handle the following construct?
+
+The proposed "innermost declarative region" wording does what we want with
+respect to visibility, but does it correctly reject a bad construct like
+
+  procedure Test is
+     type Rec (Discrim : access function return Integer := null) is
+        limited null record;
+
+     type Vec is array (Positive range <>) of Rec;
+
+     procedure Consume_Vec (Arg : Vec) is null;
+   begin
+    Consume_Vec
+      (Arg => Vec'(for Idx in 1 .. 10 =>
+                     Rec'(Discrim => (function return Idx))));
+   end;
+
+I think there may be a problem here because the definition of "master" is too
+coarse to prevent what this example is trying to do.
+
+***************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 18, 2018  8:52 PM
+
+> We have the introductory wording
+>>  Anonymous functions provide a way to define a function at a point
+>> where an access-to-function type is the expected type, or in a
+>> generic  instantiation as an actual parameter corresponding to a
+>> formal subprogram  parameter.
+>
+> but that's not usually how we do this kind of thing (I'm not
+> suggesting changing that wording - only augmenting it elsewhere).
+
+I agree.
+
+> I think we need a clearer rule stating that these guys cannot be
+> renamed, cannot occur in an aspect specification in a context where a
+> name denoting a function is expected, etc.
+>
+> I assume we want to prevent
+>    for T'Input use (<some anonymous function>); or
+>   function F (X : T) return T renames (<some anonymous function>);
+
+I suspect these are harmless, but I agree we might as well restrict the context so they can only be used as generic formal function actuals, generic formal function defaults, callable-parameters, and callable defaults.
+
+> .
+>
+> ====
+>
+> We've got
+>
+>>  An anonymous_function used in a context where there is an expected
+>> type is equivalent to an expression_function_declaration (see
+>>  6.8) declared within the innermost declarative region with the
+>> anonymous_function replaced by an Access  attribute_reference of this
+>> locally defined function
+>
+> and similarly for the actual-subprogram-of-an-instance case.
+>
+> Do we want a TBH note clarifying that it wouldn't always be possible
+> for users to declare this "equivalent" expression function at the
+> source level (e.g., if it occurs within a quantified expression or an
+> iterated component association)?
+
+I believe there is already such a TBH, a little further down.
+
+> Maybe this is unnecessary, but intuitively the above rule seems to
+> suggest that this is a more of a "syntactic sugar" construct that it
+> really is.
+>
+> ====
+>
+> Do we need to update the accessibility rules to handle the following
+> construct?
+>
+> The proposed "innermost declarative region" wording does what we want
+> with respect to visibility, but does it correctly reject a bad
+> construct like
+>
+> procedure Test is
+>    type Rec (Discrim : access function return Integer := null) is
+>       limited null record;
+>
+>    type Vec is array (Positive range <>) of Rec;
+>
+>    procedure Consume_Vec (Arg : Vec) is null;  begin
+>   Consume_Vec
+>     (Arg => Vec'(for Idx in 1 .. 10 =>
+>                    Rec'(Discrim => (function return Idx))));  end;
+>
+> I think there may be a problem here because the definition of "master"
+> is too coarse to prevent what this example is trying to do.
+
+We specifically do *not* want to allow these for access discriminants, to avoid
+getting into the 3.10.2 heart-of-darkness territory.  That is why they are only
+permitted as parameters or defaults to a subprogram where the formal is of an
+anonymous access-to-function type.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 18, 2018  9:27 PM
+
+>I believe there is already such a TBH, a little further down.
+
+I had already suggested such a TBH in this long e-mail chain, but it got lost
+when I updated the AI.  Here is what I had proposed:
+
+{AARM To Be Honest: Depending on the nature of the innermost enclosing
+ declarative region, this equivalence might violate the normal syntax rules
+ which would not permit such an expression_function_declaration in such a
+ region.}
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Tuesday, December 18, 2018  9:50 PM
+
+Here is a version that incorporates comments from Gary, Steve, and Bob. [This is
+version /07 of the AI - Editor.]
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, December 19, 2018  11:31 AM
+
+> I agree we might as well restrict the context so they can only be used as
+> generic formal function actuals, generic formal function defaults,
+> callable-parameters, and callable defaults.
+>> .
+
+...
+
+> We specifically do *not* want to allow these for access discriminants, to
+> avoid getting into the 3.10.2 heart-of-darkness territory.  That is why they
+> are only permitted as parameters or defaults to a subprogram where the formal
+> is of an anonymous access-to-function type.
+
+I agree with all of the above (and I agree that this would address my
+accessibility concerns), but I don't understand how the version 7 wording you
+proposed accomplishes this.
+
+What prevents, for example, using an anonymous function as an
+access-to-subprogram discriminant value?
+
+I suspect I am missing something.
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, December 19, 2018  11:35 AM
+
+> I agree with all of the above (and I agree that this would address my
+> accessibility concerns), but I don't understand how the version 7
+> wording you proposed accomplishes this.
+>
+> What prevents, for example, using an anonymous function as an
+> access-to-subprogram discriminant value?
+
+The legality rules say:
+
+ When used in a context where there is an expected type, the  anonymous_function
+ shall be an actual parameter in a call, or a  parameter default for a callable
+ entity.  When used in a context  where there is only an expected profile, the
+ anonymous_function  shall be a generic actual parameter in a
+ generic_instantiation for a  formal subprogram parameter, or as the
+ subprogram_default for such a formal  subprogram parameter.
+
+Doesn't this make it clear that these cannot be used for access discriminants?
+>
+> I suspect I am missing something.
+
+Perhaps the Legality Rules could be restated somehow.  But they seem pretty
+clear to me.
+
+****************************************************************
+
+From: Steve Baird
+Sent: Wednesday, December 19, 2018  11:41 AM
+
+> Doesn't this make it clear that these cannot be used for access discriminants?
+
+Yes, I just managed to confuse myself.
+
+The wording is fine,
+
+Sorry about the noise.
+
+****************************************************************
+
+From: Gary Dismukes
+Sent: Wednesday, December 19, 2018  1:57 AM
+
+> ...
+>
+> !summary
+>
+> Provide an ability to construct a local anonymous function at the
+> point of a call on a subprogram that has an access-to-function
+> parameter, or in an instantiation with a formal subprogram parameter.
+
+I would like the !summary to say "... a call on a subprogram that has an
+{anonymous} access-to-function parameter, ...".  I guess you forgot to make that
+change. :)
+
+****************************************************************
+
+From: Tucker Taft
+Sent: Wednesday, December 19, 2018  1:57 AM
+
+Oops!  Consider the change made... ;-)
+
+****************************************************************
+
+From: Randy Brukardt
+Sent: Wednesday, January 9, 2019  12:03 AM
+
+> Here is a version that incorporates comments from Gary, Steve, and 
+> Bob.
+
+You used an older version of this as the basis, so you put back various 
+errors that I had corrected.
+
+I also had get rid of 22 extra spaces after periods. :-)
+
+---
+
+I never saw a definitive answer to my original question about conformance of 
+anonymous function, or for that matter for the declaration in the expression 
+of the body.
+
+The original example was:
+
+   package Pack is
+      function Ugh (P : Natural := Foo ((function (A) return A*2), 2)) return Natural;
+   end Pack;
+
+   package body Pack is
+      function Ugh (P : Natural := Foo ((function (A) return A*2), 2)) return Natural is ...
+   end Pack;
+
+   with Pack;
+   procedure Main is
+      V : Natural := Pack.Ugh;
+   begin
+      Put (V'Image);
+   end Main;
+
+There are two issues here. 
+
+The lesser issue is that each of these functions are separate declarations, 
+so there has to be a (dead) declaration and body for the second. And the 
+compiler clearly will have to do most of the compilation steps on that 
+second one, since it could have different resolution than the first. So 
+there has to be yet another special case in the compiler (unless it has 
+good dead subprogram elimination and its OK to waste time compiling 
+something that will never be used.
+
+The primary issue, however is how this is handled for conformance.
+
+Steve points to 6.3.1(21/4), which says:
+
+each direct_name, character_literal, and selector_name that is not part of the 
+prefix of an expanded name in one denotes the same declaration as the 
+corresponding direct_name, character_literal, or selector_name in the other, 
+or they denote corresponding declarations occurring within the two 
+expressions; and 
+
+It seems this works for the anonymous function itself, but I don't know if it 
+works for the (A). This is described in terms of the profile of the outer 
+declaration rather than being a declaration of its own, and while I suppose 
+we could just handwave it (it has to be some sort of declaration if it is 
+making a name visible), we should at least make that handwaving explicit with 
+an AARM note.
+
+Note that depending on this rule means that the ids in the profiles don't have 
+to be the same, they just have to denote the same parameter:
+
+   package Pack is
+      function Ugh (P : Natural := Foo ((function (A) return A*2), 2)) return Natural;
+   end Pack;
+
+   package body Pack is
+      function Ugh (P : Natural := Foo ((function (B) return B*2), 2)) return Natural is ...
+   end Pack;
+
+6.3.1(20.1/4) is supposed to prevent that:
+   corresponding defining_identifiers occurring within the two expressions are
+   the same; and
+
+but it doesn't apply here as there are no defining_identifiers in the syntax 
+of an anonymous function.
+
+Not sure if something ought to be changed to eliminate this possibility, but 
+at minimum there should be some sort of AARM note about conformance of 
+parameters of anonymous functions and probably some mention of conformance in 
+the !discussion.
+
+****************************************************************

Questions? Ask the ACAA Technical Agent