[Oberon] Multiple RETURN in a procedure

thutt at harp-project.com thutt at harp-project.com
Sun Oct 23 17:33:07 CEST 2022


Joerg writes:
 > Wojtek
 >
 > Conceptionally, a procedure and a function are two different
 > things. A procedure is a task doing something (steering a motor or
 > drawing a circle), a function calculates a value.  In previous
 > Oberons a function was just a procedure with some RETURN
 > statements. There was no syntactic enforcement of having one RETURN
 > at all. The compiler had to count whether you included at least one
 > RETURN statement.

The original ETHZ compiler didn't check if you included a return
statement.  It actually did something that I find to be really nice --
something that would be handy for others to adopt:

   If you did not have a return statement that was executed in a
   procedure returning a value, a trap was raised.

   In System.Mod of Oberon V2:

     | 17: Texts.WriteString(W, "function without return");

   For every procedure that returned a value, the compiler would emit
   a software trap on the path to the procedure epilog.


 > If you wanted to spot what the function returns,
 > you had to find all RETURNs and hopefully you didn’t overread one..
 > In Oberon-07 the different concepts of procedures and function
 > differ also in syntax, the RETURN is not a statement anymore it is
 > the last reserved word before the end of the function.  This way it
 > is educationally easier to bring across the different concepts,
 > your code is no „spaghetti code“ anymore (RETURN statements were
 > hidden GOTOs, even from within nested loops)
 >
 > Personally, I find this a little less cluttered
 > PROCEDURE min(min,x: INTEGER): INTEGER;
 > BEGIN IF x < min THEN min := x END
 > RETURN min END min;

Very Pascal-like, and probably better for a GSA implementation.

 >
 > br
 > Jörg
 >
 > > Am 23.10.2022 um 06:05 schrieb Skulski, Wojciech <skulski at pas.rochester.edu>:
 > >
 > > I know this is a recurring topic, but still... what is so
 > > sinister about multiple RETURN statements? The following Oberon
 > > procedure was elegantly coded with two RETURNs. Could you please
 > > remind me why multiple RETURNs were so wrong that they are now
 > > forbidden? What is the overwhelming benefit of disallowing
 > > multiple RETURNs, that is justifying breaking perfectly valid
 > > code?
 > >
 > > Please do not try to convince me that rewriting is easy. Yes, it
 > > is easy to rewrite this little piece. But I am now facing three
 > > thousand lines of my Oberon-2 library. It would be so nice if
 > > stylistic improvements were not introduced to the language,
 > > unless truly necessary. Is this one truly necessary, and why?
 > >
 > > PROCEDURE min (x,y: INTEGER) : INTEGER;
 > > BEGIN IF x < y THEN RETURN (x) ELSE RETURN (y) END END min;
 > >
 > > Thanks,
 > > Wojtek

 I am not a fan of the single return, though it would probably be
 beneficial for the GSA IR and code generation.   The return causes an
 immediate return from the function, but the assignment to the
 procedure name means that the control flow will continue through the
 function.  For many non-trivial functions, with a naive compiler,
 this will lead to unnecessary code being executed, and perhaps faults
 being raised.

 Consider:

  PROCEDURE ListLength(ptr : List) : INTEGER
  VAR r : INTEGER;
  BEGIN
    IF ptr = NIL THEN
       RETURN 0;
    END;
    r := 0
    WHILE ptr # NIL DO
       INC(r);
       ptr := ptr.next;
    END
    ListLength := r;
    RETURN ListLength;
  END ListLength;

I'm not that familiar with Oberon-07, so maybe there's some nuance I'm missing?

--
Never tease a weasel, it's not nice.


More information about the Oberon mailing list