comp.lang.ada
 help / color / mirror / Atom feed
From: rjh@cs.purdue.EDU (Bob Hathaway)
Subject: Re: Procedure types and dynamic binding
Date: 9 Jan 89 20:19:55 GMT	[thread overview]
Message-ID: <5804@medusa.cs.purdue.edu> (raw)
In-Reply-To: 4046@hubcap.UUCP

> In more complicated examples parameterizable operations for each Adt 
> instance could simplify the program considerably, such as by avoiding
> nested case statements.
>
Bill Wolfe responds:
>     But you've designed your ADT to handle only two types of printing
>     situations: SHORT_PRINT and LONG_PRINT (or at least this would seem
>     to be the case to anyone who takes your generic parameter structure
>     at face value).  What we REALLY want is for ANY type of printing
>     operation to occur, depending on the user's needs, which we cannot
>     forecast in advance.  But now look at the trap we've walked into:
>     we must provide MAKE_*_PRINT, where * represents an indefinite set
>     of cases.  We now see that our old friend, the case statement, is
>     not gone; it has simply taken on a new form. 
>

This is not entirely correct, since I commented another more general solution.
It is possible to parameterize the Adt with a generic MAKE_PRINT_PROCEDURE
as described in the comment which I'll repeat below.  This is accomplished
with a nested generic subprogram declaration in the visible part of the 
package specification allowing any visible type compatible procedure
to be passed to a "MAKE_PRINT_PROCEDURE".  This satisfies the constraint 
above by dynamically assigning the generic parameter to the internal 
procedural variable, if desired.
--
-- MAKE_SHORT_PRINT
--
--    Set procedural instance variable PRINT_ELEMENT to parameter
--    SHORT_PRINT so subsequent calls to PRINT by this instance
** Please Note ***
--    will invoke SHORT_PRINT.   Could also use a generic
--    subprogram parameter to supply a new print routine, or ...
***           ***
--    Parameters SHORT_PRINT and LONG_PRINT will have to be assignment
--    compatible with type PRINT_PROCEDURE_TYPE;
--

Also, it appears unrestricted pointers to subprograms, if thats what
you propose, would provide dynamically checked operations at runtime.
This mechanism is more powerful than statically checked procedural
variables.  Analogous to the use of generics and arbitrary polymorphism
where generics should be used whenever applicable and arbitrary polymorphism
with care, procedural variables should be used whenever applicable and
unrestricted pointers with care.  Since the previous example used generics,
corresponding procedural variables are applicable and provide an
elegant general solution.  I'll let Harland, if we're lucky enough to
have him read this, provide an example with arbitrary polymorphism
and unrestricted pointers:-)

Mats Weber writes:
>I think there is one good reason why procedure types should not be included in
>the Ada language: A secure implementation of procedure types must restrict
>their use to global procedures (that is, procedures that are not nested in
>other procedures or tasks), as is the case in Modula-2.
>
>Such a rule would violate the uniformity of the language (in Ada 83, anything
>can be declared in any declarative region, no matter how deeply nested the
>region is).

I'm aware of this argument but after several years of Modula-2 programming
this simply doesn't cause concern.   This is like the "else" construct
argument where disambiguating rules must be applied to allow if-then-else
constructs.  It is not consequential that rules must be applied to 
grammars, as with the else construct, or that semantic rules must be applied
to objects, as with procedural variables.  As a programmer, the only 
procedures I would assign to a procedural variable are top-level procedures
and since the nested case doesn't occur, I don't see a problem.  I agree 
constraints restricting orthogonality should only be applied when necessary 
but procedural variables present such a case in a stack based-model since
assignment could allow access to inactive environments global to a procedure
and the assignment restriction to top-level procedures is safe, appropriate,
and general.

Also, the rule for disallowing procedural variable assignment to nested 
subprograms which are passed as generic subprogram parameters must still 
be statically checked.

Bill Wolfe writes:
>     We now see that our entire approach to the problem is wrong.  We must
>     provide a method whereby our user can access his/her stacked objects,
>     and allow the user to implement any arbitrary print procedure.  But,
>     you object, the user must be given some sort of standard print procedure
>     which can be used as a default!  And so he/she must; we achieve this
>     by supplying in a utilities package the following:
>

But this is the old scheme again since the Adt cannot be parameterized at
any point in the program and allow a single subsequent operation to invoke 
the desired subprogram.  This sheme requires the work of writing
an output procedure inline.  Yes, the user can call MY_PRINT (STACK .POP ...)
for maximum flexibility as they can with the presented example but
this was not desired.  The output example was kept simple to abstract the 
desired method and real applications are easy to construct, as shown 
below.


>     Still waiting for a situation in which procedural variables should 
>     be used in order to formulate an intuitively natural solution...

Graphical environments provide one example where dynamically parameterizable
objects can be of great assistance.  One could parameterize graphical objects 
with operations for displaying output, windows, etc., with each instance using
the correct subprogram to implement its display operations.

                                            Bob Hathaway
                                            rjh@purdue.edu 

  reply	other threads:[~1989-01-09 20:19 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1988-12-30 21:42 Procedure types and dynamic binding Erland Sommarskog
1988-12-31 17:46 ` Bob Hathaway
1989-01-05 10:02   ` William Thomas Wolfe,2847,
1989-01-07 18:05     ` Bob Hathaway
1989-01-07 21:21       ` William Thomas Wolfe,2847,
1989-01-08  1:49         ` Bob Hathaway
1989-01-08 19:01           ` William Thomas Wolfe,2847,
1989-01-08 23:10             ` Bob Hathaway
1989-01-09  1:47               ` William Thomas Wolfe,2847,
1989-01-09 20:19                 ` Bob Hathaway [this message]
1989-01-10  3:01                   ` William Thomas Wolfe,2847,
1989-01-10  3:06                   ` Bob Hathaway
1989-01-10 19:11                     ` William Thomas Wolfe,2847,
1989-01-11  2:08                       ` Bob Hathaway
1989-01-11 14:24                         ` William Thomas Wolfe,2847,
1989-01-11 17:51                           ` Barry Margolin
1989-01-11 22:54                             ` William Thomas Wolfe,2847,
1989-01-12 13:57                               ` Robert Firth
1989-01-12 19:09                                 ` William Thomas Wolfe,2847,
1989-01-14  0:46                                 ` Scott Moody
1989-01-15 18:28                                   ` William Thomas Wolfe,2847,
1989-01-24  4:07                                   ` Paul Stachour
1989-01-12  0:58                             ` William Thomas Wolfe,2847,
1989-01-12  6:12                               ` Barry Margolin
1989-01-11 14:48                         ` Submitting Ada 9X revision requests William Thomas Wolfe,2847,
1989-01-11  2:10                       ` Procedure types and dynamic binding Bob Hathaway
1989-01-05  7:38 ` William Thomas Wolfe,2847,
  -- strict thread matches above, loose matches on Subject: below --
1989-01-06 23:04 Erland Sommarskog
1989-01-07 22:20 ` William Thomas Wolfe,2847,
replies disabled

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