comp.lang.ada
 help / color / mirror / Atom feed
From: Geoff_Mendal@UMICH-MTS.MAILNET
Subject: Re: Procedures as arguments
Date: Tue, 22-Oct-85 19:02:24 EDT	[thread overview]
Date: Tue Oct 22 19:02:24 1985
Message-ID: <964133@UMich-MTS.Mailnet> (raw)

>This may seem a naive question, since at first look it seems impossible:
>can I (in Ada) pass the name (address) of a procedure to another procedure
>to be executed by that called procedure?  My goal is to have a general
>procedure that will call the supplied procedure until certain well-defined
>conditions occur, then return to the original caller.  It is trivial to do
>in C, but I cannot find anything comparable in Ada.  Thanks for any help.

Perhaps a generic subprogram with a formal subprogram parameter will
accomplish what you want. Consider the following simple example:

  generic
    with procedure Supplied_Procedure;
  procedure General_Procedure;
  . . .
  procedure General_Procedure is
  begin
    -- perhaps do something here
    Supplied_Procedure;
    -- perhaps do something here
  end General_Procedure;

All you need to do is instantiate the General_Procedure with the name of
a "supplied" procedure which you wish the General_Procedure to call. For
example, the following instantiation of General_Procedure will cause
"Hello" to be printed by a "supplied" procedure.

  with General_Procedure,
       Text_Io;
  procedure Main is
    procedure Print_Hello is
    begin
      Text_Io.Put_Line("Hello");
    end Print_Hello;

    procedure My_General_Procedure is new General_Procedure(Print_Hello);
  begin
    My_General_Procedure;
  end Main;

For simplicity, the above example assumes neither General_Procedure nor its
formal subprogram parameter pass any parameters. Passing parameters can also
be done, but the parameters of a generic formal subprogram must match those
of the actual subprogram. Hence, one can only use the above method to "pass"
subprograms that match the generic formal subprogram's parameter profile.

If generics don't do what you want, there might be another way, using
address clauses. I DO NOT ADVOCATE THIS METHOD. In fact, the ARM states that
doing so makes a program erroneous [ARM 13.5(8)]. Address clauses need not
even be implemented. With this in mind, consider the following:

  with system;
  procedure General_Procedure(Some_Procedure_Address : in System.Address) is
    procedure Supplied_Procedure;
    for Supplied_Procedure use at Some_Procedure_Address;
  begin
    -- perhaps do something here
    Supplied_Procedure;
    -- perhaps do something here
  end General_Procedure;
  . . .
  with General_Procedure,
       Text_Io;
  procedure Main is
    procedure Print_Hello is
    begin
      Text_Io.Put_Line("Hello");
    end Print_Hello;
  begin
    General_Procedure(Print_Hello'Address);
  end Main;

I doubt that this method would ever work in practice. I have yet to find an
implementation that will even compile/execute this second (erroneous) method
without blowing up (maybe that's an omen).

Geoff Mendal, Stanford U.

             reply	other threads:[~1985-10-22 23:02 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1985-10-22 23:02 Geoff_Mendal [this message]
  -- strict thread matches above, loose matches on Subject: below --
1985-10-28 19:26 Procedures as arguments Stavros Macrakis
1985-10-22 20:39 prindle
1985-10-22 14:04 Walt Lazear
1985-10-24 22:16 ` Berlen_Oronzo
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox