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