> And GNAT refused to compile it, because "subprogram must not be deeper
> than access type".
>
> So I imagined that since Builder and Output have the same lifetime, it
> might not be so well-define which will cease to exist first.
Note that the error message says "access TYPE". The Output object
has nothing to do with it. It is complaining because the access
type is at library level, whereas Builder is nested inside Main.
>...So while
> not strictly deeper, being as deep can be a problem.
No, two things at the same level have lifetimes that end at
the same time.
I don't really understand what you're trying to do, so I can't advise
you how to fix it. It might be better to use dispatching procedures
rather than access-to-procedure.
It's probably best if you avoid putting any significant code inside
your main procedure. Put everything in library packages or generic
packages, and make the main procedure just one line.
- Bob
As an aside, I'd consider an alternative type
String_Accumulator_Linked_List that
has a stack, rather than being a stack.
From this choice a more flexible design
might follow.
Also, whenever an anonymous type
seems to solve a design problem,
something might be in bad shape
at a higher level. Note that a pointer
has two ends and a direction:
You could pass work in its direction
instead of working with pointers at this
end.
The problem is that there is nothing special about the main-program procedure.
Specifically, it could be withed and called from something else, or call itself
recursively. In either case, its declarative region, with its declaration of the
function, would be nested deeper than the declaration of the access type. Since
this is a compile-time check, it rejects anything that might be deeper, even
when it never is.
The basic rule with named access-to-subprogram types is that the actual
subprogram must be declared in a library-level package.
--
Jeff Carter
"Every sperm is sacred."
Monty Python's the Meaning of Life
55
> At the other end, a factory like Accumulator_Builder might (or might not)
> deserve a type of its own.
I should have said type other than pointer.
> On 09/26/2011 06:43 AM, Robert A Duff wrote:
>> Natasha Kerensikova<lithi...@gmail.com> writes:
>>
>>> Having read the Rationale 2005, I understand now that naming an access
>>> type is far from being equivalent to text replacement.
>>
>> Yeah. That's a language design flaw.
>
> I think anonymous types are the language design flaw.
There were introduced for the need of anonymous access type to
subprograms, but 1) were applied to objects in the while 2) there were
probably alternatives (as the mentioned rational recognized). So, may be
you are right. I confess I don't really enjoy anonymous access type too.
Except that if I'm not wrong, anonymous access type were also introduced
for the need of some parts of I/O packages. Someone can tell more ?
> Le Tue, 27 Sep 2011 09:52:09 +0200, Dmitry A. Kazakov
> <mai...@dmitry-kazakov.de> a écrit:
>> Compare it with declare-begin-end blocks they too have no names and have no
>> identifiable counterpart in the domain, just an implementation detail.
> Except these are just flowed. If you want a block to be possibly invoked
> independently, then you make it a procedure, … which is named.
There is no clear margin, but the name of a procedure may refer to its name
and/or its singleton type. They are not separated properly, because Ada has
no procedural types.
BTW, blocks can be named in Ada:
A : begin
null;
end A;
Here A is the proper name, and you don't need the type of A. This type is
anonymous.
> If you do not need to access sub‑records of a record,
Access to the subrecord is needed, but only though its components not as a
whole. These components would be named but have anonymous types.
------------------------------
BTW, the list of parameters of a subprogram is an anonymous record type,
but Ada does not require its explicit declaration, e.g.
type Integer_Tuple is record
Left : Integer;
Right : Integer;
end record;
function "+" : Integer_Tuple return Integer;
If it could, you would have so much longed variant arguments:
type Printf_Arguments (Some_Discriminant : ...) is record
case Some_Discriminant is
when ... =>
when ... =>
...
end case;
end record;
pragma Unchecked_Union (Printf_Arguments);
procedure Printf : Printf_Arguments;
(:-))