[Oberon] Renaming imported procs (was: concrete use of open array)

Chris Burrows chris at cfbsoftware.com
Fri Jun 25 04:01:54 MEST 2010


>-----Original Message-----
>From: oberon-bounces at lists.inf.ethz.ch 
>[mailto:oberon-bounces at lists.inf.ethz.ch] On Behalf Of spir
>Sent: Friday, 25 June 2010 1:20 AM
>To: Oberon
>Subject: [Oberon] concrete use of open array
>
>off-topic:
>* is it possible to rename imported procs (eg "Write := 
>Out.String" :-)?

I agree with the spirit of Aubrey's reply. Keep in mind that programming is
a WORM (i.e. write-once, read-many) exercise. Well maybe not 'once' but
typically in these days of open source, the number of times source code is
read far outweighs the number of times it is written. Hence, if ease of
identification / location of an imported procedure (and protection against
unintentional ambiguity) takes a little extra typing effort then that is
well-justified.

Having said that, typically in Oberon programs you will find many
application-specific local 'helper' functions to handle the cases where the
same imported function is called many times. Procedure calls in Oberon are
efficient so there is no need to avoid writing small procedures (even
one-liners) if there is a good reason to do so. Typical Oberon programs have
procedures like:

PROCEDURE WrError(errorCode: INTEGER; msg: ARRAY OF CHAR);
BEGIN
  Out.String("Error: "); 
  Out.Int(errorCode, 0); 
  Out.String(": "); 
  Out.String(msg); 
  Out.Ln
END WrError;

so you can then write:

   WrError(309, "unterminated comment");
   WrError(310, "bad character");

However, if you *really* want to rename an imported function it can be done
using procedure variables with very little additional overhead. Just don't
tell anybody I encouraged you to do so!

e.g. 

VAR
  Write: PROCEDURE (s: ARRAY OF CHAR);

and then in the module initialisation code:

BEGIN
  Write := Out.String;
  ...

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

Note that the Procedure variable / Procedure type facility is primarily
intended to be used when you want to modify the functionality of the subject
procedure at runtime, or to pass a procedure as a parameter to a function to
modify the behaviour of that function. For example, a Generic Sorting module
could have the following definitions:

TYPE
  Object* = POINTER TO RECORD END;
  CompareProc* = PROCEDURE (CONST a, b: Object): INTEGER;

PROCEDURE Quick*(VAR a: ARRAY OF Object; compare: CompareProc; left, right:
INTEGER); 

-------

Then in the client module that IMPORTs you would have:

  PROCEDURE CompareReals(r1, r2: REAL): INTEGER;
  BEGIN
   (* Returns 
       r1 < r2: -1
       r1 = r2: 0
       r1 > r2: +1
   *)
  END CompareReals;

and the actual call would be:

  Sort.Quick(realData, CompareReals, 0, LEN(realData) - 1)

--
Chris Burrows
CFB Software
Astrobe: ARM Oberon-07 Development System
http://www.astrobe.com





More information about the Oberon mailing list