[comp.sys.mac.programmer] Metrowerks Modula-2 ramblings

ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) (09/24/90)

I got the Metrowerks Modula-2 compiler for MPW a few days ago,
and after nodding my head at some of the demos, I wrote my first
couple of Modula-2 programs on the Mac today. I thought I'd share
some very preliminary impressions, in the hope that there a few
other folks out there who have given up on the arguments over
Pascal-versus-C and decided to move on to a decent language...

First of all, I should warn you about the crummy licence agreement.
On the page after the credits, in the MPW manual supplement, it
says "You may not rent, lease, sell or give away copies of the
software ... nor include these copies in any package which you then
distribute. You may not reverse assemble or reverse compile the
software."

This is pretty rough. Let's take the second part first: You may
not disassemble or decompile the software. I had to do exactly
that this morning, to figure out some internals of the run-time
library. I was trying to write an FKEY, which I managed to get
working just fine. In the process, I had to find the main module
in MRuntime.o, so that I could remove it and prevent clashes with
my code for defining the FKEY entry point. I couldn't just leave out
the entire library, because it had some other bits in it which
the program needed.

And the next thing I had to do was check to see if any part
of their code needed access to global variables, which would have
made it unusable in an FKEY. I found that their glue for BlockMove
was making an assignment to a global variable called "err".
Exit their glue code, enter some custom inline code.

And what about the sentence that says you may not include copies
in any package that you distribute? It's not clear whether this
applies to library routines linked into your programs. Could it
be you aren't allowed to distribute programs containing *any* such
code?

To make it worse, the next paragraph says "All these actions are in
violation of the license agreement and we will prosecute anyone
who attempts to do so."

They'll never take me alive...

But enough of the depressing stuff. In my view, Modula-2 doesn't
remedy enough of the flaws in Pascal, but it seems to be enough
of an improvement to be widely considered a "serious" programming
language. Its scope control is very tight, and a sizeable program
is liable to have IMPORT and EXPORT lists all over the place. Also
it's case-sensitive, which personally annoys the hell out of me.
But it's got the low-level access, and the separate compilation,
and it doesn't sacrifice the type-safeness (at least, not much).

Metrowerks actually sell three different versions of their compiler
for the Mac, and there is even one for MIPS machines. Besides
the MPW version and a "student" version, there is the "Professional
Stand-alone Edition" (PSE), which is a custom development environment
all on its own.

I had a look at the PSE version when I was at a conference where
they were showing the product at a stand. The one thing I wanted to
know was, since they have their own custom linker, do they implement
*proper* checking for circular imports?

For those not familiar with Modula-2, modules may have initialisation
code which is automatically executed before the program starts
using stuff from those modules. If a modula A refers to things in
module B, then the initialisation code for B is guaranteed to execute
before that for A. It's a very naughty programming practice to have
a module A which depends on module B which depends on module C which
in turn depends on module A, but for some reason Niklaus Wirth
is very coy about actually denouncing this practice: he just says
that the results in this case are "undefined".

Speaking of Wirth, does anybody know a good book mail-order firm so I
can order a copy of "Programming in Modula-2", 4th Ed? It's hopeless
trying to order books from bookshops in this country: they keep
telling you it'll take 4 months to arrive via surface mail.

Anyway, to get back to PSE, what I wanted to know was, would the
linker detect a circular import situation, and issue some kind of
warning? (It was too much to hope that it would disallow the
circularity altogether). The answer was: nope, not a peep. There
didn't even appear to be an option to produce such a warning.

So, having decided that Metrowerks had blown the one advantage
that they could have offered with a custom stand-alone development
environment, and being an MPW freak from way back, I ordered the
MPW version.

The language has changed a little since I last seriously played with
it, in 1985. Back then, definition modules had to have an explicit
list of the names that they exported; now, the assumption is that
everything you put in the definition part is exported. It makes
sense, I guess.

One welcome improvement is that type casting is no longer done
as it is in UCSD-style Pascal (as on the Mac), using TypeName(Value);
you have to use the CAST function, as follows: CAST(TypeName, Value).
And you have to explicitly import CAST from the SYSTEM module. This
is a good way to prevent mistakes, and make sure that your low-level
stuff is confined to the places that you think it's in. If you
think this is a nuisance, just stop and think about the difference
between ADR(x) and ADDRESS(x) (using old-style type casts), and how
easy it would be to confuse them.

Actually, you can still compile programs using old-style type casting;
you need to specify a compiler command-line option to allow this.

One thing that's always annoyed me about Modula-2 is that you can't
pass the addresses of routines nested within other routines. In the
Mac Pascals, you can use the "@" operator to get the address of
a variable, function or procedure, but this value didn't have any
meaningful type, so all your operations on it were totally unsafe.
Modula-2 and C remedy this particular defect, but only Modula-2
avoids throwing out the baby with the bathwater by keeping the
ability to declare a routine as local to another.

The problem with calling inner routines is that you have to
pass the correct "static link" value on a call, so that the routine
can make references to variables and things declared in an outer
routine. Actually it's very easy to cover up the necessity for this
"special" treatment, but it involves generating code at run-time,
and many people feel squeamish about this, for some reason.

Anyway, the Metrowerks compiler does offer an escape: you can
use the ADR function to take the address of an inner routine,
which you could then "bind" to the static link value, and then
cast to the appropriate PROCEDURE type. The intermediate steps
are somewhat low-level, but the result is still type-safe.

One restriction with no work-around is that you aren't allowed
underscores in identifiers. I personally prefer "red_ball" (which
I like to write as "Red_ball" occasionally) to "RedBall". Unfortunately,
the Metrowerks compiler uses the underscore as a separator between
the parts of the names it generates in the object code. For
example, a procedure "TheProc" exported from a module "TheModule"
is named "TheModule_TheProc" in the object code.

I haven't had a play with the symbolic debugging yet. It's
apparently SADE-compatible--I guess it pretends to be Pascal
to the debugger.

What else--the calling conventions are similar to, but not quite
Pascal. The arguments are pushed on the stack in Pascal order
(so they end up backwards), but value arguments are always
passed by value, even if they're bigger than four bytes. Each
routine expects the caller to save all the registers by default,
which can cause you grief if you're writing code to be called
by someone else. Luckily, you can insert a call to SYSTEM.SAVEREGS
right at the start of the routine body, and the compiler will
adopt the Pascal convention and save the usual registers.

I'm looking forward to playing some more with the compiler.
In my list of custom submenus which give me quick access to
all the language interface files, I've put Modula-2 in the
number 2 position, after Pascal. Who knows, someday I may move
it to number 1.

Lawrence D'Oliveiro                       fone: +64-71-562-889
Computer Services Dept                     fax: +64-71-384-066
University of Waikato            electric mail: ldo@waikato.ac.nz
Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
"I never feel like I do when I think I should."