🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.modula2
Article #4787

Re: procedure variables (ca. 80 lines)

#4787
From: Kai Henningsen
Date: Tue, 25 Apr 1989 18:06
71 lines
3654 bytes
Well, my friendly Pascal Compiler (Turbo Pascal 5.0) does this in
exactly the same way as Wirth defines it for Modula-2, so it has
to be doable ...

The reasons behind the various do's and dont's are as follows:

1. Why not allow "standard procedures"? Simple: the compiler writer
   may decide to implement these not like ordinary procedures, but
   in some special way. Thus, they have no address that could be
   stored in a procedure variable.
   For example, try to imagine the following:
    v: PROCEDURE (ARRAY OF CHAR) : CARDINAL;
    v := SIZE;
   Somewhat problematic ...

2. Why not allow local procedures? Simple: because it's NOT simple :-)
   Really: This is part of ISO Pascal. Up to now, I have seen one
   implementation, in Mac MPW Pascal. I looked at the code. Now I know
   why you don't want to implement it ...
   It's like this: If you have a local Procedure, then you obviously
   have to save the static calling chain. Most Compilers do this by
   passing, as an invisible parameter, a pointer to the procedure's
   parent's stack frame. In the case of a procedure variable, that means
   you have to put this pointer in the variable, too. BUT a global
   procedure does not expect to get this parameter! So, you end up
   generating code like this:

   IF procvar.stackframe#NIL THEN push(procvar.stackframe) END;
   call(procvar.adr);

   Yechhh!!
   By the way, we have another problem here. Suppose the following:

   VAR v: PROCEDURE;
   PROCEDURE A;
     PROCEDURE B;
     BEGIN END B;
   BEGIN v:=B; END A;

   BEGIN A; v(); END;

   Where's my stackframe gone to???
   There are two approaches to this problem:
   First, ISO Pascal. We do not allow procedure variables, except as
   parameters. Obviously, the stack frame will thus be there.
   Second, Lisp. The stack frame is an (invisible) Lisp object.
   As long as there exists a procedure variable pointing to X,
   the garbage collector will not kill the stack frame for that
   invocation of X's parent. Obviously, stack frames are heap objects
   chained with pointers. Nice but SLOWWWW.

   Of course, there is always a third way: don't allow this. Modula-2.

3. Now what about non-exported global procedures?
   Well, what about it? Non-exported procedures are exactly like exported
   ones, except the module importer does not know these by name. Since
   he does not know the name of any procedure called via a procedure
   variable either, that shouldn't hurt.
   Of course, the implementor may choose to optimize those procedures on
   the grounds that they will only be used from places known in advance.
   So does Turbo Pascal 5.0. But, if they are used with procedure
   variables at all (wether exported or not), this must break down.
   What do we do? Either, we restrict optimizing in cases where a
   procedure is exported or assigned to a procedure variable, or we
   allow the user to decide on optimizations (remember compiler
   directives?), but allow export & assignment only on non-optimized
   procedures. (TP5 really does a mix of the two.)

Kai

onm64 @ dmswwu1a . bitnet
Technical Details
Message-ID: <INFO-M2%89042509041995@UCF1VM>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!DMSWWU1A.BITNET!ONM64

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!DMSWWU1A.BITNET!ONM64
From: ONM64@DMSWWU1A.BITNET (Kai Henningsen)
Newsgroups: comp.lang.modula2
Subject: Re: procedure variables (ca. 80 lines)
Message-ID: <INFO-M2%89042509041995@UCF1VM>
Date: 25 Apr 89 18:06:28 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Reply-To: Modula2 List <INFO-M2%UCF1VM.bitnet@jade.berkeley.edu>
Organization: The Internet
Lines: 71
X-Unparsable-Date: Tue, 25 Apr 89 14:07:05 MES