======================================================================= 1 ===
Date:    1 Feb 93 18:06:15 GMT
From:    moss@cs.cmu.edu (Eliot Moss)
Subject: status of GNU Modula-3

Well, we said we'd try to have an alpha release of GNU Modula-3 (gm3) by the
end January, and since it's now February I thought I should post and let you
know that we didn't make it.

Here are the features we know we have yet to handle for the alpha release:

- SUBARRAY: almost done, but initial attempt had inappropriate data structures
    in the compiler for nested open arrays, so it had to be redone
- REVEAL: this requires some external support for enforcing the langauge rules
    across compilations; all designed and into implementation
- FLOAT(): trivial, just not done yet
- nested procedures: requires only front-end work since static nesting is
    supported in gcc 2.0 and higher, just not done yet

Our strategy has been to attempt compiling the various files in libm3 and fix
whatever is missing/broken until those files all compile. We will then move on
to other SRC libraries using the same approach. Naturally there may be
features other than the four listed above that need some work, but these four
must be taken care of before other significant ones are uncovered. I note that
exception handling and gc are working fine.

Features that the alpha release will definitely lack are: complete support for
threads (no forking, but mutexes, conditions, and LOCK will be partially
implemented so that you can use thread-safe code), complete gdb support (in
particular, we're not emitting the symbol table info needed to access
variables at run time, but breakpoints and stepping by source line number will
work), full support for the float libraries, and extended floats (not yet
supported by gcc). The alpha release will be for the VAX only, but there are
some folks who will get the code so they can start looking at it and perhaps
start porting efforts to other architectures.

Why is this all taking so long? We are working with minimal staff -- a half
time professional programmer and a half time graduate student. Also, the
programmer's other responsibilities recently and unexpectedly demanded about a
month of full-time work (which we owe them). So, with regrets, we now predict
alpha release in mid-March. We also don't want to release something that will
waste too much testers' time, so we don't want to push it out the door too
early. However, our testing, beyond whether something compiles without errors,
is likely to be pretty cursory -- we'll be relying on the alpha testers to
find the more subtle bugs in generated code.

Alpha testers can help us some, though. It would be helpful to have priorities
from you of which packages or language features you really MUST have, which
are very desirable but not absolute requirements, and which you don't care
about right away.

We thank you all for your interest, patience, and support (especially SRC for
financial and other assistance!) --				Eliot Moss
--

J. Eliot B. Moss, Associate Professor	Visiting Associate Professor
Department of Computer Science		School of Computer Science
Lederle Graduate Research Center	Carnegie Mellon University
University of Massachusetts		5000 Forbes Avenue
Amherst, MA  01003			Pittsburgh, PA  15213-3891
(413) 545-4206, 545-1249 (fax)		(412) 268-6767, 681-5739 (fax)
Moss@cs.umass.edu			Moss@cs.cmu.edu


======================================================================= 2 ===
Date:    1 Feb 93 17:56:19 GMT
From:    mlo@dcs.qmw.ac.uk (Mike Osborne)
Subject: Network Interface Example

I recently downloaded the Network interface, but there were no example programs
So I've written one....

These programs use the Network interface posted recently by Norman.
I wanted to test the interface, so I wrote a small client and server, which
together provide an addition service.

They are not very well written (I haven't attempted to handle many exceptions,
and the port/hostname are hardcoded)
But they may give some idea of how the network interface can be used. 

If you have any more examples using this library, post them!  

Norman, if you are reading this, is this the right way to use the interface?
Do you have any example programs?

Mike


Delete everything above including this line 
#!/bin/sh
#	This is a shell archive.
#	Run the file through sh to extract its contents.
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	ArithClient.m3
#	ArithServer.m3
# This archive created: Mon Feb  1 17:50:03 1993
cat << \SHAR_EOF > ArithClient.m3
MODULE Main;

IMPORT Network,Fmt,Scan,Rd,Wr,Stdio;

VAR netreader: Network.T;
VAR first,second,response: INTEGER;
BEGIN
(* connect to the server *)
  Wr.PutText(Stdio.stdout,"Attempting to connect to the Arithmetic Server\n");
  netreader := Network.Connect("hostname",5041); (* some arbitary port *)
  Wr.PutText(Stdio.stdout,"Got connection\n\n\n"); 

  LOOP
(* Get some numbers to send to the server *)
    Wr.PutText(Stdio.stdout,"Enter the first number :\n");
    Wr.Flush(Stdio.stdout);
    first := Scan.Int(Rd.GetLine(Stdio.stdin));
    Wr.PutText(Stdio.stdout,"Enter the second number :\n");
    Wr.Flush(Stdio.stdout);
    second := Scan.Int(Rd.GetLine(Stdio.stdin));

(* Send the numbers to the server *)
    Wr.PutText(netreader.wr,Fmt.Int(first)); 
    Wr.PutText(netreader.wr,"\n");
    Wr.Flush(netreader.wr);
    Wr.PutText(netreader.wr,Fmt.Int(second));
    Wr.PutText(netreader.wr,"\n");
    Wr.Flush(netreader.wr);
    response := Scan.Int(Rd.GetLine(netreader.rd)); (* Read back the response *
)

(* Display the result *)
    Wr.PutText(Stdio.stdout,"The result of addition is: ");
    Wr.PutText(Stdio.stdout,Fmt.Int(response));     (* and display it *)
    Wr.PutText(Stdio.stdout,"\n\n");
  END
END Main.

SHAR_EOF
cat << \SHAR_EOF > ArithServer.m3
(* Example arithmetic server using the networking interface *)
(* Mike Osborne (mlo@dcs.qmw.ac.uk) *)

MODULE Main;

IMPORT Network,Thread,Fmt,Scan,Rd,Wr,Stdio;

TYPE AddClosure = Thread.Closure OBJECT
		      connection : Network.T 
		    OVERRIDES 
		      apply := Add 
		  END;

TYPE ServerLoopClosure = Thread.Closure OBJECT
			   serviceport : Network.Server
			 OVERRIDES 
			   apply := ServerLoop
			 END; 


VAR server: Network.Server;

PROCEDURE Add(self: AddClosure):REFANY RAISES {} =
VAR first,second,result: INTEGER;
BEGIN
  LOOP 
    TRY
      first := Scan.Int(Rd.GetLine(self.connection.rd));
      second := Scan.Int(Rd.GetLine(self.connection.rd));

    (* This is where the server does its "work" *)
      result := first + second;

    (* Send the result to the client *)
      Wr.PutText(self.connection.wr,Fmt.Int(result)); 
      Wr.PutText(self.connection.wr,"\n");
      Wr.Flush(self.connection.wr);
    EXCEPT
      | Rd.EndOfFile => EXIT;
    END;
  END;
RETURN (NIL);
END Add;


(* This procedure loops calling Network.Accept repeatedly. *)
(* Each time Network.Accept returns, a new thread is forked to service the *)
(* connection. It is intended to be run as a thread which will allow the *)
(* server process to continue *) 
PROCEDURE ServerLoop(self : ServerLoopClosure):REFANY RAISES {} =
VAR connection: Network.T;
BEGIN
  WHILE (TRUE) DO 
    connection := Network.Accept(self.serviceport);
    EVAL Thread.Fork(NEW(AddClosure,connection := connection));
  END;
END ServerLoop;


BEGIN
  (* create a server on port 5041 *)
  server := Network.Serve(5041);
  (* create a thread to handle incoming connections *)
  EVAL Thread.Fork(NEW(ServerLoopClosure,serviceport := server));
 
  (* This can be an empty statement, if the server is not intended to do *)
  (* anything other than provide the arithmetic service. Otherwise, we could *)
  (* add internal server monitoring/administration facilities here *) 
  REPEAT UNTIL Rd.GetChar(Stdio.stdin) = 'q';
END Main.
SHAR_EOF
#	End of shell archive
exit 0

--

Michael Osborne	                 Internet:  mlo@dcs.qmw.ac.uk
 Computer Science Department     JANET:     mlo@uk.ac.qmw.dcs
  Queen Mary & Westfield College  
   Mile End Road                   Telephone: +44 71-975 5244/5/9
    LONDON, E1 4NS, UK              Fax:       +44 81-980 6533


======================================================================= 3 ===
Date:    Mon, 1 Feb 1993 19:24:28 GMT
From:    schaeppe@nessie.cs.id.ethz.ch (Christian Schaepper)
Subject: RFD: comp.lang.oberon

              R E Q U E S T   F O R   D I S C U S S I O N
              -------------------------------------------

This is a Request For Discussion (RFD) for the creation of a newsgroup
for the discussion of issues regarding the Oberon language and system.

GROUP NAME
	comp.lang.oberon

STATUS
	unmoderated

CHARTER
	comp.lang.oberon (unmoderated) will be a newsgroup for discussion
	of all types of issues regarding the Oberon language and system.

RATIONALE
	Due to historical reasons, topics related to Oberon are currently
	being discussed in comp.lang.modula2. Not everyone may be aware of
	this fact and thus miss the discussion related to Oberon. Further,
	readers of comp.lang.modula2 might not like the "abuse" of their
	newsgroup. The creation of comp.lang.oberon solves both problems.

BACKGROUND
	Oberon is really three things:
	- the name of a project started by Proff. N. Wirth and J. Gutknecht
	  (both at ETH Zurich) with the goal of developing a modern and
	  portable operating system for personal workstations
	- a general-purpose programming language (the successor of Modula-2)
	  with type extension as its principal new feature 
	  (The programming language Oberon-2, designed to make object
	  oriented programming easier, is a true extension of Oberon)
	- an extensible operating system, complete with a novel user
          interface and associated software tools

	The Oberon system (including the Oberon compiler) is available as
	freeware via anonymous ftp from neptune.inf.ethz.ch (129.132.101.33)
	(directory 'Oberon') for the following machines:
	IBM PC (386 or better), Macintosh II (Apple), SPARC (Sun),
	DECstation/3100 and 3500, RS/6000 (IBM)
	(You'll also find some docu (including language reports) there)

SCHEDULE
	This RFD was issued on February  1 and will last for 30 days. If
	this RFD is approved, a CFV will be issued on March 4, and
	the voting period will end at 11:59 (MET), March 25.
-- 
+-----------------------------------------------------------------------------+
| Christian Schaepper, Zurich, Switzerland      schaeppe@nessie.cs.id.ethz.ch |
|                  DECnet (HEPNET/SPAN): EZINFO::SCHAEPPER (57413::SCHAEPPER) |
+-----------------------------------------------------------------------------+


======================================================================= 4 ===
Date:    Mon, 1 Feb 93 21:12:23 GMT
From:    norman@flash.bellcore.com (Norman Ramsey)
Subject: example of Network interface

I didn't post an example program that uses the Network interface
because the only real example I have is ugly, and I didn't want to
spend the time making it clean.  Here's a bowdlerized version, with
lots of the complexity and ugliness removed.  It should all be
obvious, except perhaps what to do with UnixError.E.

I show only the server; the client side is uninteresting.
So uninteresting, in fact, that for a while I used `telnet' as the
client. 

Norman



MODULE Serve EXPORTS Main;
IMPORT ...

VAR server : Network.Server;

PROCEDURE Usage() = BEGIN ... END Usage; (* print msg and exit *)

PROCEDURE Args() RAISES {UnixError.E} =
VAR i := 1;
BEGIN
  <<scan options and point [[i]] at first argument that is not an option>>
  CASE Params.Count - i OF
  | 0 => server := Network.Serve();		(* any port in a storm *)
  | 1 => TRY    server := Network.Serve(CScan.Int(Params.Get(i)));
						(* port named on command line *
)
         EXCEPT Scan.BadFormat => Usage();
         END;
  ELSE Usage();
  END;
END Args;

PROCEDURE Go() RAISES {UnixError.E} =
BEGIN
  Args();
  Log.Shout("Serving host %s port %s...", 
            Network.Host(server), Fmt.Int(Network.Port(server)));
  LOOP
    Thread.Fork(NEW(Conn, net := Network.Accept(server), name := "Anonymous"));
  END;
END Go;

TYPE 
  Conn = Thread.Closure OBJECT
           name : TEXT;
           net : Network.T;
         OVERRIDES
           apply := Listen;
         END;

PROCEDURE Listen(conn:Conn):REFANY =
BEGIN
  TRY
    LOOP
      Command.Invoke(conn, Rd.GetLine(conn.net.rd), Cmds, Unknown);
    END;
  EXCEPT
  | Rd.Failure     => Log.Shout("lost connection to " & conn.name);
  | Rd.EndOfFile   => Log.Shout(conn.name & " closed connection");
  | Thread.Alerted => Log.Shout(conn.name & " thread alerted");
  END;
  Rd.Close(conn.net.rd);
  Wr.Close(conn.net.wr);
  RETURN NIL;
END Listen;

BEGIN
  TRY
    Go()
  EXCEPT UnixError.E(rec) => 
    Log.Shout("serve: %s (%s)", rec.msg, Fmt.Int(rec.errno));
  END;
END Serve.


======================================================================= 5 ===
Date:    Tue, 2 Feb 93 02:26:41 GMT
From:    jdd@src.dec.com (John DeTreville)
Subject: Porting the new garbage collector

As you may know, the garbage collector in the new Modula-3 system is
incremental and generational, depending internally on VM protection to
read-protect or write-protect the heap.

The details of using VM protection differ greatly between versions of
Unix.  In the initial release, I implemented the necessary internal
support only for DECstations running Ultrix, since that's what I use.
On other architectures, the collector defaults to ordinary old
non-generational stop-&-copy behavior, just like the previous one.

Thanks to David Goldberg of PARC, there will soon be a complete
collector port to the SPARC under SunOS.  You'll get smaller
interruptions of service and less time spent in the collector, as in
the Ultrix version.

If you're brave, you might want to port the low-level VM support to
your own favorite machine; ask me for information.  It should be
possible to port the collector to most modern architectures and
Unixes.  You'll have to know Section 2 of your Unix manual quite
thoroughly; see runtime/src/DS3100/RTHeapDepC.c for why.

Cheers,
John


======================================================================= 6 ===
Date:    31 Jan 93 03:58:03 GMT
From:    awenn@matilda.vut.edu.au (Andrew Wenn)
Subject: Modula3 and Acorn RISCiX

Is anyone else in this group using Modula3 on an Acorn RISCix machine? If so
I would like to hear from you.

Andrew.



---------------------------------------------------------------------------
Andrew Wenn          Victoria University of Technology
                     Footscray Campus.
                     awenn@matilda.vut.edu.au

                     phone 03 688 4342
                     fax   03 688 4804
---------------------------------------------------------------------------


======================================================================= 7 ===
Date:    Tue, 02 Feb 93 17:45:27 -0800
From:    heydon@src.dec.com
Subject: Re: Inheritance and opaque types.


mjordan@src.dec.com (Mick Jordan) wrote:
> There is no language-level support for allowing a subtype
> accces to hidden fields, but denying other clients access.
> The convention is to place the half-hidden fields in a separate
> interface, and publicise that this is intended for subtype
> clients only. You can use partial revelations to arrange this.

He then gave the following canonical example (which I have corrected 
slightly): 

INTERFACE Foo;
TYPE T <: Public;
  Public = OBJECT
    (* public fields *)
  METHODS
    (* public methods *)
  END;
END Foo.

INTERFACE FooRep;
IMPORT Foo;
TYPE T = Foo.Public OBJECT (* semi-private fields *) END;
REVEAL Foo.T <: T;
END FooRep.

MODULE Foo;
IMPORT FooRep;
REVEAL T = FooRep.T OBJECT
    (* private fields *)
  OVERRIDES
    (* method implementations *)
  END;
BEGIN
END Foo.

In this scheme, we have "Foo.T <: FooRep.T <: Foo.Public". A client 
that imports only "Foo" sees only the public fields, but a client 
that imports both "Foo" and "FooRep" sees both the public and semi-private 
fields. Of course, inside the "Foo" module, the private fields are 
visible as well.

With this scheme, the order of the fields within a "Foo.T" is: public, 
semi-private, and then private; so the public fields are a prefix 
of the object. We can arrange for the semi-private fields to be a 
prefix instead: 

INTERFACE Foo;
TYPE
  Private <: ROOT;
  Public = Private OBJECT
    (* public fields *)
  METHODS
    (* public methods *)
  END;
  T <: Public;
END Foo.

INTERFACE FooRep;
IMPORT Foo;
REVEAL Foo.Private = OBJECT (* semi-private fields *) END;
END FooRep.

MODULE Foo;
IMPORT Foo, FooRep;
REVEAL T = Public OBJECT
    (* private fields *)
  OVERRIDES
    (* method implementations *)
  END;
BEGIN
END Foo.

With this scheme, we have "Foo.T <: Foo.Public <: Foo.Private". The 
reason we might want the private fields in the prefix is to be able 
to reveal in the "FooRep" interface that a "Foo.Private" is a subtype 
of some other object type that we might want importers of "FooRep" 
to see. For example, we could have instead written:

INTERFACE FooRep;
IMPORT Foo;
REVEAL Foo.Private = MUTEX OBJECT (* semi-private fields *) END;
END FooRep.

This declares that "Foo.Private <: MUTEX", so clients that import 
both "Foo" and "FooRep" not only have access to both the public and 
semi-private fields of a "Foo.T", but they can also LOCK a "Foo.T" 
object as well.

In fact, the structure of the "Wr", "WrClass", "UnsafeWr" interfaces 
-- and their implementation in the "WrRep" module -- is somewhat 
similar to this scheme. See Chapter 6 of SPwM3. In particular, see 
the third and second paragraphs from the bottom of pg 143 of SPwM3 
for a description of how to leave room for extra fields in the prefix 
and/or suffix of an object.

- Allan

Allan Heydon					heydon@src.dec.com
DEC Systems Research Center			(415) 853-2142
130 Lytton Ave.					(415) 853-2104 (FAX)
Palo Alto, CA 94301



======================================================================= 8 ===
Date:    Wed, 03 Feb 1993 20:47:47 GMT
From:    bieman@CS.ColoState.EDU (james bieman)
Subject: Modula-3 compiler for PC's

I am looking for a Modula-3 compiler for PC's running MS Windows
or DOS.  We are currently using Modula-3 in an undergraduate software
engineering course and we have off-campus students (some in other states)
without access to the internet (for remote logins) who need to use
their PC's for assignments.  In this course, we do not use
any UNSAFE features.

I (and my students) will appreciate any helpful information.

Jim Bieman
-------------------------------------------------------------
James Bieman                   Email: bieman@cs.colostate.edu
Computer Science Department    Phone: (303)491-7096
Colorado State University      Fax: (303) 491-6639
Fort Collins, CO 80523

-- 
James Bieman                   Email: bieman@cs.colostate.edu
Computer Science Department    Phone: (303)491-7096
Colorado State University      Fax: (303) 491-2293
Fort Collins, CO 80523 


======================================================================= 9 ===
Date:    Wed, 03 Feb 1993 03:11:46 +1000
From:    Arthur@cswamp.apana.org.au (Arthur Marsh)
Subject: ARM 610 and garbage collection [was Help installing m3 on ARM]

On Tue 26 Jan at 23:39 Andrew Wenn wrote:

 AW> From: awenn@matilda.vut.edu.au (Andrew Wenn)

 AW> I am installing m3 on an ACORN machine using the ARM 
 AW> architecture and RISCiX.

Although of no help with your immediate problem, I noticed in the November 1992
issue of Byte on page 297:

"The ARM610 MMU lets you implement an efficient *concurrent* garbage collector
as a permanent background task".

Would this be of interest to somone implementing M3 on an ARM based
architecture?

 * Origin: Camelot Swamp MJCNA, Hawthorndene, Sth Australia (8:7000/8)



======================================================================= 10 ===
Date:    Fri, 5 Feb 93 00:34:00 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Modula-3 Frequently Asked Questions (FAQ)

Archive-name: Modula-3-faq
Last-modified: Feb 04 1993


		 Modula-3 Frequently Asked Questions
		 ===================================


What is Modula-3 ?

   The goal of Modula-3 is to be as simple and safe as it can be while
   meeting the needs of modern systems programmers.  Instead of
   exploring new features, we studied the features of the Modula
   family of languages that have proven themselves in practice and
   tried to simplify them into a harmonious language.  We found that
   most of the successful features were aimed at one of two main
   goals: greater robustness, and a simpler, more systematic type
   system.

   Modula-3 descends from Mesa, Modula-2, Cedar, and Modula-2+.  It
   also resembles its cousins Object Pascal, Oberon, and Euclid.

   Modula-3 retains one of Modula-2's most successful features, the
   provision for explicit interfaces between modules.  It adds objects
   and classes, exception handling, garbage collection, lightweight
   processes (or threads), and the isolation of unsafe features.


Is Modula-3 a superset of Modula-2 ?

   No; valid Modula-2 programs are not valid Modula-3 programs.  However,
   there is a tool to help convert Modula-2 programs to Modula-3.


Where can I get a description of Modula-3 ? 
   
   The definition of Modula-3 is contained in:

        System Programming with Modula-3
        Edited by Greg Nelson
        Prentice Hall Series in Innovative Technology
        ISBN 0-13-590464-1
        L.C. QA76.66.S87 1991

   also known as SPwM3.  Here is the table of contents:

        1. Introduction
        2. Language Definition
        3. Standard Interfaces
        4. An Introduction to Programming with Threads
        5. Thread Synchronization: A Formal Specification
        6. I/O Streams: Abstract Types, Real Programs
        7. Trestle Window System Tutorial
        8. How the Language Got its Spots

   Chapters 2 and 3 have been reprinted in Sigplan Notices, Volume 27,
   Number 8, August 1992, pp 15-42.

   Sam Harbison has written a more tutorial book about Modula3:

        Modula-3
        Samuel P. Harbison
        Prentice Hall, 1992
        ISBN 0-13-596396-6

Where can I get other information on Modula-3 ?

   There is a Usenet newsgroup, comp.lang.modula3.  The archives of
   that group are available via anonymous ftp from gatekeeper.dec.com
   in pub/DEC/Modula-3/comp.lang.modula3.  If you do not have
   access to Usenet, there is a relay mailing list; send a message to
   m3-request@src.dec.com to be added to it.

   There are a couple high-level overview articles available:

        "Modula-3", Sam Harbison, Byte, Vol. 15, No. 12, October 1990,
        pp 385+.

        "Safe Programming with Modula-3", Sam Harbison, Dr. Dobb's Journal,
        Vol. 17, No. 10, October 1992, pp 88+.

   A description of the Modula-3 type system is in

        "The Modula-3 Type System", Luca Cardelli, Jim Donahue, Mick Jordan,
        Bill Kalsow, Greg Nelson, Conference Record of the Sixteenth Annual
        ACM Symposium on Principles of Programming Languages (POPL), Austin
        Texas, January 11-13 1989, pp 202-212.

   The Trestle window system toolkit and higher-level FormsVBT toolkit,
   available with Modula-3, are documented in the following reports:

        "Trestle Reference Manual", Mark S. Manasse and Greg Nelson,
        SRC Research Report 68, December 1991.

        "Trestle Tutorial", Mark S. Manasse and Greg Nelson, SRC Research
        Report 69, May 1, 1992.

        "The FormsVBT Reference Manual", Marc H. Brown and James R. Meehan,
        (soon to be SRC Research Report ??).

   These reports can be ordered by e-mail; send your request to
   src-reports@src.dec.com.

Where can I get an implementation ?

   There is only one implementation available today.  It has been built
   by SRC and is available via anonymous ftp from gatekeeper.dec.com in
   pub/DEC/Modula-3/release.  Contributed software can be found
   in pub/DEC/Modula-3/contrib.

   The current version, 2.11, implements the language defined in SPwM3.
   There are versions for the following machines:

        AIX386  IBM PC running AIX/PS2,
        AP3000  Apollo DN4500 running Domain/OS
        ARM     Acorn R260 running RISC iX 1.21
        DS3100  DECstation 3100 and 5000 running Ultrix 4.0 and 4.2
        HP300   HP 9000/300 running HP-UX 8.0
	HPPA    HP 700/800 running HP-UX 8.0
        IBMR2   IBM R6000 running AIX 3.1, 
        IBMRT   IBM RT running IBM/4.3, 
        NEXT    NeXT running ?
	OKI     Okidata 7300 (i860) running AT&T SVR4.0
        SPARC   SPARCstation running SunOS 4.1.x
        SUN3    SUN3 running SunOS
	SUN386  Sun 386i  running SunOS 4.0.1
        UMAX    Encore Multimax running UMAX 4.3 (R4.1.1)
        VAX     VAX running Ultrix 3.1

   SRC Modula-3 includes a user manual, compiler, runtime library,
   some libraries and a few other goodies (see below).

   The compiler generates C as an intermediate language and should be
   fairly easy to port.  Except for the very lowest levels of the
   thread implementation, the entire system is written in Modula-3.


What if I don't have ftp access ?

   Unfortunately, we cannot deliver Modula-3 other than by 
   anonymous ftp.  

   Fortunately, Prime Time Freeware (PTF) includes Modula-3.  PTF is
   a set of two ISO-9660 CDroms filled with 3GB of freeware, issued
   semi-annually.  The latest issue, Volume 1, Number 2, July 1992,
   contains SRC Modula-3 2.07.  PTF is distributed via bookstores and
   mail.  You can reach PTF using:

	Email:  ptf@cfcl.com
        Fax:    [1] (408) 738 2050
        Voice:  [1] (408) 738 4832
        Mail:   Prime Time Freeware
 	        415-112 N. Mary Ave., Suite 50
		Sunnyvale, CA 94086
	        USA

Can I contribute Modula-3 software ?

   Certainly.  Send us what you are willing to share, be it programs,
   libraries or other things.  We'll put them in the distribution.

   Right now, the pub/DEC/Modula-3/contrib directory contains:

      m3rpc   an rpc system from Xerox Parc
      M2toM3  a translator from Modula-2 to Modula-3
      m3pc    an implementation of Modula-3 for PCs.
   

-- 
Eric.






======================================================================= 11 ===
Date:    5 Feb 93 04:05:31 GMT
From:    aobrodsk@undergrad.math.waterloo.edu (Alex Brodsky)
Subject: question reg m3pc

In the latest faq release, there was mention of m3 for pc, in the file m3pc, to
 
be made available at gatekeeper, as of Thursday February 4, 1993, I could not
find it in the specified directory, could someone please clarify the situation.

Thanks very much.

ttyl
Alex


======================================================================= 12 ===
Date:    5 Feb 93 12:17:32 GMT
From:    marc@ecrc.de (Marc Bourgois)
Subject: network objects

I've come across this concept a few times in relation to m3, 
but I haven't got a clear idea what they are (will be).

Since distribution is a key issue for us, I'm interested in 
all descriptions/ideas m3 designers/implementers have about it.

So, could you please post something about network objects?


---
Marc Bourgois
European Computer-Industry Research Centre      Tel. + (49) 89-92699-179
Arabellastr 17, 8000 Muenchen 81. Germany.
Internet: marc@ecrc.de
UUCP: ..unido!ecrc!marc


======================================================================= 13 ===
Date:    6 Feb 1993 17:14:31 GMT
From:    jgshir@athena.mit.edu (John G Shirlaw)
Subject: Modula-3 on the NeXT

Hi,

Has anyone out there got 2.11 running on the NeXT yet?

Thanks 

john.


======================================================================= 14 ===
Date:    4 Feb 93 14:13:06 GMT
From:    dagenais@vlsi (Michel Dagenais)
Subject: Forking a Modula 3 program


A student here recently had problems with Fork. The M3 program would create
2 pipes, fork, and the child would exec a C program. It worked fine until a
number of interfaces were added to the import list. Then, the child and
parent would die somewhat randomly.

It turns out that when threads are started by imported interfaces, the run
time starts using virtual timers. The timers are inherited by the child and
eventually the C program (through fork and exec). The C program is not 
prepared to handle a virtual timer signal and dies, breaking the pipe 
to the parent. Resetting the timer easily solves the problem, once it is
identified.

Thus, if you need forking, check the virtual timer. A suitable comment in
the Unix.m3 and Uexec.m3 interfaces, close to the fork and exec procedures,
could be a good idea.
--
---------------------------------------------------------------------

Prof. Michel Dagenais			    dagenais@vlsi.polymtl.ca
Dept of Electrical and Computer Eng.
Ecole Polytechnique de Montreal		    tel: (514) 340-4029

---------------------------------------------------------------------


======================================================================= 15 ===
Date:    8 Feb 93 11:23:30 GMT
From:    serls@dashs.denver.co.us (Dave Serls)
Subject: Re: Modula-3 for OS/2?

Well, that's it.  Is it possible to port the SRC to
OS/2 version 2.x?  Its  32-bitness should help.

--
============================================================================
Dave Serls                                                 303-973-6120
serls@dashs.denver.co.us                                   Sorry Software
============================================================================


======================================================================= 16 ===
Date:    Tue, 9 Feb 93 00:29:41 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Re: question reg m3pc

m3pc is now available from gatekeeper.  The FAQ was just a little bit
in advance of the rest of the world.

Enjoy,
Eric.



======================================================================= 17 ===
Date:    Mon, 8 Feb 93 19:30:36 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Re: Modula-3 for OS/2?

In article <729170610snx@dashs.denver.co.us>, serls@dashs.denver.co.us (Dave Se
rls) writes:
|> Well, that's it.  Is it possible to port the SRC to
|> OS/2 version 2.x?  Its  32-bitness should help.

I think that on our side, we know too little about OS/2 to really
answer that question. 

You may be interested to know that the Interface Police is working on
a set of OS-independent interfaces that should make it much easier to
run Modula-3 on OSes that don't look like Unix; and that these
interfaces will be implemented for Unix machines as well as Windows NT
machines.

-- 
Eric.



======================================================================= 18 ===
Date:    Mon, 8 Feb 93 19:28:01 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Re: Forking a Modula 3 program

In article <DAGENAIS.93Feb4091314@pollux.vlsi>, dagenais@vlsi (Michel Dagenais)
 writes:
|> A student here recently had problems with Fork.
[...]
|> It turns out that when threads are started by imported interfaces, the run
|> time starts using virtual timers. 

More precisely, the first time Thread.Fork is invoked, it starts the
virtual timer.  This leaves unthreaded programs simpler.  There is no
direct interaction with the import/export relations.  However, a
change in the imports/exports may change the order of initialization
of modules, and change the order in which Thread.Fork and Unix.fork
are called in your program.

|> The timers are inherited by the child and
|> eventually the C program (through fork and exec). 

The UProcess interface takes care of this detail (among others) for you.

When the work of interface police will be available, the use of the U*
interfaces will be discouraged, in favor of the OS-independant
interfaces that will take care of these things.  

-- 
Eric.



======================================================================= 19 ===
Date:    Mon, 8 Feb 93 20:46:59 GMT
From:    norman@flash.bellcore.com (Norman Ramsey)
Subject: Re: Forking a Modula 3 program

In article <1993Feb8.192801.12589@src.dec.com> Eric Muller <muller@src.dec.com>
 writes:
>The UProcess interface takes care of this detail (among others) for you.

UProcess wasn't distributed with 2.11.  When will it be available on
gatekeeper?  

Norman


======================================================================= 20 ===
Date:    Mon, 8 Feb 93 21:08:12 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Re: Forking a Modula 3 program

In article <1993Feb8.192801.12589@src.dec.com>, I wrote:

|> The UProcess interface takes care of this detail (among others) for you.

But I forgot that UProcess is not exported.  It is below.  It will
make its way into the next release of libm3.


#!/bin/sh
# This is a shell archive (shar 3.32)
# made 02/08/1993 21:06 UTC by muller@procope.pa.dec.com
# Source directory /tmp_mnt/hoax/r/dlusers2/muller/tmp/uprocess
#
# existing files will NOT be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5099 -rw-r--r-- UProcess.i3
#  10101 -rw-r--r-- UProcess.m3
#     41 -rw-r--r-- m3makefile
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= UProcess.i3 ==============
if test X"$1" != X"-c" -a -f 'UProcess.i3'; then
	echo "File already exists: skipping 'UProcess.i3'"
else
echo "x - extracting UProcess.i3 (Text)"
sed 's/^X//' << 'SHAR_EOF' > UProcess.i3 &&
X(* Copyright ) 1991, 1992 Digital Equipment Corporation. *)
X(* Distributed only by permission. *)
X(* Created on Tue Nov 26 18:30:56 PST 1991 by meehan *)
X(* Last modified on Mon Feb  8 13:08:08 PST 1993 by muller *)
X(*      modified on Tue Mar  3 11:20:22 PST 1992 by meehan *)
X
XINTERFACE UProcess;
X
X(* An interface for creating Unix processes and communicating with them via
X   Unix pipes. *)
X
XIMPORT Rd, Thread, Usignal, Wr;
X
XTYPE
X  Handle = MUTEX OBJECT
X             pid           : CARDINAL;  (* the process ID (pid) *)
X             stdin         : Wr.T;
X             stdout, stderr: Rd.T;
X             stdin_t, stdout_t, stderr_t: Thread.T;
X             condition: Thread.Condition;  (* Broadcast when child dies. *)
X             childDied: BOOLEAN;           (* Guarded by the mutex *)
X             status: WaitStatus;  (* Valid only when childDied = TRUE *)
X           END;
X  WaitStatus = RECORD
X                 exitCode         : [0 .. 255];
X                 terminationSignal: [0 .. 127];
X                 dumpedCore       : BOOLEAN
X               END;
X
XEXCEPTION Error(TEXT);          (* Unix errors are reported this way. *)
X
XPROCEDURE Fork (         program    : TEXT;
X                READONLY args       : ARRAY OF TEXT;
X                         mergeOutput                  := FALSE;
X                         ignoreOutput                 := FALSE): Handle
X  RAISES {Error, Rd.Failure, Wr.Failure};
X(* This forks a Unix subprocess and opens up to 3 streams to communicate
X    with it.
X
X   "program" should be a pathname, e.g., "/usr/local/bin/foo". Fork uses
X   execvp(2), which "duplicates the shell's actions in searching for an
X   executable file in a list of directories. The directory list is obtained
X   from the environment."
X
X   "args" should be the complete list of arguments, including argument 0,
X   the name of the program, e.g., "foo".
X
X   Upon return, the 'stdin' field of the Handle is a *writer* to the caller
X   of Fork.  The characters sent to write appear on Stdio.stdin of the 
X   forked process.
X
X   Likewise, 'stdout' and 'stderr' are *readers* to the caller of Fork, and
X   they get their characters from Stdio.stdout and Stdio.stderr of the
X   forked process.
X
X   If "mergeOutput" is true, then the 'stderr' field of the the result 
X   is NIL and characters written to Stdio.stderr by the forked process
X   appear on the 'stdout' field of the result handler.
X
X   If "ignoreOutput" is true, then output from the child's stdout and stderr
X   will be read and discarded.  The 'stderr' and 'stdout' fields of
X   the result handler are NIL. 
X
X   Fork first disables the virtual interval timer; see setitimer(2); This
X   prevents other threads from running while we're cloning the image.
X
X   Fork then calls vfork(2).  The child process closes the "writing"
X   side of its stdin pipe, and the "reading" side of its stdout and
X   stderr pipes.  It calls dup2(2) to reset its stdin, stdout, and
X   stderr.  Finally, it calls execvp(2) to run the program.
X
X   The parent process then re-enables the virtual timer, even if an
X   exception was raised.
X
X   All errors in the child process, up to and including the "execvp",
X   produce error messages on Stdio.stderr, and the child process calls
X   _exit(2), not exit(2).
X
X   The returned value, "handle", is a subtype of MUTEX.  The mutex
X   guards the "childDied" field, which is FALSE when the fork is
X   created.  When the child-process terminates, a background thread
X   will set "handle.childDied" to true and will call Thread.Broadcast
X   on "handle.condition".  After that point, the value of the "status"
X   field is valid.
X
X   *)
X
XPROCEDURE Wait (h: Handle);
X(* This is a simple mechanism for blocking the current thread (not the
X   entire process) until the child process ("h.pid") 
X   and the threads forked by AttachStreams have terminated.
X   After this procedure returns, the value of "h.status" is defined. 
X   *)
X
XPROCEDURE Signal (h: Handle; signal := Usignal.SIGTERM) RAISES {Error};
X(* This signals the subprocess.  It takes no action with respect to the
X   I/O streams. *)
X
XPROCEDURE AttachStreams (h                         : Handle;
X                         stdinReader               : Rd.T     := NIL;
X                         stdoutWriter, stderrWriter: Wr.T     := NIL  );
X(* This will fork a separate thread to read characters from
X   "stdinReader" and write them to "h.stdin", unless "stdinReader"
X   h.stdin is NIL.  
X   Likewise, it will fork a thread to reader characters from
X   "h.stdout" and write them to the stdoutWriter, unless stdoutWriter
X   or h.stdout is NIL. Likewise for the stderr pipe and stderrWriter.  
X   These threads terminate on Rd.EndOfFile, Rd.Failure, Wr.Failure, or
X   Thread.Alerted.  The effect of attaching more than one stream to
X   the same pipe is undefined.  When a newline is read from any reader
X   ("stdinReader", "h.stdout", or "h.stderr"), it will be sent to the
X   corresponding writer, and then Wr.Flush will be called on that
X   writer.  
X   Threads that are created are remembered in the handle, and Wait will
X   join those threads. *)
X
XEND UProcess.
X
X
SHAR_EOF
$TOUCH -am 0208130693 UProcess.i3 &&
chmod 0644 UProcess.i3 ||
echo "restore of UProcess.i3 failed"
set `wc -c UProcess.i3`;Wc_c=$1
if test "$Wc_c" != "5099"; then
	echo original size 5099, current size $Wc_c
fi
fi
# ============= UProcess.m3 ==============
if test X"$1" != X"-c" -a -f 'UProcess.m3'; then
	echo "File already exists: skipping 'UProcess.m3'"
else
echo "x - extracting UProcess.m3 (Text)"
sed 's/^X//' << 'SHAR_EOF' > UProcess.m3 &&
X(* Copyright (C) 1992, Digital Equipment Corporation                         *
)
X(* All rights reserved.                                                      *
)
X(* See the file COPYRIGHT for a full description.                            *
)
X(*                                                                           *
)
X(*      modified on Mon Aug 17 21:27:16 PDT 1992 by meehan                   *
)
X
XUNSAFE MODULE UProcess;
X
XIMPORT Ctypes, Fmt, IntRefTbl, M3toC, Rd, Stdio, Thread, Time, Unix, Uexec;
XIMPORT UFileRdWr, Utime, Wr, RTMisc, Uerror, SmallIO, Usignal;
X
XFROM Uerror IMPORT errno;
X
X<* PRAGMA LL *>
X
XVAR PidTable := IntRefTbl.New ();
X  
XTYPE
X  Arec = RECORD
X           name: Ctypes.CharStar;
X           argv: REF ARRAY OF Ctypes.CharStar
X         END;
X  APipe = ARRAY [0 .. 1] OF Ctypes.int;
X  VPipe = Thread.Closure OBJECT
X            rd  : Rd.T;
X            wr  : Wr.T;
X            name: TEXT
X          OVERRIDES
X            apply := RW
X          END;
X    
XPROCEDURE Close (pid, n: INTEGER) RAISES {Error} =
X  BEGIN
X    IF Unix.close (n) = -1 THEN
X      Gripe (pid, "close " & Fmt.Int (n));
X    END;
X  END Close;
X
XPROCEDURE Pipe (VAR p: APipe) RAISES {Error} =
X  BEGIN
X    IF Unix.pipe (p) = -1 THEN
X      Gripe (-1, "pipe");
X    END;
X  END Pipe;
X
XPROCEDURE Dup2 (pid, a, b: INTEGER) RAISES {Error} =
X  BEGIN
X    IF Unix.dup2 (a, b) = -1 THEN
X      Gripe (pid, "dup2 " & Fmt.Int (a) & ", " & Fmt.Int (b));
X    END;
X  END Dup2;
X
XPROCEDURE Fork (         program     : TEXT;
X                READONLY args        : ARRAY OF TEXT;
X                         mergeOutput                   := FALSE;
X                         ignoreOutput                  := FALSE  ): Handle
X  RAISES {Error, Rd.Failure, Wr.Failure} =
X  VAR
X    stdin, stdout, stderr: APipe;
X    h                    : Handle;
X    pid                  : INTEGER;
X    arec                             := ConvertArgs (program, args);
X    oit                  : Utime.struct_itimerval;
X  BEGIN
X    Pipe (stdin);
X    IF NOT ignoreOutput THEN
X      Pipe (stdout);
X      IF NOT mergeOutput THEN
X        Pipe (stderr);
X      END;
X    END;
X
X    (* Disable the timer BEFORE forking. *)
X    VAR nit := Utime.struct_itimerval {
X                   it_interval := Utime.struct_timeval {0, 0},
X                   it_value    := Utime.struct_timeval {0, 0}}; 
X    BEGIN
X      IF Utime.setitimer (Utime.ITIMER_VIRTUAL, nit, oit) = -1 THEN
X        Gripe (-1, "Couldn't disable virtual timer.");
X      END; 
X    END;
X
X    TRY                         (* FINALLY re-enable timer *)
X      pid := Unix.vfork ();
X
X      IF pid < 0 THEN
X        Gripe (pid, "Couldn't fork.");
X
X      ELSIF pid = 0 THEN        (* child *)
X        (* connect stdin to end of pipe *)
X        Close (pid, stdin [Unix.writeEnd]);
X        Dup2 (pid, stdin [Unix.readEnd], SmallIO.stdin);
X        Close (pid, stdin [Unix.readEnd]);
X    
X        IF ignoreOutput THEN
X          (* connect stdout and stderr to /dev/null *)
X          VAR devnull := Unix.open (M3toC.TtoS ("/dev/null"),
X                                    Unix.O_WRONLY, Unix.Mrwrwrw); 
X          BEGIN
X            IF devnull = -1 THEN 
X               Gripe (pid, "Couldn't open /dev/null in child");
X            END;
X            Dup2 (pid, devnull, SmallIO.stdout);
X            Dup2 (pid, devnull, SmallIO.stderr);
X            Close (pid, devnull);
X          END;
X        ELSE
X          (* connect stdout to write end of pipe *)
X          Close (pid, stdout [Unix.readEnd]);
X          Dup2 (pid, stdout [Unix.writeEnd], SmallIO.stdout);
X          Close (pid, stdout [Unix.writeEnd]);
X
X          IF mergeOutput THEN
X            (* connect stderr to stdout *)
X            Dup2 (pid, SmallIO.stdout, SmallIO.stderr);
X          ELSE
X            Close (pid, stderr [Unix.readEnd]);
X            Dup2 (pid, stderr [Unix.writeEnd], SmallIO.stderr);
X            Close (pid, stderr [Unix.writeEnd]);
X          END;
X        END;
X
X        WITH v = Uexec.execvp (arec.name, ADR (arec.argv [0])) DO
X          Gripe (pid, Fmt.F ("execvp returned %s!", Fmt.Int (v))); END;
X
X
X      ELSE                      (* parent *)
X        h := NEW (Handle, pid := pid, 
X                  condition := NEW (Thread.Condition), childDied := FALSE,
X                  stdin_t := NIL, stdout_t := NIL, stderr_t := NIL);
X
X        Close (pid, stdin [Unix.readEnd]);
X        h.stdin :=  UFileRdWr.CreateFileWriter (stdin [Unix.writeEnd], TRUE);
X        IF ignoreOutput THEN
X          h.stdout := NIL;
X          h.stderr := NIL; 
X        ELSE
X          Close (pid, stdout [Unix.writeEnd]);
X          h.stdout := UFileRdWr.CreateFileReader (stdout [Unix.readEnd]);
X          IF mergeOutput THEN
X            h.stderr := NIL;
X          ELSE
X            Close (pid, stderr [Unix.writeEnd]);
X            h.stderr := UFileRdWr.CreateFileReader (stderr [Unix.readEnd]);
X          END;
X        END; 
X
X        FreeArgs (arec);
X        EVAL PidTable.put (pid, h);
X        RETURN h
X      END
X
X    FINALLY                     (* Restore previous virtual timer. *)
X      VAR nit: Utime.struct_itimerval; BEGIN
X        IF Utime.setitimer (Utime.ITIMER_VIRTUAL, oit, nit) # 0 THEN
X          Gripe (-1, "Couldn't re-enable virtual timer."); END; END;
X    END
X  END Fork;
X
XPROCEDURE Gripe (pid: INTEGER; msg: TEXT) RAISES {Error} =
X  VAR e := errno;
X  BEGIN
X    msg := Fmt.F ("pid %s, %s Errno = %s: %s", Fmt.Int (pid), msg, Fmt.Int (e)
,
X                  M3toC.StoT (Uerror.GetFrom_sys_errlist (e)));
X    IF pid = 0 THEN             (* child *)
X      TRY
X        Wr.PutText (Stdio.stderr, msg);
X        Wr.Flush (Stdio.stderr)
X      EXCEPT
X      ELSE (* ignore failures at this point *)
X      END;
X      RTMisc.Exit (99)
X    ELSE
X      RAISE Error (msg)
X    END
X  END Gripe;
X    
X
XPROCEDURE ConvertArgs (program: TEXT; READONLY args: ARRAY OF TEXT): Arec
X  RAISES {Error} =
X  VAR
X    result: Arec;
X    j            := 0;
X  BEGIN
X    result.argv := NEW (REF ARRAY OF Ctypes.CharStar, 1 + NUMBER (args));
X    result.name := M3toC.TtoS (program);
X    FOR i := FIRST (args) TO LAST (args) DO
X      result.argv [j] := M3toC.TtoS (args [i]);
X      INC (j)
X    END;
X    result.argv [NUMBER (args)] := NIL;
X    RETURN result
X  END ConvertArgs;
X
XPROCEDURE FreeArgs (VAR arec: Arec) =
X  BEGIN
X    M3toC.FreeS (arec.name);
X    FOR j := FIRST (arec.argv^) TO LAST (arec.argv^) DO
X      IF arec.argv [j] = NIL THEN
X        EXIT
X      ELSE
X        M3toC.FreeS (arec.argv [j]);
X        arec.argv [j] := NIL
X      END
X    END
X  END FreeArgs;
X
XPROCEDURE AttachStreams (h                         : Handle;
X                         stdinReader               : Rd.T     := NIL;
X                         stdoutWriter, stderrWriter: Wr.T     := NIL  ) =
X  BEGIN
X    IF stdinReader # NIL AND h.stdin # NIL THEN
X      h.stdin_t := Thread.Fork (NEW (VPipe, rd := stdinReader, wr := h.stdin,
X                                     name := "stdin"))
X    END;
X    IF stdoutWriter # NIL AND h.stdout # NIL THEN
X      h.stdout_t := Thread.Fork (NEW (VPipe, 
X                                      rd := h.stdout, wr := stdoutWriter,
X                                      name := "stdout"))
X    END;
X    IF stderrWriter # NIL AND h.stderr # NIL THEN
X      h.stderr_t := Thread.Fork (NEW (VPipe,
X                                      rd := h.stderr, wr := stderrWriter,
X                                      name := "stderr"))
X    END
X  END AttachStreams;
X
XPROCEDURE RW (vp: VPipe): REFANY =
X  BEGIN
X    TRY
X      LOOP
X        WITH c = Rd.GetChar (vp.rd) DO
X          Wr.PutChar (vp.wr, c);
X          IF c = '\n' THEN Wr.Flush (vp.wr) END
X        END
X      END
X    EXCEPT
X    | Rd.EndOfFile, Rd.Failure, Wr.Failure, Thread.Alerted =>
X    END;
X    RETURN NIL
X  END RW;
X
XVAR
X  mu                := NEW (MUTEX);
X  c                 := NEW (Thread.Condition); <* LL = mu *>
X  waiters: CARDINAL := 0;       <* LL = mu *>
X    
XPROCEDURE Wait3Forever (<* UNUSED *> cl: Thread.Closure): REFANY =
X  VAR
X    status: Uexec.w_T;
X    h     : Handle;
X    ref   : REFANY;
X  BEGIN
X    LOOP                        (* outer *)
X      LOCK mu DO WHILE waiters = 0 DO Thread.Wait (mu, c) END END;
X      LOOP                      (* inner *)
X        WITH x = Uexec.wait3 (
X                   ADR (LOOPHOLE (status, Uexec.w_A)), Uexec.WNOHANG, NIL) DO
X          IF x > 0 THEN
X            TRY
X              IF PidTable.delete (x, ref) THEN
X                h := ref;
X                LOCK h DO
X                  h.status.exitCode := status.w_Retcode;
X                  h.status.terminationSignal := status.w_Termsig;
X                  h.status.dumpedCore := status.w_Coredump # 0;
X                  h.childDied := TRUE;
X                  Thread.Broadcast (h.condition)
X                END
X              END
X            EXCEPT
X              IntRefTbl.NotFound =>
X            END
X          ELSE
X            (* x might be -1 and errno = ECHILD (no children).  OK *)
X            LOCK mu DO
X              IF waiters = 0 THEN EXIT END (* resume outer loop *) 
X            END;
X            Time.Pause (100000) (* and resume inner loop *)
X          END                   (* IF x > 0 *)
X        END                     (* WITH *)
X      END                       (* inner LOOP *)
X    END                         (* outer LOOP *)
X  END Wait3Forever;
X
XPROCEDURE Wait (h: Handle) =
X  BEGIN
X    LOCK mu DO INC (waiters); Thread.Signal (c) END;
X    LOCK h DO
X      WHILE NOT h.childDied DO Thread.Wait (h, h.condition) END
X    END;
X    IF h.stdin_t # NIL THEN
X      EVAL Thread.Join (h.stdin_t);
X      h.stdin_t := NIL;
X    END;
X    IF h.stdout_t # NIL THEN
X      EVAL Thread.Join (h.stdout_t);
X      h.stdout_t := NIL;
X    END;
X    IF h.stderr_t # NIL THEN
X      EVAL Thread.Join (h.stderr_t);
X      h.stderr_t := NIL;
X    END;
X    LOCK mu DO DEC (waiters) END
X  END Wait;
X
XPROCEDURE Signal (h: Handle; signal := Usignal.SIGTERM) RAISES {Error} =
X  BEGIN
X    IF Usignal.kill (h.pid, signal) # 0 THEN
X      Gripe (h.pid, "Couldn't signal child process.")
X    END
X  END Signal;
X
XBEGIN
X  EVAL Thread.Fork (NEW (Thread.Closure, apply := Wait3Forever))
XEND UProcess.
X
SHAR_EOF
$TOUCH -am 0208130693 UProcess.m3 &&
chmod 0644 UProcess.m3 ||
echo "restore of UProcess.m3 failed"
set `wc -c UProcess.m3`;Wc_c=$1
if test "$Wc_c" != "10101"; then
	echo original size 10101, current size $Wc_c
fi
fi
# ============= m3makefile ==============
if test X"$1" != X"-c" -a -f 'm3makefile'; then
	echo "File already exists: skipping 'm3makefile'"
else
echo "x - extracting m3makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > m3makefile &&
XModule (UProcess)
X
XLibrary (m3uprocess)
X
SHAR_EOF
$TOUCH -am 0208130693 m3makefile &&
chmod 0644 m3makefile ||
echo "restore of m3makefile failed"
set `wc -c m3makefile`;Wc_c=$1
if test "$Wc_c" != "41"; then
	echo original size 41, current size $Wc_c
fi
fi
exit 0




-- 
Eric.



======================================================================= 21 ===
Date:    8 Feb 93 20:45:28 GMT
From:    nettles+@cs.cmu.edu (Scott Nettles)
Subject: Details on the new incremental GC?


Being the garbage collection weeny that I am, I'd like to hear more details
about the new incremental collector.  I'd also like to know more about how 
finalization works.  Could someone in the know either post or point me at 
some documentation?  Thanks!

Scott
nettles@cs.cmu.edu


======================================================================= 22 ===
Date:    Thu, 11 Feb 93 20:38:02 GMT
From:    jdd@src.dec.com (John DeTreville)
Subject: Re: Details on the new incremental GC?

The new collector is really pretty vanilla, although a little complex
in its implementation.  As you recall, the old collector was a
stop-and-copy collector.  The new one is based on the old one, but
uses VM synchronization to achieve incremental collection (a la
Appel/Ellis/Li).

With an incremental collector, the program can run during a
collection.  The collector is implemented as a monitor; program
actions like allocations drive it forward but each collection is
broken into a large number of small pieces.

We maintain the invariant that locals and globals hold only objects in
the new space.  Therefore, the only way the program could access
references to the old space is by deferencing "gray" heap objects,
those in the new space whose references into the old space have not
yet been updated.

To keep this from happening, we read-protect all pages containing gray
objects.  As the collector cleans gray pages, it unprotects them.  If
the program tries to read a gray page, it gets a fault, the collector
cleans the page and unprotects it, and restarts the program.  The
program can therefore never get a reference into the old space.

Write-protection of heap pages is also used to implement generational
collection, maintaining the "remembered set."  Pages in the older
generation are write-protected; a write fault simply clears the
protection but remembers that the page might now contain a reference
into the newer generation.

Not all architectures can support VM protection.  Moreover, some of
the code is OS-dependent, and it's currently implemented only for
DECstations running Ultrix and SPARCs running SunOS.  When the code is
not implemented, the collector becomes an ordinary stop-and-copy
collector, much like the previous one.

Incremental collection gives almost unnoticable interruptions of
service due to collections.  Generational collection spends less total
time in the collector.

That's fairly nontechnical; let me know if you have more detailed
questions.

Cheers,
John


======================================================================= 23 ===
Date:    Fri, 12 Feb 93 18:49:56 GMT
From:    jdd@src.dec.com (John DeTreville)
Subject: Re: Details on the new incremental GC?

[Scott asked me some more questions via mail, and asked me to post the
answers.]

  Do you have any special tricks to avoid a flurry of faults when 
  you've just flipped or has that not been a problem?

All I can do right now is to try to encourage locality.  The previous 
collector treated the gray pages as a queue; I treat them as a stack, 
which is better.  Whenever the collector gets to choose what page 
to clean, it cleans the current copy page, which increases the number 
of intra-page references.  And I separate REF-containing objects 
from non-REF-containing when I copy them, so that I never need to 
protect objects with no REFs. 
  
  In general is the overhead of fault handling a big deal?

Yes and no.  It's higher than I'd like, but the collector runs faster 
than the old one, so things could be worse.

BTW, I think the most interesting work is in the generational side; 
I'll be writing it up soon.
  
  How does finalization work and what's the interface to it?
  
I've appended the interface; it's messy to implement but has good 
semantics, and I believe it's portable to other collector strategies.  
I've recently polished the words; let me know if it's confusing.

To support weak refs in the collector, we first do an ordinary copy 
without treating weak refs as roots.  If there are no weakly-referenced 
nodes, we're done.  Otherwise, we then need a mark phase on weakly 
referenced nodes remaining in the old space, that moves them to the 
new space if they're reachable from another weakly-referenced node; 
then we copy everything reachable from them.  Finally, we treat weakly 
referenced nodes as roots and copy everything from them to the new 
space.  Whew. 

There's a little bit of optimization in distinguishing weakly-referenced 
objects with and without cleanup procedures.

Cheers,
John

----------

(* Copyright 1992 by Digital Equipment Corp. *)

(* Most Modula-3 programs simply let the garbage collector deallocate
   storage automatically, but some programs need more control.  
   For example, if a variable allocated in the traced
   heap contains a handle on a resource in the operating system or in
   some other address space, then when the variable is garbage-collected
   it may be important to deallocate the resource.  The "WeakRef"
   interface provides this additional control.
   
   A {\it node} is a datum allocated on the traced heap. Thus a node
   is either the referent of a variable of a fixed reference type or
   the data record of a traced object.

   A "WeakRef.T" is a data structure that refers to a node 
   without protecting the node from the garbage collector.  If "w" is a 
   weak reference, we write "nd(w)" to denote the node to which "w"
   refers.
   
   We say that a weak reference "w" {\it dies} at the moment that the
   garbage collector detects that "nd(w)" is unreachable.  A precise
   definition of unreachable is given below.  Once a weak reference
   has died, it remains dead forever, even if the node to which
   it refers becomes reachable again.

   Associated with each weak reference "w" is a {\it cleanup procedure}
   "cp(w)".  If the cleanup procedure is not "NIL", the garbage
   collector will schedule a call to it when the weak reference
   dies. *)

INTERFACE WeakRef;

TYPE T = ARRAY [0..7] OF BITS 8 FOR [0..255];
(* Please treat this as though it were an opaque type:  the
   only operations allowed are assignment, equality tests,
   and the procedures in this interface.  *)

PROCEDURE FromRef(r: REFANY; p: CleanUpProc := NIL): T;
(* Return a weak reference "w" such that  "nd(w) = r" and 
   "cp(w) = p".  It is a checked runtime error if "r" is "NIL".
   It is illegal to create more than one weak reference with a
   non-nil cleanup to the same node; violations of this rule
   may lead to a checked runtime error, or may cause one
   of the cleanup actions to be omitted.  "FromRef" is not
   necessarily functional: it is possible that "nd(w1) = nd(w2)"
   but "w1 # w2". *)

PROCEDURE ToRef(w: T): REFANY;
(* Return a reference to "nd(w)", unless "w" is dead, in which 
   case return "NIL".  *)

TYPE CleanUpProc = PROCEDURE(READONLY w: T; r: REFANY);
(* If "cp(w)" is not "NIL", then when "w" dies, the garbage collector
   will schedule the call "cp(w)(w, <reference to nd(w)>)".  *)

END WeakRef.

(* The cleanup procedure will be executed at some point after 
   the weak reference dies.   A cleanup procedure is called with 
   no locks held; it must return promptly to allow other 
   objects to be cleaned up.  

   The computation "cp(w)(w, ref)" is allowed to store "ref" in a
   non-local variable, thus making "nd(w)" reachable again; the heap
   storage will not have been freed.  This does not change the fact
   that "w" is dead.  The cleanup procedure can re-enable cleanup, if
   desired, by creating a new weak reference to "nd(w)".

   The storage for a node is reclaimed when it is unreachable
   and all weak references to it are dead and all cleanup calls 
   scheduled for it have been completed.

   Finally we come to the precise definition of ``reachable'':

   A node is {\it reachable} if it can be reached by a path of traced
   references starting from a current procedure activation record, a global
   variable, or a weakly referenced node with a non-nil
   cleanup {\it other than itself}.

   Thus a weak reference to a node "nd" does not make "nd" reachable,
   but if it has a non-nil cleanup, it makes other nodes referenced 
   from "nd" reachable.
   
   For example, if "A" and "B" are two nodes that are weakly referenced 
   by weak references with non-nil cleanup procedures, then if "B"
   is reachable from "A", then "B" is reachable.  But if "A" is not
   reachable, then the garbage collector will eventually detect this 
   and schedule the cleanup of "A".  If the cleanup call returns 
   without resurrecting "A", then "A"'s storage will be reclaimed, 
   at which point "B" will be unreachable, which will lead to its cleanup.

   If "A" and "B" are weakly referenced nodes with non-nil cleanups
   that are connected by a cycle of traced references, then both of 
   them are reachable.   As long as the cycle persists, neither will 
   be cleaned up.  This situation represents a storage leak and 
   should be avoided.

\subsection*{Examples}

{\bf 1}.\ \  Suppose you want writers of the class "WrX.T" to be automatically
flushed and closed if they become unreachable.  Then you could write
code like the following in the "WrX" module:

| MODULE WrX; IMPORT WeakRef, Wr, ...;
| 
| PROCEDURE New(...): T =
|   VAR res := NEW(T); BEGIN
|     (* ... initialize res as a WrX.T ... *)
|     EVAL WeakRef.FromRef(res, Cleanup);
|     RETURN res
|   END New;
|
| PROCEDURE Cleanup(self: WeakRef.T; ref: REFANY) =
|   VAR wr: T := ref; BEGIN
|     IF NOT Wr.Closed(wr) THEN
|       Wr.Flush(wr);
|       Wr.Close(wr)
|     END
|   END Cleanup;
| 

There is no danger that another thread could close the writer
after the test "NOT Wr.Closed(wr)" and before the call "Wr.Flush(wr)",
since when "Cleanup" is called, the writer is unreachable.  Therefore 
the cleanup method has exclusive access to the writer.

{\bf 2.}\ \  The network object runtime must map wire
representations for network objects into surrogate objects.  To hand
out the same surrogate for the same wire representation, it keeps a
table mapping wire representations to surrogates.  This table contains
weak references, so the table entry itself does not prevent the
surrogate from being collected.  When the surrogate is collected, it
is removed from the table and the server containing that object is
notified that the client no longer has a surrogate for it.

When a weak reference in the table becomes dead, the network object
represented by the dead surrogate might be unmarshaled by the address
space before the surrogate is cleaned up.  In this case the unmarshaling
code resurrects the unreachable surrogate by creating a new weak 
reference and inserting it in the table in place of the dead weak
reference.  The cleanup code can tell whether to report in clean by
checking whether there is a new weak reference in the table or not.

Here is a sketch of the code:

| TYPE Surrogate = OBJECT wr: WireRep; ... END;

| VAR
|   mu := NEW(MUTEX);
|   <* LL >= {mu} *>
|   tbl := NEW(WireRepToWeakRefTbl.T);

   The mutex "mu" must be held to read or write "tbl" (that
   is what the "LL" pragma means).

   The table "tbl" maps "WireRep"s to "WeakRef"s that reference
   surrogates.

   The following invariants hold whenever "mu" is not held:

   If "tbl(wrep)" is not dead, then "nd(tbl(wrep))" is the 
   surrogate for the network object whose wire representation 
   is "wrep".

   If "tbl(wrep)" is dead, then the surrogate for "wrep" is 
   unreachable. 
   
   If "tbl" has no entry for "wrep", then the address space
   contains no surrogate for "wrep".

| PROCEDURE Cleanup(wref: WeakRef.T; ref: REFANY) =
| <* LL = {} *>
|   VAR 
|     srg := NARROW(ref, Surrogate); 
|     tblVal: WeakRef.T;
|   BEGIN
|     LOCK mu DO
|       IF tbl.get(srg.wr, tblVal) AND wref = tblVal 
|       THEN
|         EVAL tbl.delete(srg.wr);
|         ... Report that srg is deleted ...
|       END
|     END
|   END Cleanup;
|
| PROCEDURE WireRepToSrg(wrep: WireRep): Surrogate =
|   VAR wref: WeakRef.T; res: Surrogate; BEGIN
|     LOCK mu DO
|       IF tbl.get(wrep, wref) THEN
|         res := WeakRef.ToRef(wref);
|         IF res # NIL THEN RETURN res END
|       END;
|       res := NewSurrogate(wrep);
|       EVAL tbl.put(wrep, WeakRef.FromRef(res, Cleanup));
|       RETURN res
|     END
|   END WireRepToSrg;

  In the above we assume that "NewSurrogate" creates a new surrogate
  from a wire representation. *)


======================================================================= 24 ===
Date:    Fri, 12 Feb 1993 15:26:51 GMT
From:    os102@cl.cam.ac.uk (Oliver Stephens)
Subject: Oddity with TextPorts

I wonder if anyone else has come across this one:

If I have a Trestle program running iconised for a length of time (like
overnight, say) then when I de-iconise it, about 1 out of 5 times,
TextPorts won't accept any keyboard or mouse input, no matter how hard
and long I try and make them.  Buttons still work OK, so do home-grown
VBTs and things like ListVBTs and ScrollBars; it seems to be unique to
TextPorts.

(I am running m3 2.11 on SPARC under mwm with X11R4)

------------------------------------------------------------------------- 
Olly Stephens                                oliver.stephens@cl.cam.ac.uk
Computer Laboratory
University of Cambridge    Loved you there and then, and now like a sheep
United Kingdom                                             - Van Morrison


======================================================================= 25 ===
Date:    Sat, 13 Feb 93 01:01:02 -0800
From:    msm@src.dec.com
Subject: Re: Object type questions


In response to your questions,

1) It is a bit verbose, but that's the idiom that we've grown accustomed 
to for making partial revelations.  If you were willing to repeat 
all of the declarations for the type in its revelation, you could 
dispense with giving the intermediate type a name, but that's much 
more error-prone.  One might think about some syntactic sugar for 
"the minimal type matching what's statically known about T", which 
you could use in the revelation, but instead the Public convention 
has grown up.


2) Even if you reveal the method values in the declaration of a type, 
method invocation is still going to have to examine the method suite 
of the object, because any call to the method might be a call on 
an object which is (synamically) a subtype of the static type, and 
which might therefore override the method.  This is related to your 
confusion with point 3.  To achieve an effect like C++ non-virtual 
member functions, you should either define procedures in the interface, 
or, instead of calling object.method, you should call ObjectType.method.  


3) Narrowing an object to a supertype doesn't change any properties 
of the object; it merely changes your view of the mapping of names 
within the object to offsets in the object (either by extending the 
map, or contracting it).  You can think of the methods of an object 
simply as extra procedure-valued fields of the object (although the 
implementation is more space-efficient than that).  Another way of 
thinking about it is that METHODS in M3 are like virtual member functions 
in C++. 

Suppose we have
  A = OBJECT a: INTEGER END;
  B = A OBJECT b: INTEGER END;

If I take an object of type B, and I narrow it to an A, and pass 
it to a procedure expecting an A, the b field is still there; that 
procedure just can't name it.  

Similarly, if we have

  A = OBJECT METHODS a() := AProc END;
  B = A OBJECT OVERRIDES a := BProc END;

If b is a B, B.a() invokes BProc, as does NARROW(b, A).a(), since 
no value has changed.  (If B was defined to be 
  A OBJECT METHODS a := BProc END;
that would introduce a new "field" named a which would obscure the 
old field of that name.  When I narrow it to an A, the name a refers 
to the offset for the old field, and thus to AProc).

I can always invoke AProc by calling A.a(b), if I want; that may 
be useful in the implementation of BProc, for instance.

Without this, method overriding wouldn't accomplish much of anything.  
The reason that you create a subtype of some type is so that you 
can pass it to all the same old procedures that statically expect 
the supertype.  The reason that you override a method is to define 
a new behavior for that operation; if that's not what you want, you 
should add a new method instead.

Mark



======================================================================= 26 ===
Date:    12 Feb 93 03:58:50 GMT
From:    robh@eclipse.cs.colorado.edu (Robert G Henderson)
Subject: Object type questions


I have a few questions related to object types.  I welcome
any information you can provide.  Feel free to point me
to the applicable documentation when appropriate (in other
words, RTFM responses will be gracious accepted as long as
you tell me which M :-).

1.  I find the use of object types in conjunction with
    information hiding to be a bit cumbersome.  I am
    defining a public type in the interface to expose
    those features of the class I want public.  I then
    make the actual class a subtype of this public type
    in order to hide the features of the class I want
    private.  Is this the "accepted" way of achieving
    information hiding with classes?  It just seems a
    little strange to have to declare two actual object
    types for each conceptual class just to achieve
    information hiding.

2.  I am declaring METHODS in the public object type
    (in the interface) and not initializing them.  I then 
    OVERRIDE them (in the module) and provide a procedure
    that implements the method.  For example:

    In the interface:

       TYPE
          T <: Public_T;
          Public_T = OBJECT
            METHODS
               Foo();
               Bar();
          END;

    and in the module:

       REVEAL T = Public_T BRANDED OBJECT
           SomethingPrivate: INTEGER;
           OVERRIDES
               Foo := FooProc;
               Bar := BarProc;
           END;

    The problem I am having with this is related to run-time
    performance.  I am finding that the the calls to Foo and
    Bar are incurring overhead related to dynamic dispatch
    so a call to object.Foo() is somewhat more expensive
    than to ModuleName.FooProc(object).  I would expect to pay
    the overhead of dynamic dispatch if I declared an object type
    that was a subtype of this type and overrode Foo and Bar.
    However, I don't really need the overhead of dispatch.
    But, by using the technique shown above to achieve
    information hiding with object types, it seems that I
    am paying the cost.  Is there a way to achieve this level
    of information hiding with object types and not pay the
    dispatch overhead and without having to make normal procedure
    calls like ModuleName.FooProc(object)?

3.  I am a little puzzled by the interaction between OVERRIDEs
    and NARROW.  If an object that overrides a method defined in
    the superclass is NARROWed to the supertype, the overridden
    method is still not visible.  What was the motivation behind
    these semantics?  Why would you not want the NARROW to reveal
    the method in the supertype, as is the case if the subtype
    declares a new METHOD rather than overriding?

I greatly appreciate any and all responses to these (hopefully not
*too* naive) questions.  I'm relatively new to Modula-3 and am
trying to gain a better understanding of the language.

Feel free to respond either via a followup post or email,
whichever you feel appropriate.  Thanks.

		--Rob

-------------
Rob Henderson                          Department of Computer Science
CSops Staff/Graduate Student           Campus Box 430, ECEE00-69
robh@cs.colorado.edu                   University of Colorado
(303) 492-5720                         Boulder, CO  80309-0430


======================================================================= 27 ===
Date:    13 Feb 93 01:02:52 GMT
From:    dmiller@beta.tricity.wsu.edu (David L. Miller)
Subject: Re: Help with building mentor

In article <bmiller.729552302@atto>, bmiller@atto.cs.umn.edu (Bradley N. Miller
) writes:
|> 
|> one executable is large than the whole package!
|> If anyone could give me any pointers as to where I might have gone
|> astray I would really appreciate it. (my sysadmin too)
|> 
Those numbers sound about like what I encountered when building m3...
I ended up with most executables in the 5MB to 6MB range with a peak of about
18MB :(

|> Brad
|> 
|> bmiller@cs.umn.edu
|> --
|> ----------------------------------------------------------------------------
---
|> Brad Miller                   |              e-mail:   bmiller@cs.umn.edu   
  |
|> University of Minnesota       |                                             
  |
|>                               |        this space for rent                  
  |

-- 
*****************************************************************************
David L. Miller                       Internet: dmiller@beta.tricity.wsu.edu
Systems Programmer/Network Analyst      BITNET: MILLERD@WSUVM1
Washington State University Tri-Cities    UUCP: ...!yoda!dmiller
100 Sprout Road                          
Richland, WA 99352                       Phone: (509)375-9245
*****************************************************************************


======================================================================= 28 ===
Date:    Sat, 13 Feb 93 17:40:09 -0800
From:    msm@src.dec.com
Subject: Re: Help with building mentor


No error; M3 executables (especially with symbols) are very large.  
If you're running on a SPARC, you might try using shared libraries 
to reduce the disk requirements for executables.

You should also be able to strip the executables and gain a significant 
savings in size; using your C optimizer may also help, if it doesn't 
produce code that doesn't work.

Mark


======================================================================= 29 ===
Date:    Sun, 14 Feb 93 07:06:43 GMT
From:    Eric Muller <muller@src.dec.com>
Subject: Re: Help with building mentor

You can reduce the size of executable by not compiling with debug (the
default).  In mentor/src/m3makefile, add the line:

M3OPT =

at the top.

-- 
Eric.



======================================================================= 30 ===
Date:    12 Feb 93 21:25:02 GMT
From:    bmiller@atto.cs.umn.edu (Bradley N. Miller)
Subject: Help with building mentor

Well,
After reading the 'Color and Sound in Algorithm Animation' article in the
December issue of Computer, I was motivated to build the modula3 system
so I could run some of the animations myself.  So here is where I'm
at:  I think that I have everything built correctly up to the point
of building mentor.  I do a m3make build_install.mentor, and off we
go compiling for a VERY long time. finally I see a message that we are
linking, and shortly after that we are out of disk space.  So I try
again, same result.  Now, as an experiment I decided to build just
one part of mentor.  so I cd to euclid/src and do a make.  This actually
works however this is what the euclid executable looks like:
-rwx------  1 bmiller  12419072 Feb 12 15:20 /home/grad08/bmiller/m3/mentor.ex/
euclid/src/euclid

No wonder I run out of disk space when I try to build everything!

Now the thing that puzzles me is that according to the README these are
the characteristics of the mentor package 
    File           Build  Inst.  Src.  Desc
name     size    disk cpu
mentor    328    9762  42  4      1017 algorithm animation demos

one executable is large than the whole package!
If anyone could give me any pointers as to where I might have gone
astray I would really appreciate it. (my sysadmin too)

Brad

bmiller@cs.umn.edu
--
-------------------------------------------------------------------------------
Brad Miller                   |              e-mail:   bmiller@cs.umn.edu     |
University of Minnesota       |                                               |
                              |        this space for rent                    |


======================================================================= 31 ===
Date:    13 Feb 1993 02:24:51 GMT
From:    patl@bodacia.Eng.Sun.COM (Pat Lashley)
Subject: Cstdio/SmallIO porting question

I'm starting a Modula-3 port to a non-unix system.  The easiest method
is probably to use some unix emulation capabilities that were developed
(by someone else) for the gcc port.  It looks pretty smooth so far, except
for the I/O buffer definition in Cstdio.i3.  The stdio.h file on the target
system claims to be based on the BSD Tahoe release.  The definition of
the I/O buffer is significantly different from that on SunOS4.x, Solaris-2,
or any other system I'm familiar with.  (Among other things, it has separate
read and write counters, a pointer for a separate ungetc buffer for long
ungetc's, etc.)

The standard SmallIO package is expecting an iobuf that consists of little
more than a couple of pointers, a size, and a count.  I'm not familiar enough
with the SRC m3 system to know whether I should simply stick with the simple
iobuf definition in Cstdio; or should I re-write SmallIO to use the longer
definition.  I'm hoping that someone out there can clear up my ignorance...



Thanks,
-Pat


---
PMLashley	plashley@Sun.COM    SunSoft:NeWS/TNT
"Those who do not understand NeWS are doomed to recreate it - badly"



======================================================================= 32 ===
Date:    16 Feb 93 00:49:02 GMT
From:    patl@bodacia.Eng.Sun.COM (Pat Lashley)
Subject: :? SunOS/OW patch required for M3 X11 apps

Some of the X11 demo apps (e.g. solitaire) are crashing OpenWindows.
I seem to recall seeing a message a while back that contained the
number of a SunOS or OpenWindows patch that fixes this.  I thought
I'd saved it, but I can't find it in my archives, nor in a quick
search of the archives on gatekeeper.  Could one of you kind souls
please mail me the info?



Thanks,
-Pat



---
PMLashley	plashley@Sun.COM    SunSoft:NeWS/TNT
	"Those who do not know NeWS are doomed to recreate it - badly."


======================================================================= 33 ===
Date:    Mon, 15 Feb 1993 16:23:25 GMT
From:    bmiller@myria.cs.umn.edu (Bradley N. Miller)
Subject: Re: Help with building mentor

Thanks very much to all who responded to my plea.  Stripping the executable
reduced the size of the file by a whopping 10 Meg!

I am also going to try a build with the debug option turned off and see
what that gets me.

Thanks again,

Brad
bmiller@cs.umn.edu



======================================================================= 34 ===
Date:    16 Feb 93 23:38:49 GMT
From:    dsims@don.ece.uc.edu (David Sims)
Subject: yacc grammar available for Modula-3?

Does anyone have a yacc grammar for Modula-3?

-- 
David Sims                    Dept. of Electrical and Computer Engineering
david.sims@uc.edu             University of Cincinnati
(513) 556-2499                Cincinnati OH  45221-0030
RIPEM mail accepted.          USA


======================================================================= 35 ===
Date:    Wed, 17 Feb 93 23:02:00 -0800
From:    meehan@src.dec.com
Subject: Re: yacc grammar available for Modula-3?


    Does anyone have a yacc grammar for Modula-3?

There's one in the pretty-printer sources (Parse.yacc) that come 
with the distribution.  Opening comment from that file:

    A yacc source file for the Modula-3 pretty-printer.  This grammar 
    was constructed from the grammar given in the Modula-3 report; 
    the main problem was to get it right for yacc (an expression 
    can start by a type). Expect 2 shift/reduce conflicts.


======================================================================= 36 ===
Date:    16 Feb 93 22:48:55 GMT
From:    werts@aardvark.cecs.csulb.edu (Michael Werts)
Subject: Difficulty using Trestle

I having problems again. This time I'm trying to compile and run the
sample programs in the Trestle distribution.

I attempted the following from sun4-m3/trestle/Apps.
--------------------------------------------------------
lynx.cecs.csulb.edu# ../../bin/m3make m3makefile all
`m3makefile' is up to date.
/u1/sun4-m3/bin/m3 -w1 -make -why -g   
-D../src/xvbt:../src/vbt:../src/split:../src/trestle  -commands -o  
TypeInTest TypeInTest.m3   ../SPARC/libm3ui.a -lm3X11R4 -lX11 
inhale ../SPARC/libm3ui.a
inhale /u1/sun4-m3/lib/m3/libm3X11R4.a
inhale /usr/lib/libX11.a
inhale /u1/sun4-m3/lib/m3/libm3.a
inhale /usr/lib/libm.a

new objects -> linking TypeInTest
missing compiled interface "TrestleComm.io" imported by:
   TypeInTest.m3  
missing compiled interface "TypeInVBT.io" imported by:
   TypeInTest.m3  
missing compiled interface "HVSplit.io" imported by:
   TypeInTest.m3  
missing compiled interface "Trestle.io" imported by:
   TypeInTest.m3  
rm .m3imports
rm TypeInTest_m.o

Fatal Error: incomplete program

*** Error code 255
make: Fatal error: Command failed for target `TypeInTest'
------------------------------------------------------------

What is going on here? I think I ran "m3make clean.all" after
installing everything. Did I trash some files that I needed? libm3
is still usable. Why would "clean.all" delete files needed to 
compile Trestle programs, but not delete files needed for programs
using libm3?

Also, can Trestle programs be invoked from OpenWindows?

--

MICHAEL WERTS -- werts@csulb.edu
Computer Engineering Computer Science
California State University Long Beach


======================================================================= 37 ===
Date:    13 Feb 93 22:21:59 PST
From:    offline!marc (Marc Duponcheel)
Subject: M3 reference book

I am a C++ programmer and I would like to know more
about M3. So, is there a de-facto book (maybe from Wirth) ?

And are some C++ features present in M3 such as

multiple inheritance
virtual inheritance
virtual methods
operator and function overloading
templates
exceptions

Thanks for any reply ... It might be my trigger for M3

-- 
 preferred e-mail address
  marc@offline.UUCP

  happy Amiga 4000 user (UUCP node & FIDO point) at HOME

  happy Sun  Sparc user (mdup@cimad)             at WORK

 ==========   // ===================================================
  Thanks to \X/ Amiga for being the best computer ever ...
 ====================================================================


======================================================================= 38 ===
Date:    Thu, 18 Feb 93 09:34:30 -0800
From:    msm@src.dec.com
Subject: Re: M3 reference book


The standard reference is

Greg Nelson. System Programming in Modula-3. Prentice Hall, May 1991

The language has virtual inheritance and methods (all methods and 
instance variables are virtual; if you want non-virtuals, you make 
them module variables or procedures), templates (generics), and exceptions.  
It does not have multiple inheritance, although you can get that 
effect by using run-time type fiddling.  It doesn't have operator 
or function overloading; a lot of the demand for function loading 
goes away because M3 does have default values for parameters, and 
keyword parameter passing (which can be used in the same call as 
positional parameters); it also has modules, so that the same procedure 
name can be used to mean different things when qualified by different 
module names.  There is no support for operator overloading. 

Bottom line: 

The advantages for M3 are a cleaner type system, thread support, 
automatic garbage collection, no need for an ARM to let you know 
what the designer thought the language was supposed to mean, a rich 
and standard set of interfaces to build on top of. 

The disadvantages are no multiple inheritance (which only helps you 
for classes which noone has further subclassed anyway), no method 
syntax for non-virtual functions and variables, no operator overloading.

Mark


======================================================================= 39 ===
Date:    17 Feb 93 15:41:15 GMT
From:    buschman@slsvaat.sel.de (Andreas Buschmann US/ESI R.127 Tel.3841)
Subject: Re: yacc grammar available for Modula-3?

dsims@don.ece.uc.edu (David Sims) writes:
: Does anyone have a yacc grammar for Modula-3?

Yup, I have one.

but 
  - it is clobbered with calls to actions (I tried to implement an
    Interpreter for m3)

  - it is the language as described in 

    Luca Cardelli, James Donahue, Lucille Glassman, Mick Jordan, Bill
    Kaslow, Greg Nelson. Modula-3 Report (revised). October 1989.

    it does not include the changes from 

    Greg Nelson. System Programming in Modula-3. Prentice Hall, May
    1991

  - the grammar works ok with bison, yacc, byacc. It relies on a flex
    scanner which does more than one symbol lookahead when the keyword
    PROCEDURE is found, to decide between declarations and
    expressions. (An other idea would have been to hand information
    about the current state of the parser back to the scaner.)

If you are interested I'll dig it up from its floppy disk.

					Tschuess
						Andreas

-- 
#include <stddisclaimer.h>

 /|)	Andreas Buschmann
/-|)	SEL Stuttgart US/ESI

	buschman@us-es.sel.de


======================================================================= 40 ===
Date:    Wed, 17 Feb 1993 21:13:51 GMT
From:    werts@piggy.cecs.csulb.edu (Michael Werts)
Subject: Trestle trouble

I just looked in /lib in our Modula-3 directory. There does not appear
to be any library for Trestle, i.e. something of the form
libm3Trestle.{a|ax}. Could this cause the problem I mentioned in my
previous posting ("Difficulty using Trestle")?

--

MICHAEL WERTS -- werts@csulb.edu
Computer Engineering Computer Science
California State University Long Beach


======================================================================= 41 ===
Date:    17 Feb 93 13:13:46 +1000
From:    shtodd@vaxsar.vassar.edu
Subject: looking for xview or OLIT libs for m3

Hello,
I am tring to locate interface files for the xview and/or OLIT
libraries. I am using m3 on a sun running SunOS 4.1.1 and OpenWindows 3.
If you can help me, please write to shtodd@vassar.edu.
Thank you for your time,
 
Shad Todd


======================================================================= 42 ===
Date:    Fri, 19 Feb 1993 08:20:00 +0000
From:    Simon.Johnston@purplet.demon.co.uk (Simon Johnston)
Subject: Modula-2 standards document

To: klaeren@informatik.uni-tuebingen.de
I've just read a posting from you in the comp.lang.modula2 news group saying 
that the postscript version of the Modula-2 standards doc is 7Mb, is this 
compressed? If not is it possible to send a compressed version? If not is 
there an ftp site where I can get it from?

Thanks very much.

----------------------------------------------------------------------------
Simon Johnston - ICL Retail Systems - +44 (0)344 476320
3&4 Willoughby Road, Bracknell, Berks, RG12 4TJ, United Kingdom
S.K.Johnston.bra0801@oasis.icl.co.uk -or- Simon.Johnston@purplet.demon.co.uk  
 


======================================================================= 43 ===
Date:    21 Feb 93 20:51:50 GMT
From:    moss@cs.cmu.edu (Eliot Moss)
Subject: Re: What does `TYPE var: (CARDINAL);' mean?

If I recall correctly, there are a few (unusual) situations where parentheses
are necessary to disambiguate types. Consider the type of a procedure that
returns a procedure and might signal an exception. (I don't have my M3 book
here, but this should give you the idea):

	TYPE PPP = PROCEDURE (): PROCEDURE (): INTEGER RAISES {FOO};

This is ambiguous in terms of which procedure gets the RAISES clause.
Parentheses can disambiguate as follows:

	TYPE PP1 = PROCEDURE (): (PROCEDURE (): INTEGER RAISES {FOO});
	TYPE PP2 = PROCEDURE (): (PROCEDURE (): INTEGER) RAISES {FOO};

There may be other cases but this is the one that comes to mind. Just as with
expressions, parentheses do not change the meaning (of parsed types), but aid
the parsing. Hence, they would not appear in abstract syntax. Hence,

	VAR var: (CARDINAL);

means exactly the same thing as

	VAR var: CARDINAL;

Hope this clarifies .....					EM
--

J. Eliot B. Moss, Associate Professor	Visiting Associate Professor
Department of Computer Science		School of Computer Science
Lederle Graduate Research Center	Carnegie Mellon University
University of Massachusetts		5000 Forbes Avenue
Amherst, MA  01003			Pittsburgh, PA  15213-3891
(413) 545-4206, 545-1249 (fax)		(412) 268-6767, 681-5739 (fax)
Moss@cs.umass.edu			Moss@cs.cmu.edu


======================================================================= 44 ===
Date:    25 Mar 93 17:53:12 GMT
From:    moss@cs.cmu.edu (Eliot Moss)
Subject: GNU Modula-3 alpha release status

We said we'd try to get the initial (alpha) release of GNU Modula-3 out some
time this month (March), and we're in the process of figuring out what to
release and how to package it up. We expect to have something in roughly two
weeks (watch this space for a notice).

What would this be? First, it is a compiler for the VAX (only) under Ultrix
(only), definitely without threads, and probably still failing a small number
of the tests in the SRC test suite (which implies that not all of libm3 is
likely to work either). The actual release information will detail more about
what's working and what's not at that time. We DO currently pass all the
compiler tests that the SRC compiler did when it was first released (i.e., the
ones we fail are more obscure things that users uncovered over time).

Second, the release itself will be a compressed tar file including sources and
executables. The executables will probably work only if you put libraries,
etc., in the expected places (otherwise, you'll need to rebuild from sources).
The compiler is written in C and should be compiled with a recent version of
gcc (so you'll need gcc installed). The system also uses gld (the GNU linker).

This release should be most useful to people undertaking ports to other
machines and operating systems, since it will give them a head start on
understanding the compiler and getting the full system ready. It may be of
some use for ordinary programming, but it really depends on whether you tend
to use features that tickle the remaining bugs. We are indeed interested in
alpha test reports, but only if they tell us something new (i.e., we'll
provide a list of known deficiencies).

When the release is made, we'll also start email discussions with the various
parties who have indicated they might undertake ports, to help sort out who
will do what.

Regards, and thanks for your continued interest and encouragement --  EM
--

J. Eliot B. Moss, Associate Professor	Visiting Associate Professor
Department of Computer Science		School of Computer Science
Lederle Graduate Research Center	Carnegie Mellon University
University of Massachusetts		5000 Forbes Avenue
Amherst, MA  01003			Pittsburgh, PA  15213-3891
(413) 545-4206, 545-1249 (fax)		(412) 268-6767, 681-5739 (fax)
Moss@cs.umass.edu			Moss@cs.cmu.edu


======================================================================= 45 ===
Date:    Sun, 21 Feb 1993 19:13:40 GMT
From:    dmb@srl03.cacs.usl.edu (David M. Brumley)
Subject: Re: What does `TYPE var: (CARDINAL);' mean?

Argh, argh, argh.  I meant, "What does `VAR var: (CARDINAL);' mean?".


======================================================================= 46 ===
Date:    21 Feb 93 18:14:05 GMT
From:    dmb@srl03.cacs.usl.edu (David M. Brumley)
Subject: What does `TYPE var: (CARDINAL);' mean?

Would someone explain the semantics of the type production
`Type = "(" Type ")".'?  I can't seem to find an example in _SPwM3_
and the compiler source implies that the parens are meaningless.


======================================================================= 47 ===
Date:    Sun, 21 Feb 93 13:28:52 -0800
From:    meehan@src.dec.com
Subject: Re: What does `TYPE var: (CARDINAL);' mean?


    Would someone explain the semantics of the type production
    `Type = "(" Type ")".'?  I can't seem to find an example in _SPwM3_
    and the compiler source implies that the parens are meaningless.

The parentheses are needed to resolve [rare] cases of potential ambiguity. 
There is an example on the very last line of section 2.2.8, page 
20:

    In a procedure type, RAISES binds to the closest preceding PROCEDURE, 
    That is, the parentheses are required in:

    TYPE T = PROCEDURE (): (PROCEDURE ()) RAISES {};

Not a stellar example, since "RAISES {}" is redundant. Consider

    TYPE T = PROCEDURE (): (PROCEDURE ()) RAISES {E};
    VAR p: T;

"p" is a procedure that can raise exception E. It returns a procedure 
that raises no exceptions.

The only other place I've seen parentheses used for type-declarations 
is in revelations: 


INTERFACE Z;
TYPE T <: OBJECT slot: INTEGER METHODS p() END;
(* ... *)
END Z.

MODULE Z;
REVEAL T = (OBJECT slot: INTEGER METHODS p() END)
           BRANDED OBJECT OVERRIDES p := P END;
(* ... *)
BEGIN END Z.

The more idiomatic way to do this is to write:

TYPE Public = OBJECT slot: INTEGER METHODS p () END;
REVEAL T = Public BRANDED OBJECT OVERRIDES p := P END;

The "Public" declaration often goes in the interface.


======================================================================= 48 ===
Date:    22 Feb 93 03:49:51 GMT
From:    ednstras@kraken.itc.gu.edu.au (Michael Strasser)
Subject: Modula-3 for OS/2

It is my understanding that no-one yet has ported the SRC M3 compiler to
OS/2.  I am an OS/2 user and believe that M3 will suit it admirably, using
OS/2's built-in threads.

I would like to hear from anyone who is contemplating the port or who may
have taken tentative steps towards it (as I have done).  I am willing to
help but don't have the time to do it all myself.

Please E-mail me if you are interested.  I have a quite good general
knowledge of OS/2 architecture and will happily learn more about it and
Modula-3.

-- 
Mike Strasser                       Internet: M.Strasser@edn.gu.edu.au.
Faculty of Education
Griffith University
Brisbane, Australia


======================================================================= 49 ===
Date:    Mon, 22 Feb 1993 13:46:28 GMT
From:    gloeckler@fh-ulm.de (Thomas Gloeckler)
Subject: Re: Modula-2 standards document

In article <115.2B85599D@purplet.demon.co.uk> Simon.Johnston@purplet.demon.co.u
k (Simon Johnston) writes:

>I've just read a posting from you in the comp.lang.modula2 news group saying 
>that the postscript version of the Modula-2 standards doc is 7Mb, is this 
>compressed? If not is it possible to send a compressed version? If not is 
>there an ftp site where I can get it from?


I found it on 

  ftp.mathematik.uni-ulm.de : /pub/soft/modula/standard

  User anonymous

wfr Thomas Gloeckler


======================================================================= 50 ===
Date:    Wed, 24 Feb 1993 17:50:37 GMT
From:    barton@chopin.eche.ualberta.ca (Bob Barton System Administrator (403)4
92 5160)
Subject: RS6000 build problem

I have obtained the release 2.11 from gatekeeper.dec.com and started the build.
Everything was going fine until I started to do the m3make build_install.all
(the libm3 part worked OK) when I got the following message in the tools
section. 

Wed Feb 24 10:29:48 MST 1993 ****************************************** tools
        zcat tools-2.11.tar.Z | /bin/tar xf -
        /usr/local/bin/m3make -f m3makefile.tools all install
        mkdir tools/pp/IBMR2
        mkdir tools/coverage/IBMR2
        mkdir tools/gnuemacs/IBMR2
        mkdir tools/m3bundle/IBMR2
-------------------------------------- tools/pp/IBMR2
        /usr/local/bin/m3 -w1 -make -why -g -X1_-I../src_    -o m3pp -F.PGM_SOU
RCES -ll
new source -> compiling ../src/y.tab.c
new source -> compiling ../src/ExceptionArg.i3
new source -> compiling ../src/FBE.i3
new source -> compiling ../src/FBEPostScript.i3
new source -> compiling ../src/FBEWr.i3
new source -> compiling ../src/Parse.i3
new source -> compiling ../src/NewFormatter.i3
new source -> compiling ../src/Main.m3
new source -> compiling ../src/FBEPostScript.m3
"../src/FBEPostScript.m3", line 432: warning: potentially unhandled exception (
<ANY>)
"../src/FBEPostScript.m3", line 486: warning: potentially unhandled exception (
<ANY>)
2 warnings encountered
new source -> compiling ../src/FBEWr.m3
new source -> compiling ../src/Parse.m3
new source -> compiling ../src/NewFormatter.m3
new objects -> linking m3pp
0706-317 ERROR: Unresolved or undefined symbols detected:
                 Symbols in error (followed by references) are
                 dumped to the load map.
                 The -bloadmap:<filename> option will create a load map.
alloca

Fatal Error: program "/bin/bsdcc" failed (exit status 16)

make: 1254-004 The error code from the last command is -1.

Make Quitting.
make: 1254-004 The error code from the last command is 2.

Make Quitting.
make: 1254-004 The error code from the last command is 2.

Make Quitting.

Any suggestions? Thank you.

--,,,,
 | D |  R.L. Barton                    Department of Chemical Engineering
 | A |  Tel (403) 492-5160             University of Alberta 
 | C |  Fax (403) 492-2881             Edmonton, Alberta, Canada T6G 2G6
 | S |  Internet barton@chopin.eche.ualberta.ca
--''''


======================================================================= 51 ===
Date:    23 Feb 93 04:50:13 GMT
From:    friedl@mtndew.Tustin.CA.US (Stephen Friedl)
Subject: anybody got Modula-3 for SCO UNIX?

Hi folks,

     A customer of mine is researching languages to use for a *serious*
development environment for multiple embedded hardware platforms, and
Modula-3 has caught his eye.  We thought about using something like C
or C++, but these are either just too tough for the person off the
street who is likely to be our target developer.  After looking at it
for a while, I have become quite enamored with this language and am
looking forward to working with it.

     I got the source form the Prime Time Freeware CD and am
trying to build a version for SCO UNIX starting from the AIX386 definition,
and I am so far having no joy.  The SCO C compiler has more bugs than
Rush Limbaugh has opinions, and the debugger itself dumps
core with regularity.

     I don't have a working GNU C compiler for this platform (having
troubles with the header files), so at this point I am really stuck.
I am confident that with time I could figure it out, but I am reluctant
to rack up lots of hours on my customer's nickel.

     I would love to hear from those hardy souls who have gone down
this road, and am also interested in finding wizards-for-hire that know
the internals well (particularly the code generator).

     Thanks much,
     Stephen

P.S. - I have just requested this group from uunet's postmaster, but it
might take a day or so for this to take effect: email replies preferred.

-- 
Stephen J Friedl | Software Consultant | Tustin, CA |     +1 714 544-6561
3b2-kind-of-guy  | I speak for me ONLY |   KA8CMY   | uunet!mtndew!friedl
 
Attorneys are paranoid because they assume everybody else is dishonest too


======================================================================= 52 ===
Date:    25 Feb 93 04:41:16 GMT
From:    moss@cs.cmu.edu (Eliot Moss)
Subject: Re: Recursive data structures using generics?

This seems to me like a pretty screwy way to do things:

    INTERFACE Node;
    IMPORT NodeStack;
    TYPE
      T = OBJECT
        id: TEXT;
        stack: NodeStack.T;
      END;

You did not say, but I gather Stack(Foo).T is defined as some kind OBJECT type
with a T in it, so I suppose you get (if you macro expand by hand) a well
defined recursive Modula-3 type.

I think the reason I feel this is screwy is because it is defining a very
simple kind of recursive type across multiple modules. I would expect the
recursive aspect to be defined more locally, especially with stacks, since the
physical linking of the sturctures is inherent to the ADT Stack and should not
be exposed. (I know, you'll pull a StackRep interface out of the hat next!)

One reason to disallow circular interface dependencies is that in their
presence there is no well-defined order for compiling the interfaces, and
interfaces and modules are designed to be separately compiled. When things are
that intertwined, they should be in a single interface, so the compiler has
allt he necessary knowledge in one place. So, in a nutshell, the answer to
your question "why?" is "because of separate compilation".

Hope this helps. What would have made more sense to me would be a generic
interface along these lines (pardon syntax goofs, please):

INTERFACE Stack(Element);
TYPE T = OBJECT
           item: Element.T;
	   next: T;
	 END;
END.

Regards								-- Eliot
--

J. Eliot B. Moss, Associate Professor	Visiting Associate Professor
Department of Computer Science		School of Computer Science
Lederle Graduate Research Center	Carnegie Mellon University
University of Massachusetts		5000 Forbes Avenue
Amherst, MA  01003			Pittsburgh, PA  15213-3891
(413) 545-4206, 545-1249 (fax)		(412) 268-6767, 681-5739 (fax)
Moss@cs.umass.edu			Moss@cs.cmu.edu


======================================================================= 53 ===
Date:    24 Feb 93 20:02:44 GMT
From:    rhoover@watson.ibm.com (Roger Hoover)
Subject: Re: RS6000 build problem

In article <1993Feb24.175037.15399@kakwa.ucs.ualberta.ca>, barton@chopin.eche.u
alberta.ca (Bob Barton System Administrator (403)492 5160) writes:
|> I have obtained the release 2.11 from gatekeeper.dec.com and started the bui
ld.
|> Everything was going fine until I started to do the m3make build_install.all
|> (the libm3 part worked OK) when I got the following message in the tools
|> section. 
.....
|> new source -> compiling ../src/NewFormatter.m3
|> new objects -> linking m3pp
|> 0706-317 ERROR: Unresolved or undefined symbols detected:
|>                  Symbols in error (followed by references) are
|>                  dumped to the load map.
|>                  The -bloadmap:<filename> option will create a load map.
|> alloca
|> 
....
|> Any suggestions? Thank you.



Unfortunately the tools m3makefile is a mess.  It looks like an
attempt was made to encorporate calls to lex and yacc in the makefile,
but it was abandoned.  As a result, the makefile tries to make the
y.tab.c and lex.yy.c files in tools/pp/src, but these were generated
for the wrong system.

I posted the following last fall (along with similar fixes for the
gnuemacs tool), but they never made it into the release:
----------------------------------------------------------------------
Return-Path: root
Received: from localhost by trek.watson.ibm.com (AIX 3.2/UCB 5.64/920123)
          id AA26748; Fri, 13 Nov 1992 08:44:50 -0500
Message-Id: <9211131344.AA26748@trek.watson.ibm.com>
To: m3@src.dec.com, muller@src.dec.com
Cc: rhoover
X-External-Networks: yes
Subject: gnuemacs fixes for IBMR2
Date: Fri, 13 Nov 92 08:44:49 EST
From: Roger Hoover <rhoover@trek.watson.ibm.com>


To compile gnuemacs (from the tools package), you must
change hash.h as follows and re lex and yacc parse.lex and
parse.yacc respectively.

diff -c 2.08/gnuemacs/src/hash.h gnuemacs/src/hash.h
*** 2.08/gnuemacs/src/hash.h    Tue Mar 24 16:06:27 1992
--- gnuemacs/src/hash.h Fri Nov 13 08:34:10 1992
***************
*** 175,180 ****
--- 175,183 ----
        return(NULL);
  }

+ #ifdef _IBMR2
+ extern void exit();
+ #endif
  void
  install(where)
       PTRKEYWORDENTRY where;


======================================================================= 54 ===
Date:    Wed, 24 Feb 1993 23:48:31 GMT
From:    rhoover@watson.ibm.com (Roger Hoover)
Subject: Recursive data structures using generics?

I'd like to use generics in a recursive data structure.  For
example, consider an object type that uses the Stack generic
in SPwM3:
::::::::::::::
Node.i3
::::::::::::::
INTERFACE Node;

IMPORT NodeStack;

TYPE
  T = OBJECT
    id: TEXT;
    stack: NodeStack.T;
  END;

Now, NodeStack is a stack of Node.T.  Thus, we have:
::::::::::::::
NodeStack.i3
::::::::::::::
INTERFACE NodeStack = Stack(Node) END NodeStack.

Unfortunately this gives:
"./Node.i3", line 3: circular imports (NodeStack -> Node -> NodeStack)

Questions:

1) Is there a way to write this data structure using the stack generic?

2) Why are circular interface imports not allowed?

roger
rhoover@watson.ibm.com


======================================================================= 55 ===
Date:    26 Feb 93 23:25:20 GMT
From:    najork@cs.uiuc.edu (Marc Najork)
Subject: Re: Recursive data structures using generics?

Well, here is one way to handle the problem Roger described.
It's not pretty, but it works ...

And I agree, it would be nice to allow for cyclic imports in
interfaces, and then just compile all the interfaces in a strongly
connected component at once. Certainly feasible, but would probably
require quite some reworking of the compiler. And of course we would
have to change the language definition ... (see SPwM3 p. 43)

-- Marc Najork


::::::::::::::
NodeStack.i3
::::::::::::::
INTERFACE NodeStack = Stack(Node) END NodeStack.

::::::::::::::
Node.i3
::::::::::::::
INTERFACE Node;

TYPE T <: ROOT;

::::::::::::::
PrivateNode.i3
::::::::::::::
INTERFACE PrivateNode;

IMPORT NodeStack;
FROM Node IMPORT T;

REVEAL 
  T <: Private;

TYPE 
  Private = OBJECT
    id: TEXT;
    stack: NodeStack.T;
  END;

::::::::::::::
Node.m3:
::::::::::::::
MODULE Node EXPORTS Node, PrivateNode;

REVEAL
  T = Private BRANDED OBJECT
  END;

....


======================================================================= 56 ===
Date:    26 Feb 93 13:52:15 GMT
From:    moss@cs.cmu.edu (Eliot Moss)
Subject: Re: Recursive data structures using generics?

Ok, now I understand the programming problem that gave rise to the situation
that the compiler complained about (which induced you to complain about the
compiler :-). To recap, you wanted to implement a graph with a representation
of each Node consisting of some other data plus a Stack of the edges, i.e., a
Stack of references to Nodes.

One could readily define such a recursive type in a single interface or
module. However, in this case, Stack was already available as a separate
generic interface. You tried to instantiate it, producing Stack(Node) (being
free with notation), but this failed because the instantiated Stack interface
depends on the Node interface and vice versa, giving rise to a cycle of
interface dependencies, which is illegal.

Thus, reuse is compromised. There may be some tricky way out of this, but I
can't think of it in 30 seconds :-). It does sound like a kind of language
bug/deficiency, and upon reflection I agree that cyclic interface dependencies
don't impress me as being a fundamental problem. As you pointed out, the
compiler can read in all the interfaces and resolve the definitions in any
compilation involved, and there must already be logic to prevent reading
interfaces in more than once during a compilation.

Perhaps the SRC folks could comment further on this one?

If it is crucial you get your program up and running, you could instantiate
Stack on REFANY or OBJECT and use NARROW to extract the Node objects -- not
great, but perhaps workable.
--

J. Eliot B. Moss, Associate Professor	Visiting Associate Professor
Department of Computer Science		School of Computer Science
Lederle Graduate Research Center	Carnegie Mellon University
University of Massachusetts		5000 Forbes Avenue
Amherst, MA  01003			Pittsburgh, PA  15213-3891
(413) 545-4206, 545-1249 (fax)		(412) 268-6767, 681-5739 (fax)
Moss@cs.umass.edu			Moss@cs.cmu.edu


======================================================================= 57 ===
Date:    Thu, 25 Feb 1993 15:43:32 GMT
From:    rhoover@watson.ibm.com (Roger Hoover)
Subject: Re: Recursive data structures using generics?

In article <MOSS.93Feb24234116@CRAFTY.cs.cmu.edu>, moss@cs.cmu.edu (Eliot Moss)
 writes:
|> This seems to me like a pretty screwy way to do things:
|> 
|>     INTERFACE Node;
|>     IMPORT NodeStack;
|>     TYPE
|>       T = OBJECT
|>         id: TEXT;
|>         stack: NodeStack.T;
|>       END;
|> 
|> You did not say, but I gather Stack(Foo).T is defined as some kind OBJECT ty
pe
|> with a T in it, so I suppose you get (if you macro expand by hand) a well
|> defined recursive Modula-3 type.
|> 
|> I think the reason I feel this is screwy is because it is defining a very
|> simple kind of recursive type across multiple modules. I would expect the
|> recursive aspect to be defined more locally, especially with stacks, since t
he
|> physical linking of the sturctures is inherent to the ADT Stack and should n
ot
|> be exposed. (I know, you'll pull a StackRep interface out of the hat next!)
|> 
As I said in the original post, the stack is that in SPwM3 (Page 46).  I
do not think that I'm doing something screwy---I just want to build a
graph whose edgelists are kept in a stack.  Why should I have to write
my own stack implementation when I have Greg Nelson's?  All implementation
details of the stack are hidden.  I know it must be a valid recursive type,
because Node.T is an object type.

The 'screwy' part of this is that generics must be in seperate modules. 
Thus, to use one in a recursive type, I am forced to define the type across
multiple modules.

|> One reason to disallow circular interface dependencies is that in their
|> presence there is no well-defined order for compiling the interfaces, and
|> interfaces and modules are designed to be separately compiled. When things a
re
|> that intertwined, they should be in a single interface, so the compiler has
|> allt he necessary knowledge in one place. So, in a nutshell, the answer to
|> your question "why?" is "because of separate compilation".
I don't buy this.  The SRC compiler reads all of the imported interfaces
when I compile an interface (otherwise, it couldn't give me the circularity
error).  I see no reason why it can't read all imported interfaces and resolve
the type declarations.

|> Hope this helps. What would have made more sense to me would be a generic
|> interface along these lines (pardon syntax goofs, please):
|> 
|> INTERFACE Stack(Element);
|> TYPE T = OBJECT
|>            item: Element.T;
|> 	   next: T;
|> 	 END;
|> END.
I don't understand.  How does this give me a graph of nodes with a stack
of edges?

roger
rhoover@watson.ibm.com


