Box Generator / Sprache Modula
 
StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern

Die Sprache Modula-2 ist bekannt für die gute Möglichkeit zur Kapselung von abstrakten Datentypen. Auch in Modula-2 wird die Schnittstelle in einer eigenen Datei definiert.

DEFINITION MODULE RndBox;

TYPE RndBox;

PROCEDURE NewRndBox() : RndBox;
PROCEDURE DisposeRndBox(self: RndBox);
PROCEDURE RndBoxNext(self: RndBox);
PROCEDURE LastGaussian(self: RndBox) : REAL;

END RndBox.

Der Typ, hinter dem der Generator steckt, bleibt dabei (wie in BoxGenerator/SpracheCee) verdeckt und wird erst in einer eigenen Implementationsdatei spezifiziert.

IMPLEMENTATION MODULE RndBox;

FROM SYSTEM IMPORT TSIZE;
FROM Storage IMPORT ALLOCATE, DEALLOCATE;
FROM RndUniform IMPORT RndUniform,
                       NewRndUniform, DisposeRndUniform,
                       RndUniformNext, LastUniform;
FROM MathLib IMPORT sqrt, ln;

TYPE
  RndBox = POINTER TO RndBoxRecord;
  RndBoxRecord = RECORD
    random : RndUniform;
    x, y, product, first, second : REAL;
    available : BOOLEAN;
  END;

PROCEDURE NewRndBox() : RndBox;
VAR Result : RndBox;
BEGIN
  ALLOCATE(Result, TSIZE(RndBoxRecord));
  Result^.random := NewRndUniform();
  Result^.available := FALSE;
  RETURN(Result);
END NewRndBox;

PROCEDURE DisposeRndBox(self: RndBox);
BEGIN
  DisposeRndUniform(self^.random);
  DISPOSE(self);
END DisposeRndBox;


PROCEDURE RandUniv(self: RndBox) : REAL;
VAR
  Result : REAL;
BEGIN
  RndUniformNext(self^.random);
  Result := LastUniform(self^.random);
  RETURN(Result);
END RandUniv;


PROCEDURE RandPoint(self: RndBox);
VAR
  x, y : REAL;
BEGIN
  REPEAT
    x := RandUniv(self) * 2.0 - 1.0;
    y := RandUniv(self) * 2.0 - 1.0 ;
    self^.product := x * x + y * y;
  UNTIL self^.product <= 1.0;
  self^.x := x;
  self^.y := y;
END RandPoint;

PROCEDURE Generate(self: RndBox);
VAR
  p : REAL;
BEGIN
  RandPoint(self);
  p := sqrt((-2.0 * ln(self^.product))/
            self^.product);
  self^.available := TRUE;
  self^.first := p * self^.x;
  self^.second := p * self^.y;
END Generate;

PROCEDURE RndBoxNext(self: RndBox);
BEGIN
  IF self^.available
    THEN self^.available := FALSE;
    ELSE Generate(self);
  END;
END RndBoxNext;

PROCEDURE LastGaussian(self: RndBox) : REAL;
VAR
  Result : REAL;
BEGIN
  IF self^.available
    THEN Result := self^.first;
    ELSE Result := self^.second;
  END;
  RETURN(Result);
END LastGaussian;

END RndBox.

Fragen

Sehe ich das richtig, daß man den Generator händisch mir RndBoxNext? weiterschalten muß? Ist das ein Modula Idiom oder einfach nur ein anderer Ansatz?

Das ist weder ein anderer Ansatz noch ein Modula-Idiom. Es ist lediglich die Umsetzung des Entwurfs in Pseudocode.

Warum es nicht unbedingt die beste Lösung ist, den Zugriff auf die letzte erzeuget Pseudozufallszahl und das Weiterschalten in der Pseodozufallszahlenfolge als eine Operation zu betrachten versuchte ich bereits anzudeuten. Hier noch einmal die Begründung dafür: Ein Pseudozufallszahlengenerator iteriert über eine Folge. Die natürlichen Operationen sind daher der 'Zugriff' an der aktuellen Position und der 'Schritt' zum nächsten Element der Folge.

Dass der Zugriff auf das aktuelle Element der Folge einen Schritt zum nächsten Element als Seiteneffekt hat, mag für Java-Kundige ein vertrautes Verhalten eines Iterators sein. Das Entwurfsmuster 'Iterator' versteht die natürlichen Nachrichten first, next, isDone und currentItem, und currentItem hat keine Seiteneffekte (Gamma et. al. 1994). Auch BertrandMeyer (1997) sieht das nicht anders.

Also: welchen Grund ausser der Definition von java.util.Iterator gibt es, das Weiterschalten und den Zugriff auf das letzte Element als einen Abfrage mit Seiteneffekt oder als eine Anweisung mit Rückgabewert zu sehen. Zumindest Meyers 'Command-Query Separation principle' wird durch die Funktionsweise von next() in java.util.Iterator verletzt. Das sich rand() aus der C-Standardbibliothek so verhält ist bei den Abstraktionsmöglichkeiten von C, wie sie im Jahr 1972 gesehen wurden, kaum zu vermeiden.

Ausser Java fällt mir keine aktuelle Programmiersprache ein, in der der Zugriff auf das aktuelle Element über einen Iterator den Seiteneffekt 'Weiterschalten' hat. -- KurtWatzka

StartSeite | BoxGenerator/ | Neues | TestSeite | ForumSeite | Teilnehmer | Kategorien | Index | Hilfe | Einstellungen | Ändern
Text dieser Seite ändern (zuletzt geändert: 14. Juli 2002 20:04 (diff))
Suchbegriff: gesucht wird
im Titel
im Text