Path: utzoo!utgpu!water!watmath!clyde!att!ucbvax!wb3ffv.UUCP!uucp
From: uucp@wb3ffv.UUCP
Newsgroups: comp.lang.modula2
Subject: Warning From uucp
Message-ID: <8808182358.AA14713@wb3ffv.UUCP>
Date: 20 Aug 88 02:00:48 GMT
Sender: daemon@ucbvax.BERKELEY.EDU
Reply-To: Info-Modula2 Distribution List 
Organization: The Internet
Lines: 174

We have been unable to contact machine 'sarin' since you queued your job.

        sarin!mail eric   (Date 08/17)
The job will be deleted in several days if the problem is not corrected.
If you care to kill the job, execute the following command:

        uustat -ksarinN0ed9

        Sincerely,
        wb3ffv!uucp

#############################################
##### Data File: ############################
>From aplcen!mimsy!rutgers!ucf1vm.bitnet!INFO-M2  Wed Aug 17 13:19:21 1988 remot
   e from wb3ffv
Received: by wb3ffv.UUCP (Smail-2.5)
        id AA02416; 17 Aug 88 13:19:21 EDT (Wed)
Received: by mimsy.UMD.EDU (smail2.5)
        id AA00907; 17 Aug 88 04:59:56 EDT (Wed)
Received: from AJPO.SEI.CMU.EDU by rutgers.edu (5.59/1.15)
        id AA11676; Wed, 17 Aug 88 04:52:32 EDT
Received: from cunyvm.cuny.edu by decwrl.dec.com (5.54.5/4.7.34)
        id AA23497; Wed, 17 Aug 88 01:22:17 PDT
Received: from BITNIC.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id
    5077; Tue, 16 Aug 88 14:29:35 EDT
Received: by BITNIC (Mailer X1.25) id 4157; Tue, 16 Aug 88 14:31:16 EDT
Return-Path: 
Received: from ucbvax.berkeley.edu by jade.berkeley.edu (5.54 (CFC
          4.22.3)/1.16.18B) id AA19041; Tue, 16 Aug 88 02:30:21 PDT
Received: by ucbvax.Berkeley.EDU (5.59/1.30) id AA06462; Tue,
          16 Aug 88 01:33:05 PDT
Received: from USENET by ucbvax.Berkeley.EDU with netnews for
          info-m2@ucf1vm.bitnet (info-modula-2@ucf1vm.bitnet) (contact
          usenet@ucbvax.Berkeley.EDU if you have questions)
Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742
References: <79500004@p.cs.uiuc.edu>, <79500010@p.cs.uiuc.edu>
Message-Id: <13019@mimsy.UUCP>
Date:         Tue, 16 Aug 88 07:32:11 GMT
Reply-To: Info-Modula2 Distribution List 
Sender: Info-Modula2 Distribution List 
Comments:     Warning -- original Sender: tag was
              editor%ucf1vm.BITNET@JADE.BERKELEY.EDU
From: Chris Torek 
Subject:      Re: C v.s. Modula II
Comments: To: info-modula-2@ucf1vm
To: "(no name)" 

In article <79500010@p.cs.uiuc.edu> gillies@p.cs.uiuc.edu writes:
>I will elaborate, since I think parts of my posting were
>misunderstood:

(Some were; some I answered just a few minutes ago)

>Often, for(;;) loops are written with *no body*, and adding additional
>commands can require major restructuring of the loop.
>/* Here is a way to copy a string */
>for(p=charbuf, q=copybuff; *p++=*q++;);
>
>/* What if I wanted to debug this, and print characters as they were copied? */
>for(p=charbuf, q=copybuff; *q;) {
>       putchar(*p++=*q++);             /*  */
>}

Well, you *could* write

        for (p = charbuf, q = copybuf; putchar(*p++ = *q++););

but all of these examples are grotesqueries.

>Notice how I had to restructure the looping condition to make this
>change.  Things can be much worse with a more complicated loop.

I will agree that if you are going to revise a loop you must look
at the `for' part as well as the body.  So what?  If I am going to
revise a

        # unspecified generic odd-looking fully-bracketed language:
        for i from 31 to 97 do a[i] <- f(i); rof;

into a

        for i in a[] do a[i] <- f(i); rof;

I will have to look at the `for' part as well as think about what
is going on.

Certainly C's for statement can be abused, but I think the flexibility
it provides is worth it---look at the number of syntaxes for the Mesa
FOR statement to see what I mean.

>... callback procedures ... How can I express something like this
>in C?

>dict: Dictionary.Handle;               -- global variable
>
>PrintDictionary: PROCEDURE = {
>  wh: Window.Handle := Somewhere.GetAWindowHandle[];     -- used in callback
>  -- A CallbackProc is a PROC[a:LONG STRING] RETURNS[BOOLEAN];
>  ShowName: Dictionary.CallbackProc = {
>    Put.String[wh, a];
>    Put.CR[wh];
>    RETURN[TRUE]
>  }
>  Dictionary.Enumerate[dict, ShowName];
>}
>
>I call the Dictionary.Enumerate[] procedure, and it repeatedly makes
>call to the ShowName procedure. FURTHERMORE, from within the ShowName
>procedure, I can access & change the variables global to
>PrintDictionary (wh, the window handle).  This is crucial if you want
>to get something done, in a type-safe manner.  I don't think C++'s
>pointer parameters cut the mustard.....

Yes they do, but I will write this in C, rather than in C++.  (C++ can
make short work of it by using classes, so that is no fun at all.  It
is interesting, though, to note that either Dictionary or Window must
be a subclass of the other to do it.  That problem vanishes with
multiple inheritance, coming soon to a C++ compiler near you :-) .)

        /* typedef int boolean; */ /* in some header; or just use int */

        Dictionary_Handle dict;         /* global, as before */

        struct communique {
                Window_Handle wh;
                /*
                 * any other variables local to PrintDictionary
                 * that might be needed/modified in ShowName
                 * go here too.
                 */
        };

        static boolean ShowName(void *private_data, char *a) {
                struct communique *vars = private_data;

                Put_String(vars->wh, a);
                Put_CR(vars->wh);
                return TRUE;
        }

        void PrintDictionary() {
                struct communique vars;

                vars.wh = Somewhere_GetAWindowHandle();
                Dicationary_Enumerate((void *)&vars, dict, ShowName);
        }

>Callback procedures are a nice way of supporting abstract enumeration
>when the language lacks something like CLU's explicit enumerators.

Yes, they are.  While the above lacks the elegance of Mesa's syntax, it
works; it is portable; it can do everything the Mesa version can do.
Moreover, it does not require displays.  (One can simplify the above
example, eliminating the structure entirely, since there is only a
single pointer variable communicated.  In the general case, though, the
structure is required.)

Personally, I would rather use the elegant syntax.

Note that uplevel variable accesses can always be transformed into
references via an opaque pointer, as I did it above, at no cost to
those routines that do not participate.  The compiler must be able to
tell which procedures have such references, which which procedures call
such procedures, which procedures call procedures that . . ., etc.  A
better method, which does not require recursive inference, is to
generate new functions on the fly that automatically provide the
appropriate hidden argument.  This can be done with some cooperation
from the hardware and the O/S.  David Chase recently stirred up a fuss
in comp.lang.c by mentioning this technique.  (Search for the subject
`partial application', but be forewarned: it quickly evolved into a
debate about self-modifying code.)
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris@mimsy.umd.edu     Path:   uunet!mimsy!chris