[comp.lang.ada] parameter passing

jon@bdmrrr.bdm.com (Jon Humphreys) (06/21/89)

I'm currently trying to learn Ada by translating a program written
in BASIC (my employer's choice, not mine), and I've got a fairly
fundamental question: when passing parameters from one package
to another, is it possible to simulate something like a FORTRAN
common block by placing variables in a package and then 
using the package whenever I need to access/modify the variables? For
example, consider the following hierarchy:

				main
				 | 
			--------------------
			|  		   |
			A		   B
					---|---
					|     |
(B, C, and D are a package)		C     D

If a set of variables were used in procedures A and D, would it
be possible to create a package containing these variables and 
then include them in procedure A and D? Or should all the variables
be declared in main and then passed as parameters to A and B, and then
from B to D (this seems inefficient)? I guess what I'm asking is, which 
way would be considered correct in Ada? (Currently, we don't even have a 
compiler, so there isn't any way for me to test this kind of thing.)

Thanks for any help, 

jon

billwolf%hazel.cs.clemson.edu@hubcap.clemson.edu (William Thomas Wolfe,2847,) (06/22/89)

From article <1116@bdmrrr.bdm.com>, by jon@bdmrrr.bdm.com (Jon Humphreys):
> I'm currently trying to learn Ada by translating a program written
> in BASIC (my employer's choice, not mine), and I've got a fairly
> fundamental question: when passing parameters from one package
> to another, is it possible to simulate something like a FORTRAN
> common block by placing variables in a package and then 
> using the package whenever I need to access/modify the variables? 

    Sure, it's easy.  Just set up:

      package Global_Variables is

         First_Variable  : First_Variable_Type := Initial_Value;

         Second_Variable : Second_Variable_Type;

         -- etc...

      end Global_Variables;

   Then simply with the package whenever you need it; just remember 
   to qualify all references with the package name, e.g., 

      Global_Variables.First_Variable := whatever...;

   Now as to whether or not this is a good idea, I think *you* already
   know that the application should be redesigned rather than translated
   literally; so just post your boss's e-mail address and we'll...   :-)


   Bill Wolfe, wtwolfe@hubcap.clemson.edu

stt@inmet.inmet.com (06/27/90)

Re: Assumptions about parameter passing

No, it is not a safe assumption.  In a distributed address
space (such as the 1750A expanded memory model), the compiler
will copy composite parameters which would not be addressible
in the called routine's address space, whereas those
which are addressible may be passed by reference.

Another case is where one formal parameter is constrained, and the other
is unconstrained or simply has a different
constraint (though both are of the same type).  Many compilers
pass "short" composite objects by copy, and longer or unconstrained
ones by reference.

In any case, I am curious why you care.  It would be
useful to have specific examples of where this kind
of assumption about parameter passing
would be useful, since limiting compiler flexibility
can severely interfere with efficiency.
However, it is also the case that variability can
make certain kinds of program proofs more complicated
(though not always! Sometimes it is easier to prove
something using a non-deterministic model than
a deterministic model).

S. Tucker Taft
Intermetrics, Inc.
Cambridge, MA  02138

mfeldman@seas.gwu.edu (Michael Feldman) (06/28/90)

In article <1569@oravax.UUCP> davidg@oravax.UUCP (David Guaspari) writes:
>Certain kinds of reasoning about Ada subprograms that terminate by
>raising exceptions are considerably simplified if one is allowed to
>make the following assumption:
>
>   If a and b are actual parameters to some call of subprogram P,
>   and a and b are of the same type, then that call passes them
>   in the same way (either both by copy or both by reference).
Scalars are passed by copy - always. Structures and arrays can be
passed by reference or by copy. I can speak for a few compilers I know
(but don't remember which is which) - many systems will gauge which way
to pass based on the size of the parameter. That is, arrays known to be 
"small" will be copied, but arrays not known to be small - either known to
be large, or unconstrained and of unknown size - will be passed by reference.
Since constrained objects of an unconstrained type have different subtypes
but the same type, what you say holds true in my experience. I can't imagine
why different objects of the same type should be passed differently. But
then again, there are a lot of imaginable things _I_ can't imagine.
Great question for language lawyers!
---------------------------------------------------------------------------
Prof. Michael Feldman
Department of Electrical Engineering and Computer Science
The George Washington University
Washington, DC 20052
+1-202-994-5253
mfeldman@seas.gwu.edu
---------------------------------------------------------------------------

davidg@oravax.UUCP (David Guaspari) (06/29/90)

Here's why I asked whether it would be reasonable to assume that
parameters of the same type are passed in the same way.  My problem is
reasoning about the values of out or inout parameters of composite
types after exceptional exit.

There are useful, simple cases in which we know how to write the
intended programs (in a natural way) and convince ourselves that
they're correct.

1. Example: Consider 

  procedure add_item(comp: in out composite_type, i: item_type)

part of whose specification is

  If i is an inappropriate item, then raise the exception
  INAPPROPRIATE_ITEM and leave comp unchanged.

If comp is passed by copy, then this part of the specification is
satisfied free of charge, so (at least as far as the given spec is
concerned) we can safely reason about add_item under the assumption
that comp is passed by reference.

2. Generalizing the example: 

What the example really shows is that it's possible to reason easily
about *invariant properties* of writable composite parameters -- i.e.,
about specifications like

  (*)  If some_exception is raised then (in the resulting exit state) 
       comp still satisfies some_property_it_satisfied_on_entry

It takes modest care to formulate "comp still satisfies ..." correctly. 

3. Generalizing too far: 

I'm involved in designing a specification language for Ada programs.
It permits you to say things like (*), but not to state any other
kinds properties of the value of comp upon exceptional exit.
Naturally, we want the class of permitted invariant properties to be
as general as possible (so long as we can still reason about them
easily).  Under Ada's rules, we're going too far if we permit the
invariant to be a joint property of two writable parameters, e.g. (for
the case in which composite_type is an array type (or, in the second
case, an array type with discrete components))

    if comp1 and comp2 are permutations of one another upon entry,
    then they are still permutations of one another upon exceptional
    exit

or

    the lexicographic ordering of comp1 and comp2 is the same on
    exceptional exit as it was on entry

For specifications like these, we can safely pretend that comp1 and
comp2 are passed by reference only if we are entitled to assume that
they're passed by the same mechanism.  

Hence my question.


David Guaspari
oravax!davidg@cu-arpa.cs.cornell.edu
davidg%oravax.uucp@cu-arpa.cs.cornell