Differences when using anonymous access procedures or access procedure types - scope

I've been working with Ada for a bit over a year, and while I think I've got the hang of it and feel comfortable with the very strong type system, I run into troubles once in a while.
At the moment, I have an issue regarding nested procedures in which the compiler gives me an error which I do not really can wrap my head around: subprogram must not be deeper than access type. This error arises when I've declared a type which is an access to a procedure, however it works flawlessly when using an anonymous access parameter, as shown in the following MWE:
procedure Generaltest is
type T_Access_Procedure is access procedure;
procedure Test_Access (Proc : access procedure) is
begin
null;
end Test_Access;
procedure Test_Type (Proc : in T_Access_Procedure) is
begin
null;
end Test_Type;
procedure Test is
procedure Nested_Procedure is
begin
null;
end;
-- Not allowed; subprogram must not bee deeper than access procedure.
Proc : T_Access_Procedure := Nested_Procedure'Access;
begin
Test_Access (Nested_Procedure'Access); -- This line works fine.
Test_Type (Nested_Procedure'Access); -- This line also generates the error.
end Test;
begin
Test;
end Generaltest;
From my point of view, this can be interpreted in two different ways, depending on the emphasis; the subprogram must not be deeper than access type or, the subprogram must not be deeper than access type. In other words, is the error regarding the subprogram itself, or the type of the parameter? I tend to believe it is the former as the subprogram is an access type, but I'm definitely not sure.
Can someone explain to me what is the real difference between using the type as in parameter or using an access parameter in this sence and why the former is thought to be "deeper"?
In my world using the type T_Access_Procedure as an in paramater is a more elegant way of doing it, especially if my procedure of choice is to be used in many procedures or if it have a long argument list.

As discussed in Ada 95 Rationale, 3.7.2 Access to Subprograms, "Compile-time accessibility rules ensure that a subprogram designated by an access value cannot be called after its enclosing scope has exited." In your example, an access value referencing Nested_Procedure is only valid within the scope of Test, but a value of type T_Access_Procedure could be used to invoke Nested_Procedure outside the scope of Test. Both Proc and the actual parameter passed to Test_Type are of type T_Access_Procedure; neither is permitted.
A specific alternative depends on what you want to do. It may be helpful to look at Rationale for Ada 2012, 6.3 Iteration. As discussed here, "Generic formal subprograms remain the most general means of parameterizing an algorithm by an arbitrary externally specified subprogram."

The difference is deliberate. As trashgod has explained, with a named access type, it is possible to store the access value and call it later, and the rules are intended to prevent storing a value that might otherwise be called when it is invalid. Anonymous access-to-subprogram parameters, on the other hand, cannot be stored, which allows passing any subprogram.

Related

How to get a message from compiler when incorrect string format is used

Here is a piece of Delphi code that the compiler perfectly compiles :
Var S: String;
Begin
S := Format('%s %s', ['Hello']);
....
But on execution it raises an exception, of course there are two argument in the left string, and only one in the brackets...
Is there a way to have this error checked by the compiler and to be displayed at least as a warning, or better fatal error?
The compiler as currently written makes no effort to know about what's embedded between the quotes in the first parameter. It also doesn't count the values being passed in the second parameter, or have any idea whether they're correct. They're not evaluated until the function is called, where the exception is raised because they're incorrect. IOW, the compiler does not attempt to do anything that would allow it to issue such a warning or error.
When the function is called at runtime, it validates the number of arguments, whether they're the right type or not, and whether you've provided proper arguments. The compiler doesn't attempt to do that in any way. It only makes sure that you provide a string for the first parameter and an array of const for the second.
So to directly answer the question you've asked: No, there is no way to have the error checked by the compiler to have it issue a warning, because the compiler makes no effort to check anything that would allow it to do so.

Accessing a routine's Capture from within

What's the syntax for accessing a subroutine Capture once it's called? self only works for objects, and &?ROUTINE refers to the static routine, not its state once called. So first, is it possible to access the routine's Capture from inside? If so, what's the syntax for accessing it? I've looked at the related Synopse but I can't find a way, if there's one.
There's no way to do exactly what you're asking for. While conceptually arguments are passed by forming a Capture object holding them, which is then unpacked by a signature, for most calls no Capture ever really exists. With every operator in Perl 6 being a multi-dispatch subroutine call, the performance of calling is important, and the language design is such that there's plenty of room for implementations to cheat in order to achieve acceptable performance.
It is possible to explicitly ask for a Capture, however:
sub foo(|c ($a, $b)) { say c.perl; }
foo(1, 2);
This will capture the arguments into c and then unpack them also into $a and $b, enforcing that inner signature.
One might realize that things like callsame do indeed find a way to access the arguments to pass them on, even though no Capture appears in the signature. Their need to do so causes the compiler to opt any routine containing a callsame out of various optimizations, which would otherwise discard information needed to discover the arguments. This isn't ideal, and it's probable it will change in the future - most likely by finding a way to sneak a |SECRET-CAPTURE into the signature or similar.

What do creating an object "explicitly" and "implicitly as a result of elaboration" mean?

From p498 of Programming Language Pragmatics, by Scott
With a reference model for variables, every object is created
explicitly, and it is easy to ensure that an appropriate constructor
is called.
With a value model for variables, object creation can happen
implicitly as a result of elaboration. In Ada, which doesn’t provide
automatic calls to constructors by default, elaborated objects begin
life uninitialized, and it is possible to accidentally attempt to use
a variable before it has a value. In C++, the compiler ensures that an
appropriate constructor is called for every elaborated object, but the
rules it uses to identify constructors and their arguments can
sometimes be confusing.
What does it mean by creating an object "explicitly" and "implicitly as a result of elaboration"?
What does "elaboration" mean?
Thanks.

Is there a way to use the namelist I/O feature to read in a derived type with allocatable components?

Is there a way to use the namelist I/O feature to read in a derived type with allocatable components?
The only thing I've been able to find about it is https://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/269585 which ended on an fairly unhelpful note.
Edit:
I have user-defined derived types that need to get filled with information from an input file. So, I'm trying to find a convenient way of doing that. Namelist seems like a good route because it is so succinct (basically two lines). One to create the namelist and then a namelist read. Namelist also seems like a good choice because in the text file it forces you to very clearly show where each value goes which I find highly preferable to just having a list of values that the compiler knows the exact order of. This makes it much more work if I or anyone else needs to know which value corresponds to which variable, and much more work to keep clean when inevitably a new value is needed.
I'm trying to do something of the basic form:
!where myType_T is a type that has at least one allocatable array in it
type(myType_T) :: thing
namelist /nmlThing/ thing
open(1, file"input.txt")
read(1, nml=nmlThing)
I may be misunderstanding user-defined I/O procedures, but they don't seem to be a very generic solution. It seems like I would need to write a new one any time I need to do this action, and they don't seem to natively support the
&nmlThing
thing%name = "thing1"
thing%siblings(1) = "thing2"
thing%siblings(2) = "thing3"
thing%siblings(3) = "thing4"
!siblings is an allocatable array
/
syntax that I find desirable.
There are a few solutions I've found to this problem, but none seem to be very succinct or elegant. Currently, I have a dummy user-defined type that has arrays that are way large instead of allocatable and then I write a function to copy the information from the dummy namelist friendly type to the allocatable field containing type. It works just fine, but it is ugly and I'm up to about 4 places were I need to do this same type of operation in the code.
Hence trying to find a good solution.
If you want to use allocatable components, then you need to have an accessible generic interface for a user defined derived type input/output procedure (typically by the type having a generic binding for such a procedure). You link to a thread with an example with such a procedure.
Once invoked, that user defined derived type input/output procedure is then responsible for reading and writing the data. That can include invoking namelist input/output on the components of the derived type.
Fortran 2003 also offers derived types with length parameters. These may offer a solution without the need for a user defined derived type input/output procedure. However, use of derived types with length parameters, in combination with namelist, will put you firmly in the "highly experimental" category with respect to the current compiler implementation.

What's this language token/keyword/thingy mean?

At the following URL: https://developer.mozilla.org/en/XPCOM_Interface_Reference/nsICacheVisitor is the following code chunk:
boolean visitDevice(in string deviceID, in nsICacheDeviceInfo deviceInfo);
I thought I was dealing with c++, but "in" is not a c++ keyword according to c++ keyword lists i looked up, nor is it a java keyword. So what's it there for and what's it mean?
It means that the parameter is an input parameter, meaning that it will be used but not modified by the function.
The opposite of an in parameter is an out parameter, which means that the parameter is going to be modified, but not explicitly returned. If you were to use an out parameter after a method that uses it, the value is going to (potentially) be different.
As nos points out in the comment, the page you linked to is describing a .idl, or Interface definition language, file. I'm not familiar with the IDL that Mozilla uses (but if you want to learn more, you can read about it here), but I am somewhat familiar with the Object Management Group's IDL, which says that in parameters are call-by-value, out parameters are call-by-result, and inout parameters are call-by-value/result.
The language is Mozilla's Interface Description Language (XPIDL).
The keyword "in" is described here: here
I've seen frameworks/SDKs for C/C++ that define macros to indicate whether a parameter is for input, output or both. I'm guessing that that's what's going on in your example.
For example, the Windows DDK does this for IN OUT and INOUT (if I remember right). When compiling these macros are defined to nothing, they have the potential to be defined to something useful for other tools (like an IDL compiler or a static analysis tool). I;m not sure if they still use these macros in the more recent DDKs.
Microsoft has taken this idea to an extreme with the SAL macros that give a very fine level of control over what behavior is expected for a parameter.

Resources