[comp.lang.modula2] Why are the loops so awkward?

cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) (06/10/90)

I've been coerced into writing a large application in Modula2 and my
confusions and biases are coming to the fore.
 
Can someone please comment on the following examples and tell
me whether I win the prize for the most abstruse interpretation
of the rules, or whether I have really understood the language
properly.  Problem: do something to every element in an array (say a string).
 
 PROCEDURE P(VAR S : ARRAY OF CHAR);
 VAR i,j   : INTEGER;
     k,n   : CARDINAL;
 BEGIN
    n := Length(S);
 
    FOR k := 0 TO n-1 DO
      process(S[k]);
    END;
    (* Wrong: For empty strings, n-1 is not a cardinal, or may be very big *)
 
    FOR i := 0 TO n-1 DO
       process(S[i]);
    END;
    (* Wrong: Can't mix INTEGER and CARDINAL in the same loop *)
 
    j := INTEGER(n);          (* Lets assume this is okay *)
    FOR i := 0 TO j-1 DO      (* The loop now goes correctly in all cases *)
       process(S[i]);
    END;
    (* Wrong: The index type of an open array is CARDINAL, so using
              an integer as a subscript is not strictly permitted. *)
 
    k := 0;
    WHILE (S[k] <> 0C) DO
       process(S[k]);
       INC(K);
    END;
      (* Wrong: Strings do not always store the trailing NUL byte. *)
 END P;
 
Am I in a grumpy mood without justifiable cause?
 
Pete



--  
uucp: uunet!m2xenix!puddle!5!494!4.0!cspw.quagga
Internet: cspw.quagga@p0.f4.n494.z5.fidonet.org

Jim.Long@p15.f42.n105.z1.fidonet.org (Jim Long) (06/10/90)

In a message of <09 Jun 90  14:04:56>, cspw quagga (5:494/4) writes:

 > PROCEDURE P(VAR S : ARRAY OF CHAR);
 > VAR i,j   : INTEGER;
 >     k,n   : CARDINAL;
 > BEGIN
 >    n := Length(S);
 >    k := 0;
 >    WHILE (S[k] <> 0C) DO
 >       process(S[k]);
 >       INC(K);
 >    END;
 > END P;

WHILE k < n DO
  ...
  INC(k);
...


--  
uucp: uunet!m2xenix!puddle!42.15!Jim.Long
Internet: Jim.Long@p15.f42.n105.z1.fidonet.org

Fred.van.der.Windt@f106.n512.z2.fidonet.org (Fred van.der.Windt) (06/12/90)

How about:
 
PROCEDURE P(VAR S : ARRAY OF CHAR);
 
VAR
  i : CARDINAL;
 
BEGIN
 
(* this works: *)
 
  IF S[0] <> CHR(0) THEN
    FOR i := 0 TO Length(S) - 1 DO
      process(S[i]);
    END;
  END;
 
(* this looks nicer: *)
 
  FOR i := 1 TO Length(S) DO
    process(S[i-1]);
  END;
 
END P;
 
> Am I in a grumpy mood without justifiable cause?
 
I think so ;-)
 
 
                Fred!


--  
uucp: uunet!m2xenix!puddle!2!512!106!Fred.van.der.Windt
Internet: Fred.van.der.Windt@f106.n512.z2.fidonet.org

Peter.M..Perchansky@f101.n273.z1.fidonet.org (Peter M. Perchansky) (06/13/90)

Hello Peter:

    Why not do the following:

    PROCEDURE P (VAR s: ARRAY OF CHAR);
    VAR
       i, len : CARDINAL;
    BEGIN
        len := Length (s);
        FOR i := 0 TO len DO
            Process (s[i])
        END;
    END P;

    1)  I am not sure why you subtracted one from the length in your example since Length should return the given values given the following examples:

        s := ''; (* empty string *)
        (* len will equal 0 *)
        s := 'Peter';
        (* len will equal 5 *)

     2)  If you must subtract one, it is better to use the following:

         len := Length (s) - 1;

         instead of subtracting 1 from len in the FOR loop (some compilers might not optimize, and the expression will have to be evaluated every time.

      3)  To catch 0 - 1 errors when using CARDINAL, you can test it first.

      IF len # 0 THEN
         DEC (len) (* or len = len - 1 *)
      END;

   If you tell me what the procedure Process does, and what you are trying to accomplish, I (or some one else) might be better able to answer your questions.



--  
uucp: uunet!m2xenix!puddle!273!101!Peter.M..Perchansky
Internet: Peter.M..Perchansky@f101.n273.z1.fidonet.org

ccc_ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) (06/13/90)

There are two interpretations of this situation:

1) Unless they're a natural fit to the problem you're trying to solve,
   stay away from zero-based arrays. Only C programmers could love them.
2) FOR-loops also have their problems. So who needs FOR, WHILE and
   REPEAT loops, anyway? Use a LOOP statement with one or more EXITs instead.

Note that neither of these points is necessarily specific to Modula-2.

Lawrence D'Oliveiro
Computer Services Dept                    fone: +64-71-562-889
University of Waikato                      fax: +64-71-384-066
Hamilton, New Zealand            electric mail: ldo@waikato.ac.nz
DOS user interfaces have come a long way: Ctrl-K-B has given way to Alt-F4.

wolniewi@boulder.Colorado.EDU (WOLNIEWICZ RICHARD HANSON) (06/13/90)

In article <728.26767558@waikato.ac.nz>
ccc_ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
>There are two interpretations of this situation:
>
>1) Unless they're a natural fit to the problem you're trying to solve,
>   stay away from zero-based arrays. Only C programmers could love them.

But look at what Modula 2 _requires_ us to use when we pass an array into a
procedure.

>2) FOR-loops also have their problems. So who needs FOR, WHILE and
>   REPEAT loops, anyway? Use a LOOP statement with one or more EXITs instead.

Using FOR, WHILE, and REPEAT loops would usually seem to be preferable to
LOOP statements with EXITs, for a number of reasons:

1) They more clearly express the intent of the programmer, and thus make the
program easier to understand in the future.

2) Avoiding EXITs makes it easier (or trivial) to determine under what
conditions the loop will terminate, making post-condition verification much
easier.

3) Since FOR, WHILE, and REPEAT provide more semantic information, a compiler
may be able to perform more optimization that in a LOOP construct.  For
example a compiler could check the constraints on the looping variable's range
in a FOR loop at compile time, whereas using INC inside of the loop might
require the code to check the constraints at run time, and on every iteration.

Usage of looping constructs can be a very religious issue, of course.  This
is just my best understanding of the issues involved.

 .    .    ______      Laboratory for Atmpospheric and Space Physics
 |   / \  (__  ._)     University of Colorado, Boulder
 |__/   \____) |       Richard Wolniewicz (wolniewi@tramp.colorado.edu)
                       Disclaimer: Only the opinions of a grad student (me)

Jim.Long@p15.f42.n105.z1.fidonet.org (Jim Long) (06/14/90)

In a message of <12 Jun 90  14:17:02>, Peter M. Perchansky (1:273/101) writes:

 >    Why not do the following:
 >
 >    PROCEDURE P (VAR s: ARRAY OF CHAR);
 >    VAR
 >       i, len : CARDINAL;
 >    BEGIN
 >        len := Length (s);
 >        FOR i := 0 TO len DO
 >            Process (s[i])
 >        END;
 >    END P;
 >
 >    1)  I am not sure why you subtracted one from the length in your 
 >example since Length should return the given values given the following 
 >examples:
 >
 >        s := ''; (* empty string *)
 >        (* len will equal 0 *)

And Process will process s[0], even though s[0] is indeterminate.

 >     2)  If you must subtract one, it is better to use the following:
 >         len := Length (s) - 1; instead of subtracting 1 from len 
 >         in the FOR loop

It depends on what 'better' means.  Some approaches take the time to save some memory space, some approaches take the space to save time.

A WHILE will avoid the need for a decrement and solve the zero length problem at once:

  i := 0;
  WHILE i < Length( s ) DO
    Process( s[ i ] ); INC( i );
  END;

 >some compilers might not optimize, and the expression will have to be 
 >evaluated every time.

Is it known that Length(s) is constant for the time duration of that loop?  That is necessary before Length(s) can be optimized for use in testing the above WHILE condition.


--  
uucp: uunet!m2xenix!puddle!42.15!Jim.Long
Internet: Jim.Long@p15.f42.n105.z1.fidonet.org

ccc_ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) (06/14/90)

In <22213@boulder.Colorado.EDU>, wolniewi@boulder.Colorado.EDU
(WOLNIEWICZ RICHARD HANSON) points out (in answer to my suggestion
about only using zero-based arrays where it makes sense to) that
Modula-2 _requires_ open arrays to be zero-based.

Agreed. In which case it may be better in some cases to avoid open
arrays, and resort to a lower-level technique, on the grounds that
this can make the code easier to understand.

The lower-level technique I'm thinking of looks like this:

	TYPE
	    ArbitraryArray = POINTER TO ARRAY [0 .. 32767] OF Whatever;

	PROCEDURE DoSomething
	  (
	    WithArray : ArbitraryArray;
	    LowBound, HighBound : CARDINAL
	  );

	    VAR
		Index : CARDINAL;

	BEGIN
	    FOR Index := LowBound TO HighBound DO
		DoSomethingWith(WithArray^[Index])
	    END (*FOR*)
	END (*DoSomething*);

	CONST
	    ThisLowBound = 99;
	    ThisHighBound = 243;
	VAR
	    MyArray : ARRAY [ThisLowBound .. ThisHighBound] OF Whatever;

    BEGIN (*Mainline*)
	DoSomething
	  (
	    ADDRESS(CARDINAL(ADR(MyArray)) - ThisLowBound * TSIZE(Whatever)),
	    ThisLowBound, ThisHighBound
	  )
    END (*Mainline*).

So long as LowBound is never passed as zero, you won't get "underflow"
problems with CARDINAL.

Yeah, sure it's yucky. But I submit that there may be sometimes when this
is better than the alternative. Not always, just sometimes.

Hanson goes on to give reasons for using FOR, WHILE and REPEAT instead
of endless-LOOP-with-EXIT:

"They more clearly express the intent of the programmer, and thus make the
program easier to understand in the future."

This is an unwarranted generalisation. Consider the following example
(it should be pretty much self-explanatory):

	LOOP
	    IF NrCharsLeft = 0 THEN
		StringsSame := TRUE;
		EXIT
	    END (*IF*);
	    INC(SourceIndex);
	    DEC(NrCharsLeft);
	    IF String1[SourceIndex] <> String2[SourceIndex] THEN
		StringsSame := FALSE;
		EXIT
	    END (*IF*)
	END (*LOOP*)

Do you think you could write it just as simply and clearly using something
other than LOOP? I don't think so. Do you think this is an unusual example?
I find that, in my programs, the majority of my loops are best written
using LOOP-with-EXIT rather than WHILE, REPEAT or FOR.

"Avoiding EXITs makes it easier (or trivial) to determine under what
conditions the loop will terminate, making post-condition verification much
easier."

See above example again.

The third point, about compiler optimisation--I admit Hanson has a
point here. But if compilers were smarter, there would be less of a
need for special-case constructs, so we can then avoid burdening the
language (and the programmer) with them.

Loops a religious issue? Now why would that be? In my days as a Computer
Science student we used to argue about this sort of thing all the time.
So long as the debate stays calm and reasonable, I'm happy to take part in
it!

Lawrence D'Oliveiro
Computer Services Dept                    fone: +64-71-562-889
University of Waikato                      fax: +64-71-384-066
Hamilton, New Zealand            electric mail: ldo@waikato.ac.nz
New mistakes are the only kind worth making.

pseemann@inf.ethz.ch (Patrick Seemann) (06/14/90)

You may replace the FOR by a WHILE loop:

  n := Length (s);
  i := 0;
  WHILE (i < n) DO
    (* process s[i] *)
    INC (i);
  END (* WHILE *);

greetings, pat

moeller@uniol.UUCP (Klaus Moeller) (06/14/90)

ccc_ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:

>This is an unwarranted generalisation. Consider the following example
>(it should be pretty much self-explanatory):

>	LOOP
>	    IF NrCharsLeft = 0 THEN
>		StringsSame := TRUE;
>		EXIT
>	    END (*IF*);
>	    INC(SourceIndex);
>	    DEC(NrCharsLeft);
>	    IF String1[SourceIndex] <> String2[SourceIndex] THEN
>		StringsSame := FALSE;
>		EXIT
>	    END (*IF*)
>	END (*LOOP*)

>Do you think you could write it just as simply and clearly using something
>other than LOOP? I don't think so. Do you think this is an unusual example?
>I find that, in my programs, the majority of my loops are best written
>using LOOP-with-EXIT rather than WHILE, REPEAT or FOR.

Of course no. But this was meant for loops with only one exit.
You must use LOOP for loops that have more than one exit point
simply because you can't do that with FOR, WHILE or REPEAT. But when
you have only one exit point, WHILE, FOR and REPEAT are much clearer.
In C you can have while and for loops with additional exits in them, Modula
prohibits this. I suppose that Wirth wanted to isolate this in pure LOOPs.
The Semantics of while, repeat and for become much easier this way.

					Klaus
-- 
   /---------------------------------------------------------------------\
  /  Klaus Moeller, Leiteweg 2, 2940 Wilhelmshaven, West - Germany        \
  |  UUCP : moeller at uniol.uucp  | BITNET   : 078326 at DOLUNI1.BITNET  |
  |~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~|
  \    Fill what's empty, empty what's full and scratch where it itches   /
   \---------------------------------------------------------------------/

wolniewi@boulder.Colorado.EDU (WOLNIEWICZ RICHARD HANSON) (06/15/90)

In article <747.2677cd57@waikato.ac.nz> ccc_ldo@waikato.ac.nz
(Lawrence D'Oliveiro, Waikato University) writes:
>In <22213@boulder.Colorado.EDU>, wolniewi@boulder.Colorado.EDU
>(WOLNIEWICZ RICHARD HANSON) points out (in answer to my suggestion
>about only using zero-based arrays where it makes sense to) that
>Modula-2 _requires_ open arrays to be zero-based.
>
>Agreed. In which case it may be better in some cases to avoid open
>arrays, and resort to a lower-level technique, on the grounds that
>this can make the code easier to understand.
>
>The lower-level technique I'm thinking of looks like this:

 [Code using pointer to array and array bounds passing]

>Yeah, sure it's yucky. But I submit that there may be sometimes when this
>is better than the alternative. Not always, just sometimes.

I do agree that there are times that this technique would be useful (I
frequently want to get around the array renumbering Modula 2 forces on us)
but I would hesitate to use this in most situations, since it complicates
the procedure interface and might discourage the next programmer on the
project from re-using the code.  In the specific instance of avoiding a
CARDINAL value constraint, a simple IF statement around the loop would
seem easier.

 [D'Oliveiro then disagrees that using LOOP constructs instead of FOR ...
  makes the code more difficult to understand, and offers the following code
  as an example.]

>	LOOP
>	    IF NrCharsLeft = 0 THEN
>		StringsSame := TRUE;
>		EXIT
>	    END (*IF*);
>	    INC(SourceIndex);
>	    DEC(NrCharsLeft);
>	    IF String1[SourceIndex] <> String2[SourceIndex] THEN
>		StringsSame := FALSE;
>		EXIT
>	    END (*IF*)
>	END (*LOOP*)
>
>Do you think you could write it just as simply and clearly using something
>other than LOOP? I don't think so.

I would probably write

    stringsSame := TRUE;
    WHILE stringsSame AND (index <= stringLength) DO
        stringsSame := (String1[index] = String2[index]);
        INC(index);
    END; (* WHILE *)

Here I think it is just as clear, if not more so, that the intent of the
programmer is to terminate the loop with stringsSame set correctly, and that
the loop will terminate when a difference is found or the index exceeds the
string length.  Of course, this is where the opinionated nature of looping
constructs comes in.

>Loops a religious issue? Now why would that be? In my days as a Computer
>Science student we used to argue about this sort of thing all the time.
>So long as the debate stays calm and reasonable, I'm happy to take part in
>it!

I agree!  That's why I have subscribed to this group, after all; to take part
in discussions which will hopefully help us do this programming thing better.

p.s. Hansen is my middle name, which the University recorded incorrectly.
Please feel free to call me 'Richard', 'Wolniewicz' being somewhat cumbersome.

 .    .    ______      Laboratory for Atmpospheric and Space Physics
 |   / \  (__  ._)     University of Colorado, Boulder
 |__/   \____) |       Richard Wolniewicz (wolniewi@tramp.colorado.edu)
                       Disclaimer: Only the opinions of a grad student (me)

touch@dsl.cis.upenn.edu (Joe Touch) (06/15/90)

In article <22259@boulder.Colorado.EDU> wolniewi@tramp.Colorado.EDU (WOLNIEWICZ RICHARD H.) writes:
>
>I would probably write
>
>    stringsSame := TRUE;
>    WHILE stringsSame AND (index <= stringLength) DO
>        stringsSame := (String1[index] = String2[index]);
>        INC(index);
>    END; (* WHILE *)
>

I'd prefer

	WHILE (index <= stringLength) AND (String1[index] = String2[index] DO
		INC(index);
	END; (* WHILE *)

Unless my book is wrong, M2 is defined as having short-circuit evaluation
of conjunctions and disjunctions.  So if the index is out of bounds,
the string element comparison never occurs, and the AND is safe.

This omits the use of a redundant boolean (logical) variable, 
and not only is ir correct, but it will run faster (you don't
really need to store the value of the comparison, do you?)

I'd like to add that loops aren't awkward, but some PROGRAMMERS 
implementation of them IS. ;-)

Joe Touch

PS - A good text for a M2 course is "Modula-2" by Beidler and Jackowitz,
PWS Publishers, 1986 (approx).  It was developed by my advisor
at the University of Scranton when I was there, where M2 has been
used as a primary teaching language since 1984.

Jim.Long@p15.f42.n105.z1.fidonet.org (Jim Long) (06/15/90)

In a message of <14 Jun 90  17:07:42>, cspw quagga (5:494/4) writes:

 >There have been a number of suggestions that my awkward problem
 >of processing every element in a string should be coded
 >like this
 >    i := 0;
 >    WHILE (i < Length(s)) DO
 >       process(S[i]);
 >       INC(i);
 >    END;
 > 
 >Although this works nicely, it violates all the ideas that one
 >should distinguish between definite loops (where the number of iterations
 >is known in advance, and a FOR loop is the most appropriate
 >construct), and an indefinite loop where one iterates until or while
 >the conditions have not been fulfilled.

Without seeing the definition of 'process(CHAR)' we cannot determine from this code fragment which type of loop we have.  If S[i] is passed as a VAR CHAR, the loop may be indefinite.


--  
uucp: uunet!m2xenix!puddle!42.15!Jim.Long
Internet: Jim.Long@p15.f42.n105.z1.fidonet.org

cspw.quagga@p0.f4.n494.z5.fidonet.org (cspw quagga) (06/15/90)

 
There have been a number of suggestions that my awkward problem
of processing every element in a string should be coded
like this
    i := 0;
    WHILE (i < Length(s)) DO
       process(S[i]);
       INC(i);
    END;
 
Although this works nicely, it violates all the ideas that one
should distinguish between definite loops (where the number of iterations
is known in advance, and a FOR loop is the most appropriate
construct), and an indefinite loop where one iterates until or while
the conditions have not been fulfilled.  So although this loop
satifies the problem, imho it is stylistically bad.
 
Pete
 
 
--
EP Wentworth - Dept. of Computer Science - Rhodes University - Grahamstown.
Internet: cspw.quagga@f4.n494.z5.fidonet.org
Uninet: cspw@quagga
uucp: ..uunet!m2xenix!quagga!cspw



--  
uucp: uunet!m2xenix!puddle!5!494!4.0!cspw.quagga
Internet: cspw.quagga@p0.f4.n494.z5.fidonet.org

Cameron.Barnard@f715.n153.z1.fidonet.org (Cameron Barnard) (06/15/90)

I've read several of the answers people have given you and they are good but 
I'm not sure that they were what you were looking for.

It is difficult to tell exactly what you are trying to do from the small 
segments of code you gave as examples but here is some general advice.

If you have ever programmed in BASIC or any other unstructured language you 
will do best to forget everything you have learned there.

Modula-2 is a highly structured language that is extremely powerful but can be 
tricky to use because YOU HAVE TO HAVE A DEFINITE PLAN OF ACTION BEFORE YOU 
EVEN BEGIN TO START PROGRAMMING.  This has advantages and disadvantages.  You 
have a lot of power but it takes a while to get the hang of it.

I used to program in BASIC and found Modula-2 quite difficult to learn but now 
that I am familar I will NEVER go back to basic.  (Unless I want to write 
something really quick and dirty.)

I highly reccomend a book by Rick Sutcliffe titled INTRODUCTION TO PROGRAMMING 
USING MODULA-2.  It is published by Merrill and is an excellent and very 
readable book.

Good Luck and hang in there!

Cameron Barnard.


--  
uucp: uunet!m2xenix!puddle!153!715!Cameron.Barnard
Internet: Cameron.Barnard@f715.n153.z1.fidonet.org

wolniewi@boulder.Colorado.EDU (WOLNIEWICZ RICHARD HANSON) (06/15/90)

In article <26032@netnews.upenn.edu>
touch@dsl.cis.upenn.edu (Joe Touch) writes:
>I'd prefer
>
>	WHILE (index <= stringLength) AND (String1[index] = String2[index] DO
>		INC(index);
>	END; (* WHILE *)
>
>Unless my book is wrong, M2 is defined as having short-circuit evaluation
>of conjunctions and disjunctions.  So if the index is out of bounds,
>the string element comparison never occurs, and the AND is safe.

This is something I had never known before.  I assumed short-circuit
evaluation was in use, but I also (apparently incorrectly) assumed that the
compiler could evaluate the expressions in whatever order it found to be
optimal.  Could someone find the reference for this?  If this is true, I look
forward to taking advantage of it.

>This omits the use of a redundant boolean (logical) variable, 
>and not only is ir correct, but it will run faster (you don't
>really need to store the value of the comparison, do you?)

I think you do need that comparison result (remember my example was based upon
another netter's previous example).  Why compare two strings if you aren't
going to use the comparison result?

 .    .    ______      Laboratory for Atmpospheric and Space Physics
 |   / \  (__  ._)     University of Colorado, Boulder
 |__/   \____) |       Richard Wolniewicz (wolniewi@tramp.colorado.edu)
                       Disclaimer: Only the opinions of a grad student (me)

beers@acsu.Buffalo.EDU (Andrew Beers) (06/16/90)

M2 IS defined as having short circuit evaluation of expressions, but it is
the implementer's choice whether or not to have the compiler use it.  Not
all features of every language are implemented in every compiler.  :(

Andrew Beers
------------
beers@autarch.acsu.buffalo.edu
Suny @ Buffalo
Buffalo, NY

jem@cs.hut.fi (Johan Myreen) (06/20/90)

In article <22422@boulder.Colorado.EDU> wolniewi@boulder.Colorado.EDU (Richard Wolniewicz) writes:

>(not clearly stated in my last posting) is this; does the Modula 2 language
>insure that a short circuit evaluation of an expression will evaluate the
>different components in order of appearance in the code.  For example, in the
>code below,

>IF A() OR B THEN ...

>where A is a function call returning a BOOLEAN, and B is a BOOLEAN variable,
>does Modula 2 insure that A will be called, or could the compiler optimize

Yes. Also, if A() is TRUE, B will not be evaluated at all.  The order
is left to right, and as soon as the result is known evaluation stops.

Someone said in an earlier message that this was not the case in some
compilers, and that it is the implementer's choice whether the
compiler supports this feature or not. This is not true. If a compiler
doesn't implement short circuit evaluation, it isn't a Modula-2
compiler.

--
Johan Myreen
jem@cs.hut.fi

Peter.M..Perchansky@f101.n273.z1.fidonet.org (Peter M. Perchansky) (06/26/90)

Hello Jim:

In a msg dated 23 Jun 90  08:09:06, Jim Long said:
**********************BEGIN QUOTE*****************************

In an article of <21 Jun 90 15:40:03 GMT>, lins@Apple.COM (Chuck
Lins) writes:

 >        Compilers are allowed to strip dead code. Constant
boolean
 >        expressions may never need to be evaluated at run-time
at all.

I haven't tested my Modula-2 system in this regard, but I recall
years ago   that UCSD p-System's Pascal compiler treated BOOLEAN
constants in IFs like   conditional compilation.  If the
constant was FALSE, the compiler would not   generate code for
the THEN clause.  Does anyone know of any M2 compilers with
this feature? 
***********************END QUOTE******************************

    Although I don't know of any compilers having this feature, I do know of one that comes close.

    TopSpeed Modula-2 2.00 has compiler pragmas for conditional compilation.  A very short example follows:

    CONST DEBUG = TRUE;
    ...
    BEGIN
     ...
         (*%T DEBUG *)
         (* DEBUG STATEMENTS *)
         (* FOLLOW HERE      *)
          ...
         (*%E *)
     ...
    END;



--  
uucp: uunet!m2xenix!puddle!273!101!Peter.M..Perchansky
Internet: Peter.M..Perchansky@f101.n273.z1.fidonet.org

borchert@MATHEMATIK.UNI-ULM.DE (Andreas Borchert) (06/27/90)

Jim Long writes:

> In an article of <21 Jun 90 15:40:03 GMT>, lins@Apple.COM (Chuck Lins) writes:
>
>  >        Compilers are allowed to strip dead code. Constant boolean
>  >        expressions may never need to be evaluated at run-time at all.
>
> I haven't tested my Modula-2 system in this regard, but I recall years ago
> that UCSD p-System's Pascal compiler treated BOOLEAN constants in IFs like
> conditional compilation.  If the constant was FALSE, the compiler would not
> generate code for the THEN clause.  Does anyone know of any M2 compilers with
> this feature?

At least all Modula-2 compilers which descend from the Lilith Modula-2 compiler
have this feature.

Andreas Borchert
--
borchert@mathematik.uni-ulm.de
borchert@dulruu51.bitnet