gm2
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gm2] Use of functions in expressions


From: Andreas Fischlin
Subject: Re: [Gm2] Use of functions in expressions
Date: Mon, 17 Nov 2008 00:37:06 +0100
User-agent: Thunderbird 2.0.0.17 (Macintosh/20080914)

Dear Scott,

Thanks for explaining this in more detail. To avoid this story getting too big: The code example you give below has exactly the same problems as the previous one. It is all syntactically illegal in all Modula-2 dialects and all language implementations I know of.

In short: You have to rewrite the code to introduce a temporary variable.

Moreover, please don't argue this restriction to be an inconsistency in the original language definition. On the contrary, this language property is purposefully and carefully designed that way. That definition avoids syntax difficulties and compiler building difficulties, in particular with code generation. Arguing that some other languages might offer similar features as you seem to be interested in, is not particularly helpful either, since those languages may be based on very different language philosophies. What you try to accomplish, is simply not possible in Modula-2.

If you fear to have to make too many changes while porting existing code to gm2, asking for such features as you seem to imply, i.e. dialect introduction, is IMHO not the way to go. We should for good reasons stick to the language syntax as carefully designed. If the former is your concern, I'd rather consider to program a code translation assistant, if  you have hundreds of such constructs. tcl commands such as regsub, available from within AlphaX (http://alphatcl.sourceforge.net/wiki/) might be a solution. Or a Modula-2 program similar to the cross-reference generator you find in PIM (PIM2, p. 87-92, section 25 "Program decomposition into modules") or parts from a compiler. We have done both successfully (XREF in RAMSES Extras http://www.sysecol.ethz.ch/SimSoftware/SimSoftware.html#RAMSES_Extras). Even if such an assistant gives you only a partial solution that requires additional manual editing, it can already safe you lots of time. Such a translation assistant may generate a temporary variable declaration at the wrong place in the code. But if it is already generated, translation becomes much easier, since you need only to move the declaration to the proper place, not write it from scratch. Modula-2 compilers will help you to avoid any mistakes, since forgetting about any such move will be picked by the compiler and you learn about it already at compile time.

Regards,
Andreas
 

Cited References:
----------------------
PIM2: Wirth, N., 1983 (2 (corr.) ed.). Programming in Modula-2. Springer-Verlag: Berlin a.o, 176 pp.


Scott Robinson wrote:
Hi Andreas,

I apologize for not explaining the situation thoroughly so I'll do so
now.  I have some existing Modula-2 code that was built with an
internal version of a Modula-2 compiler (the compiler was never sold
as a separate product).   I would like to run that code through gm2
since it will allow me to port the code to a different
architecture...hopefully with minimal effort.  It will also be an
excellent test for the gm2 compiler.  The main problem is that this
internal Modula-2 compiler has some non-standard enhancements so
whenever I run into something that doesn't compile through gm2 I have
to figure out if it is a problem with the gm2 parser (which is a beta)
or if it is a problem with the original Modula-2 code being
non-standard.  Hopefully that explains the questions I am posting to
the list since I don't have access to either the ISO Modula-2 standard
or  other production Modula-2 compilers.

Now to answer your particular points:

I'm not particularly interested in arguing the pros and cons of the
ISO Modula-2 standard especially since I don't have access to it :-).
However, it is a standard so I am assuming that Gaius is at least
designing the gm2 parser to accept language constructs accepted by
that standard as opposed to restricting it to Wirth (1983).  Hopefully
if there are production compilers out there that accept non-standard
language constructs Gaius is at least considering inclusion of those
constructs otherwise there would be porting difficulties moving
existing Modula-2 code from those compilers to gm2.

In regards to my example, evidently it wasn't acceptable so I'll try a
different one with a function returning a pointer instead:

MODULE test1;

FROM InOut   IMPORT WriteString, WriteCard, WriteLn;

TYPE
  tItemPtr = POINTER TO tItemNode;
  tItemNode =
    RECORD
      key   : CARDINAL;
      value : CARDINAL
    END;

  tListPtr = POINTER TO tListNode;
  tListNode =
    RECORD
      item : tItemPtr;
      next : tListPtr
    END;

PROCEDURE FindItem(list : tListPtr; key : CARDINAL) : tItemPtr;
BEGIN
  (* Empty to make this shorter *)
  RETURN NIL
END FindItem;

VAR
  list : tListPtr;

BEGIN

  (* Code to build the list here *)

  (* Attempting to dereference a pointer '^' returned by a function within
     an _expression_ results in a compile failure. *)
  WriteString("The value with key 3 is ");
  WriteCard(FindItem(list, 3)^.value, 1);
  WriteLn;

  (* Code to destroy the list here *)

END test1.

The gm2 compiler gives the following error when compiling the above example:

#gm2 -c test1.mod
test1.mod:36:3: error: syntax error, found `^'
test1.mod:36:3: error: syntax error, `)' missing
test1.mod:36:3: error: syntax error, `END' missing
test1.mod:36:3: error: inconsistant program module name
test1.mod:36:3: error: syntax error, `.' missing
test1.mod:36:3: error: syntax error, found `,'
test1.mod:42:1: error: compilation failed

Because of the above error, I would have to store the function result
into a temporary variable and then do the pointer dereference using
the temporary.  Thus a function returning a POINTER has inconsistent
behavior versus a function returning a REAL, INTEGER, or
CARDINAL...all of which can be used immediately in the _expression_
without storing into a temporary first.  My opinion is that that
inconsistency is a design flaw in the Modula-2 language definition as
specified in Wirth (1983) and I am wondering if the ISO Modula-2
standard fixed the inconsistency by allowing the above syntax?  I am
also interested if any other Modula-2 compilers accept it?

Your suggestions on how to change the code aren't relevant (to me
anyways) since I have no intention of going to that much effort to
port the code to gm2.

You asked "why do I want to have string expressions?"  Well, to get a
specific character out of it would be one reason.  Other languages
treat strings as first class data types and have quite a few
operations defined on them (length, replication, splicing,
concatenation, etc).  All of those make perfect sense to use on a
string in an _expression_.

Those BNF diagrams you are pointing me to are derived from Wirth
(1983) and not the ISO Modula-2 standard (see
http://cui.unige.ch/db-research/Enseignement/analyseinfo/Modula2/) so
they do not provide the information I am after.

Thanks,
Scott

Cited references:
--------------------
Wirth, N., 1983 (2 (corr.) ed.). Programming in Modula-2.
Springer-Verlag: Berlin a.o, 176 pp.

On Sun, Nov 16, 2008 at 9:12 AM, Andreas Fischlin
<address@hidden> wrote:
  
Hi Scott,

Exactly because of such rather messy code did Wirth in his original language
defintion NOT allow for such constructs. That some compilers accept such
code is actually only due to the ISO standard of Modula-2. Prior to this
your first formulation was not legal either and since I am not an adept with
the ISO standard, I have no strong opinions about the pros and cons of this
ISO extension of the original Modula-2. I'm wary it might complicate matters
unnecessarily, something fundamentally at odds with Modual-2. Remember also
that the ISO standard is not without difficulties, which makes people like
me rather sceptical with respect to its benefits, except for settling on a
standard library (but that has little to do with the language itself). In
this context see also 10 little Modulans...
http://www.scifac.ru.ac.za/cspt/sc22wg13.htm#Ten .

More specifically:

First, please note that I see very little reason to write in Modula-2 such
code as you wrote. Function procedures should be used only if they return a
well defined object, e.g. a real variable, if they have no side effects and
if they can be used in place of a variable in an _expression_ (e.g. think of
it as a factor
http://cui.unige.ch/db-research/Enseignement/analyseinfo/Modula2/factor.html).
Therefore my first question to you whould be: Why do you want to have string
expressions? Unless you would have some applications where you really want
to multiply a string meaningfully with a number - or something similarly
exotic - I see little sense in that. Modula-2 is helping you to stay away
from such applications. Conclusion: use a procedure, NOT a function
procedure.

Second, when you comment some code by "this works", "this does not work"
then it is not clear what you mean from that. You should in general always
distinguish between, code that can be compiled, because the compiler accepts
it as legal, or whether the code does fail during execution, typically
causing a run-time error. From what you write further down I guess that you
mean "can be compiled" vs. "can't be compiled".

Thirdly,  Write(tester()[4]);  is a phantasy code clearly in conflict with
any Modula-2 syntax I know of. It conflicts with the BNF for a procedure
call (see
http://cui.unige.ch/db-research/Enseignement/analyseinfo/Modula2/procedure_call.html).
Therefore any Modula-2 compiler should reject it as syntactically wrong.

A correct solution to what you try to do would be:

PROCEDURE Tester(VAR s: ARRAY OF CHAR);
BEGIN
    Assign("testing",s);
END Tester;

BEGIN
   Tester(temp); WriteString(temp);
   ...

That is all not very complicated and IMHO quite elegant code. Why trying
something different that gives you and compiler builders only trouble?

I recommend you give up on your idea of using a function procedure in
relation with strings as illustrated above. Of course, there are some rather
rare cases in which it may make sense to work with function procedures with
respect to strings. E.g. if such a function returns an opaque string object
or a single CHAR. See this module from the 'Dialog Machine' for such
procedures:

    http://se-server.ethz.ch/RAMSES/Objects/DM/DMStrings.html#DMStrings
   (with Comments)

http://se-server.ethz.ch/RAMSES/Objects/DM/DM_Quick_Reference.html#DMStrings
   (without Comments)

The case of a single CHAR may be interesting in a conversion function such
as

    PROCEDURE Upper(ch: CHAR): CHAR;
    BEGIN
        RETURN CAP(ch)  (*  should of course be something more meaningful *)
    END Upper;

and its application

    PROCEDURE StringToUpper(VAR s: ARRAY OF CHAR);
        VAR i,n: INTEGER;
    BEGIN
        n := HIGH(s); WHILE (i<=n) AND (s[i]<>0C) DO s[i] := Upper(s[i]);
INC(i) END;
    END StringToUpper;

all not very useful, but I hope illustrative.

In general, please note also, Modula-2 is NOT C and arrays, including
strings, should be considered what they are, a structured data type that has
first of all nothing to do with  dynamic data as passed by function
procedures via the stack or pointers referencing data in the heap. An array
is a static data structure with a finite size allocated by the compiler at
compile time. It faciliates repetitive operation on its element, which, BTW,
can be very complex, i.e. it can be an entire RECORD of a very complex type.

Hope this helps to solve your problems.

Sincerely yours,
Andreas Fischlin



Scott Robinson wrote:

Hi all,

I have another Modula-2 language question about function results and using
them in expressions.  Specifically, it seems that the language allows you to
return an array or a pointer but apparently (at least according to the GM2
compiler) does not allow you to turn around and use an array subscript to
access a particular element of the array within an _expression_.  The pointer
dereference operator '^' also appears to be illegal after a call to a
function.

A specific example:

MODULE test1;

FROM InOut IMPORT WriteString, Write, WriteLn;

TYPE
 tArr = ARRAY [0..9] OF CHAR;

VAR
 temp : tArr;

PROCEDURE tester() : tArr;
BEGIN
 RETURN "testing";
END tester;

BEGIN

 (* This works *)
 WriteString("The 5th character returned is ");
 temp := tester();
 Write(temp[4]);
 WriteLn;

 (* This does not work *)
 WriteString("The 5th character returned is ");
 Write(tester()[4]);
 WriteLn;

END test1.

GM2 gives the following for the above:

# gm2 -c test1.mod
test1.mod:26:3: error: syntax error, found `['
test1.mod:30:1: error: compilation failed

I'm wondering if the Modula-2 ISO standard specifically disallows that
syntax?  And, if anyone has access to other Modula-2 compilers, do those
compilers accept the above?

Thanks,
Scott



_______________________________________________
gm2 mailing list
address@hidden
http://lists.nongnu.org/mailman/listinfo/gm2

--

________________________________________________________________________
Dr. Andreas Fischlin, Ph.D., Group Director

Terrestrial Systems Ecology
Institute of Integrative Biology: Ecology, Evolution, Infectious Disease
Department of Environmental Sciences, ETH Zurich

Address:
ETH Zurich, CHN E21.1
8092 Zurich, Switzerland

Phone: +41 44 633-6090 / Fax: +41 44 633-1136
http://www.sysecol.ethz.ch/Staff/af/
http://www.sysecol.ethz.ch/

     _/_/_/ _/_/_/ _/  _/
    _/       _/   _/  _/   Eidgenoessische Technische Hochschule Zuerich
   _/_/_/   _/   _/_/_/   Swiss Federal Institute of Technology Zurich
  _/       _/   _/  _/   Ecole polytechnique federale de Zurich
 _/_/_/   _/   _/  _/   Politecnico federale de Zurigo

             Make it as simple as possible, but distrust it!
________________________________________________________________________


    

--
________________________________________________________________________
Dr. Andreas Fischlin, Ph.D., Group Director

Terrestrial Systems Ecology
Institute of Integrative Biology: Ecology, Evolution, Infectious Disease
Department of Environmental Sciences, ETH Zurich

Address:
ETH Zurich, CHN E21.1
8092 Zurich, Switzerland

Phone: +41 44 633-6090 / Fax: +41 44 633-1136
http://www.sysecol.ethz.ch/Staff/af/
http://www.sysecol.ethz.ch/

     _/_/_/ _/_/_/ _/  _/
    _/       _/   _/  _/   Eidgenoessische Technische Hochschule Zuerich
   _/_/_/   _/   _/_/_/   Swiss Federal Institute of Technology Zurich
  _/       _/   _/  _/   Ecole polytechnique federale de Zurich
 _/_/_/   _/   _/  _/   Politecnico federale de Zurigo

             Make it as simple as possible, but distrust it!
________________________________________________________________________
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]