A thread in July/August 2009 on comp.lang.ada (see Google groups thread) discussed the issue of using anonomous access types in Ada.
I've written a small example, based on OpenToken. It is implemented in two styles; one using anonymous access types (access_style), the other not (object_style). The object style uses Ada.Containers Cursors to get reference semantics when needed.
The source is available here: access_vs_object-2009-08-18.tar.gz, access_vs_object-2009-08-18.zip. I've tested it with GNAT 6.2.1 on Windows and GNAT 4.4 on Debian.
The problem domain of this example is grammars; the goal of the application is to allow the user to build a data structure that represents a grammar, so the application can then use that structure to parse input strings.
Typical grammars have recursion in them. This requires pointers of some form in the data structure. The access_style package tree in this example uses explicit access types as the pointers, and access parameters in the relevant grammar constructing functions. The object_style package tree uses Ada.Containers Cursors as the pointers.
The object style contains a significant kludge; there is a global (but private, in Object_Style.Pointers spec) List object that holds all the tokens needed for the grammar. That was the only way I could see to get a Cursor for each. AI05-0069-1 defines holder containers that should eliminate this kludge in Ada 201z.
In addition, in Object_Style.Sequence "&" body, we must examine the tag of the arguments, rather than using dispatching to achieve the same result. This doesn't happen in the access style, because we can define two "&" functions with different type profiles; one takes a token object, the other an access to class-wide.
Finally, some type information is lost with this style. Compare object_style-run.adb to access_style-run.adb; there are more precise types in the access style version. In the full OpenToken application, this becomes even more significant.
There are two main objections to the access style:
The first objection can be mitigated by realizing that there is never any need to deallocate any of the grammar structures. This could be made explicit with a new pragma No_Deallocations.
The second objection can be eliminated by adding preconditions, as defined by ai05-0145-1 and ai05-0024-1:
pragma Inherited_Precondition ("/", Left in Access_Style.Token_Access_Type);
A reasonably smart compiler can then report the accessibility errors at compile time rather than runtime.
With the facilities of Ada 201z, I believe using explicit access types and access parameters is the best fit to the problem domain. Using container Cursors as the pointers is awkward, loses type information, and doesn't gain enough to be worth it.
my home page Author : Stephen Leake Last modified: Thu Feb 11 11:00:54 EST 2010