Oberon-2
Oberon からの拡張 > 実行時型チェック

Oberon-2 はオブジェクトの型について、動的なチェックを行う機構がいくつか用意されている。例えば、Bird オブジェクトのインスタンスとして Duck や Cuckoo があったとき、Oberon-2 では実行時にオブジェクトの実際の型に応じた処理が可能である。
従来的な方法としては、「型束縛システム」を使った方法がある。第二の方法として、WITH 文を使った方法がある。これは、変数の動的な派生型を直接チェックするものである。どちらの場合も、派生型を特定したら、プログラマはその派生型に適切な型束縛プロシージャや型束縛変数を使うことができる。以下に具体例を示す。
なお、Oberon-2 の WITH 文と Pascal や Modula-2 の WITH 文は無関係である。以下のメソッドではレコードのフィールドへのアクセスを略記しているが、Oberon や Oberon-2 では実際にはこのような記法は使わない。
型束縛
MODULE Birds;

    TYPE Bird* = RECORD
                     sound* : ARRAY 10 OF CHAR;
                 END;
END Birds.
(*-------------------------------------*)
MODULE Ducks;
    IMPORT Birds;
    
    TYPE Duck* = RECORD(Birds.Bird) END;
            
    PROCEDURE makeSound*( VAR bird: Duck );
    BEGIN COPY("Quack!", bird.sound); END makeSound;

END Ducks.
(*-------------------------------------*)
MODULE Cuckoos;
    IMPORT Birds;

    TYPE Cuckoo* = RECORD(Birds.Bird) END;
            
    PROCEDURE makeSound*( VAR bird: Cuckoo );
    BEGIN COPY("Cuckoo!", bird.sound); END makeSound;

END Cuckoos.
WITH 文
MODULE Test;
  IMPORT Out, Birds, Cuckooo, Ducks;

    TYPE SomeBird* = RECORD ( Birds.Bird ) END;

    VAR sb : SomeBird;
    VAR c  : Cuckoos.Cuckoo;
    VAR d  : Ducks.Duck;
    
    PROCEDURE setSound*( VAR bird : Birds.Bird );
    BEGIN
        WITH bird : Cuckoos.Cuckoo DO
                    bird.sound := "Cuckoo!";
           | bird : Ducks.Duck DO
                    bird.sound := "Quack!";
        ELSE
                    bird.sound := "Tweet!";
        END;
    END setSound;

    PROCEDURE MakeSound* ( VAR b : Birds.Bird );
    BEGIN
    Out.Ln;
    Out.String( b.sound );
    Out.Ln;
    END MakeSound;

BEGIN

    setSound(c);
    setSound(d);
    setSound(sb);
    
    MakeSound(c);
    MakeSound(d);
    MakeSound(sb);

END Test.
POINTER
MODULE PointerBirds;
   IMPORT Out;

   TYPE BirdRec*   = RECORD sound* : ARRAY 10 OF CHAR; END;
        DuckRec*   = RECORD(BirdRec) END;
        CuckooRec* = RECORD(BirdRec) END;

   TYPE Bird   = POINTER TO BirdRec;
        Cuckoo = POINTER TO CuckooRec;
        Duck   = POINTER TO DuckRec;

    VAR pb : Bird;
        pc : Cuckoo;
        pd : Duck;

    PROCEDURE makeDuckSound*( bird : Duck );
    BEGIN COPY("Quack!", bird.sound) END makeDuckSound;
    
    PROCEDURE makeCuckooSound*( bird : Cuckoo );
    BEGIN COPY("Cuckoo!", bird.sound) END makeCuckooSound;

    PROCEDURE makeSound*( bird : Bird );
    BEGIN
        WITH bird : Cuckoo DO makeCuckooSound(bird);
           | bird : Duck   DO makeDuckSound(bird)
          ELSE
            COPY("Tweet!", bird.sound);
        END;
    END makeSound;

BEGIN
   NEW(pc);
   NEW(pd);
   
   makeCuckooSound( pc );
   makeDuckSound( pd );
   
   Out.Ln;Out.String( pc^.sound );Out.Ln;
   Out.Ln;Out.String( pd^.sound );Out.Ln;

   makeSound( pc );
   makeSound( pd );

   Out.Ln;Out.String( pc^.sound );Out.Ln;
   Out.Ln;Out.String( pd^.sound );Out.Ln;
(* -------------------------------------- *)
(* Pass dynamic type to procedure         *)

   pb := pd;

   makeDuckSound( pb(Duck) );
   Out.Ln;Out.String( pb^.sound );Out.Ln;

   pb := pc;

   makeCuckooSound( pb(Cuckoo) );
   Out.Ln;Out.String( pb^.sound );Out.Ln;
(* -------------------------------------- *)

   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;

   pb := pd;
   
   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;
(* -------------------------------------- *)
   NEW(pb);
   
   makeSound(pb);
   Out.Ln;Out.String( pb^.sound );Out.Ln;
   
END PointerBirds.
第三の方法として、IS 演算子を使った方法もある。これは、等号（=）や不等号（>）などと同じ優先順位の関係演算子であるが、動的な型の検査を行う。しかし、上述の2つの方法とは異なり、検出した派生型によって処理を振り分けることはできない。