Oberon

Oberon是一種通用程式語言，最初由尼克勞斯·維爾特在1987年推出，是維爾特風格的類ALGOL語言中的最後一員（繼Euler、ALGOL W、Pascal、Modula和Modula-2之後）。Oberon是增進Pascal的直接後繼者Modula-2的能力，並減少其複雜度的集中努力的結果。它的原理性新特徵是記錄類型的數據類型擴展的概念。它允許新數據類型構造在現存數據類型之上並將它們關聯起來，脫離了嚴格的靜態類型數據的教條。Oberon是在瑞士的蘇黎世聯邦理工學院作為Oberon (作業系統)實現的一部份而開發的。這個名字來自天王星的衛星奧伯隆。

Oberon的當前版本是2007年修訂的Oberon-07，它由維爾特來維護而Oberon計劃編譯器最近更新於2020年3月6日。

## 設計

Oberon的基本指導原則是集中於基礎和根本的特徵，並忽略短暫性的問題。另一個因素是認識到了在語言如C++和Ada中複雜度的增長。與它們相反，Oberon強調使用庫概念來擴展語言。在Modula-2中提供的枚舉和子範圍類型被省略了，並且集合類型被限制為小的整數集合。所有的導入項目都必須用它們在其中聲明的那個模塊的名字來限定。通過只允許低層設施在包含了標識符`SYSTEM`於其導入列表的模塊中使用而突顯了它們。甚至跨越模塊的非常嚴格的類型檢查、運行時間索引檢查、空指針檢查和安全的類型擴展概念，在很大程度上允許編程單獨的依仗於語言規則。

這種策略的意圖是產生易於學習、實現更簡單和高效的語言。Oberon編譯器被認為是簡明和快速的，卻提供了可比擬於商業編譯器的代碼質量。

## 特徵

<image>

刻畫Oberon語言的特徵包括：

- 具有大寫關鍵字的大小寫敏感語法。
- 具有類型測試的類型擴展。
- 模塊和分離編譯。
- 字串操作。
- 孤立不安全代碼。
- 支持系統編程。

## 面向對象示例

Oberon支持對記錄類型的擴展，用於抽象和異構結構的構造。不同於後期方言即1991年提出的Oberon-2和1998年提出的Active Oberon，最初的Oberon缺乏作為語言特徵的分派機制，而是把它作為一種編程技術或設計模式。這給出了在OOP上的巨大靈活性。在Oberon (作業系統)中，兩種技術被一起用於分派調用：方法套件和消息處理器。

### 方法套件

在這種技術中，泛化模塊定義過程變量的一個表格類型，而擴展模塊中聲明這個類型的一個共享變量，泛化模塊中的方法要訪問這個表格的對應項目，而擴展模塊將這個表格的項目指派到自己相應的過程：

```modula2
MODULE Figures; (* 抽象模块 *)

  TYPE
    Figure* = POINTER TO FigureDesc;
    Interface* = POINTER TO InterfaceDesc;
 
    InterfaceDesc* = RECORD
      draw* : PROCEDURE (f : Figure);
      clear* : PROCEDURE (f : Figure);
      mark* : PROCEDURE (f : Figure);
      move* : PROCEDURE (f : Figure; dx, dy : INTEGER);
    END;
 
    FigureDesc* = RECORD
      if : Interface;
    END;
 
  PROCEDURE Init* (f : Figure; if : Interface);
  BEGIN
    f.if := if;
  END Init;
 
  PROCEDURE Draw* (f : Figure);
  BEGIN
    f.if.draw(f);
  END Draw;
 
(* 这里是其他过程Clear、Mark和Move *)
 
END Figures.
```

擴展泛化類型`Figure`為特定形狀`Rectangles`：

```modula2
MODULE Rectangles;
 
  IMPORT Figures;
 
  TYPE
    Rectangle* = POINTER TO RectangleDesc;
 
    RectangleDesc* = RECORD
      (Figures.FigureDesc)
      x, y, w, h : INTEGER;
    END;
 
  VAR
    if : Figures.Interface;
 
  PROCEDURE New* (VAR r : Rectangle);
  BEGIN
    NEW(r);
    Figures.Init(r, if);
  END New;
 
  PROCEDURE Draw* (f : Figure);
    VAR
      r : Rectangle;
  BEGIN
    r := f(Rectangle); (* f具有Rectangle类型 *)
    (* ... *)
  END Draw;
 
(* 这里是其他过程Clear、Mark和Move *)
 
BEGIN (* 模块初始化 *)
  NEW(if);
  if.draw := Draw;
  if.clear := Clear;
  if.mark := Mark;
  if.move := Move;
END Rectangles.
```

動態分派只能通過泛化模塊的`Figures`中的方法集合完成，比如這裡的`Draw`、`Clear`、`Mark`和`Move`過程，它們通過接口表格調用了擴展模塊`Rectangles`中的同名過程。

### 消息處理器

這種技術形成於，在泛化模塊中定義一個單一的處理器過程類型，並在擴展模塊中聲明這個類型的一個過程，用它處理對應各種方法並包含了相應的實際參數的消息記錄：

```modula2
MODULE Figures; (* 抽象模块 *)
 
  TYPE
    Figure* = POINTER TO FigureDesc;
 
    Message* = RECORD END;
    DrawMsg* = RECORD (Message) END;
    ClearMsg* = RECORD (Message) END;
    MarkMsg* = RECORD (Message) END;
    MoveMsg* = RECORD (Message) dx*, dy* : INTEGER END;
 
    Handler* = PROCEDURE (f : Figure; VAR msg : Message);
 
    FigureDesc* = RECORD
      (* 抽象 *)
      handle : Handler;
    END;
 
  PROCEDURE Handle* (f : Figure; VAR msg : Message);
  BEGIN
    f.handle(f, msg);
  END Handle;
 
  PROCEDURE Init* (f : Figure; handle : Handler);
  BEGIN
    f.handle := handle;
  END Init;
 
END Figures.
```

擴展泛化類型`Figure`為特定形狀`Rectangles`：

```modula2
MODULE Rectangles;
 
  IMPORT Figures;
 
  TYPE
    Rectangle* = POINTER TO RectangleDesc;
 
    RectangleDesc* = RECORD (Figures.FigureDesc)
      x, y, w, h : INTEGER;
    END;
 
  PROCEDURE Draw* (r : Rectangle);
  BEGIN
    (* ... *)
  END Draw;
 
  (* 这里是其他过程Clear、Mark和Move *)
 
  PROCEDURE Handle* (f: Figure; VAR msg: Figures.Message);
    VAR
      r : Rectangle;
  BEGIN
    r := f(Rectangle);
    IF msg IS Figures.DrawMsg THEN Draw(r)
    ELSIF msg IS Figures.MarkMsg THEN Mark(r)
    ELSIF msg IS Figures.MoveMsg THEN 
      Move(r, msg(Figures.MoveMsg).dx, msg(Figures.MoveMsg).dy)
    ELSE (* 忽略 *)
    END
  END Handle;
 
  PROCEDURE New* (VAR r : Rectangle);
  BEGIN
    NEW(r);
    Figures.Init(r, Handle);
  END New;
 
END Rectangles.
```

在Oberon作業系統中，這兩種技術都用於動態分派。前者用於已知的方法集合；後者用於在擴展模塊中聲明的任何新方法。例如，如果擴展模塊`Rectangles`要實現一個新的`Rotate()`過程，在擴展模塊之外只能通過它的消息處理器過程來調用。

## 外部資源連結

### 一般性

- Official website (latest available copy at archive org) at ETH-Zürich
- Niklaus Wirth's Oberon Page at ETH-Zürich
- Oberon Page at SSW, Linz
- Oberon: The Programming Language at Ulm
- Project Oberon, The Design of an Operating System and a Compiler , book in PDF by Niklaus Wirth and Jürg Gutknecht, 2005 Edition
- Oberon Language Genealogy
- Astrobe ARM Oberon-07 Development System
- Oberon System V4 for HP OpenVMS Alpha with source code upward-compatible 64 bit addressing
- 64 bit Oberon-2 compiler for HP OpenVMS Alpha
- Oxford Oberon-2 Compiler and its User Manual
- Free Oberon-07 IDE Free Oberon-07 IDE for Windows, Macintosh, and Linux with syntax colouring, semantic navigation and source code debugger
- Oberon article by Joseph Templ in the January 1994 issue of Dr.Dobbs

### Oberon的演化

- Modula-2 and Oberon Wirth (2005)
- The Programming Language Oberon Wirth, (1988/90)
- The Programming Language Oberon (Oberon-7, Revised Oberon) Wirth, (2016, most current language report)
- Differences between Oberon-07 and Oberon Wirth (2011)
- The Programming Language Oberon-2 H. Mössenböck, N. Wirth, Institut für Computersysteme, ETH Zürich, January 1992
- Differences between Oberon and Oberon-2 Mössenböck and Wirth (1991)
- What's New in Component Pascal (Changes from Oberon-2 to CP), Pfister (2001)

## 基本資料

- 編程范型：指令式, 結構化, 模塊化, 面向對象
- 語言家族：Wirth Oberon
- 設計者：Niklaus Wirth
- 開發者：蘇黎世聯邦理工學院
- 發行日期：1987年
- 軟體版本週期：Oberon-07
- 軟體版本週期：2020年3月6日
- 類型系統：強類型, 混合（靜態和動態）
- 作用域：詞法
- 平台：ARM, StrongARM; IA-32, x86-64; SPARC, Ceres (工作站) (NS32000)
- 作業系統：Windows, Linux, Solaris, classic Mac OS, Atari TOS, AmigaOS
- 受影響於：Modula-2
- 施影響於：Modula-3, Oberon-2, Component Pascal, Active Oberon, Oberon-07, Nim, Go, Zonnon