複製鏈接
請複製以下鏈接發送給好友

Modula-3

鎖定
Modula-3是一種編程語言,被視為Modula-2升級版(稱為Modula-2 +)的後續版本。雖然它在研究領域具有影響力(影響Java,C#和Python等語言的設計),但它在工業領域還沒有被廣泛採用。它由Luca Cardelli,James Donahue,Lucille Glassman,Mick Jordan(之前在Olivetti軟件技術實驗室),數字設備公司(DEC)系統研究中心(SRC)的Bill Kalsow和Greg Nelson以及Olivetti研究中心ORC)在20世紀80年代後期。
Modula-3的主要特點是簡單和安全,同時保留了系統編程語言的強大功能。 Modula-3旨在繼續Pascal類型安全的傳統,同時為實際的實際編程引入新的構造。特別是Modula-3增加了對泛型編程(類似於模板), 多線程,異常處理,垃圾收集,面向對象編程,部分啓示和不安全代碼的明確標記的支持。 Modula-3的設計目標是以相當基本的形式實現現代命令式語言的最重要特徵的語言。因此,所謂的危險和複雜的特徵,如多重繼承和操作符重載被省略。
外文名
Modula-3
特    點
簡單和安全

Modula-3歷史發展

Modula-3項目始於1986年11月,當時莫里斯威爾克斯給Niklaus Wirth寫了一些關於Modula新版本的想法。 Wilkes在此之前一直在DEC工作,並已回到英國並加入Olivetti的研究戰略委員會。 Wirth已經轉到Oberon,但是在Modula的名字下威爾克斯的團隊繼續發展並沒有問題。語言定義於1988年8月完成,並於1989年1月更新。DEC和Olivetti的編譯器很快就完成了,隨後的第三方實現。
它的設計深受當時SRC和Acorn計算機研究中心(ARC,後來ORC當Olivetti收購Acorn時)使用的Modula-2 +語言的影響,這是用於操作系統的語言編寫了DEC Firefly多處理器VAX工作站,其中編寫了用於Acorn C的Acorn編譯器和ARC的ARM模塊執行庫(CAMEL),用於基於ARM的Acorn Archimedes系列ARM計算機的ARX操作系統項目。正如修訂後的Modula-3報告所述,該語言受到Mesa,Cedar,Object Pascal,Oberon和Euclid等其他語言的影響。
在20世紀90年代,Modula-3作為教學語言獲得了相當可觀的貨幣,但它從未廣泛用於工業用途。對此有所貢獻的可能是DEC,一個關鍵的Modula-3支持者(特別是在1998年DEC出售給康柏之前不再有效地維持它)的消亡。無論如何,儘管Modula-3的簡單性和強大功能,似乎很少需要使用面向對象編程的程序化編譯語言。一段時間以來,一個名為CM3的商業編譯器由DEC SRC之前的主要實現者之一維護,他在DEC被出售給Compaq之前被聘用,一個名為Reactor的集成開發環境和一個可擴展的Java虛擬機(以二進制和源格式授權以及由Critical Mass,Inc.提供,但該公司在2000年停止了活動,並將其產品的一些來源提供給elego Software Solutions GmbH。 Modula-3在大學裏教授,主要是比較編程語言課程,其教科書已絕版。從本質上來説,Modula-3的公司支持者是elego Software Solutions GmbH,該公司繼承了來自Critical Mass的資源,並且此後以源代碼和二進制形式發佈了CM3系統的多個版本。 Reactor IDE在幾年之後就已經開放源代碼,並且新的名稱為CM3-IDE。 2002年3月,elego還接管了另一個主動Modula-3發行版PM3的存儲庫,直到當時保留在蒙特利爾高等理工學院,但後來由於HM3的工作而繼續改進,直到它被廢棄為止 [1] 

Modula-3語法

語言的語法一個常見例子是Hello world程序。
MODULE Main;  
IMPORT IO;
 BEGIN
   IO.Put("Hello World\n")
  END Main.
Modula-3中的所有程序都至少有一個模塊文件,而大多數程序還包含一個客户端用來訪問模塊數據的接口文件。 像其他語言一樣,Modula-3程序必須導出一個主模塊,它可以是一個名為Main.m3的文件,也可以是一個文件可以調用EXPORT來導出主模塊。
MODULE Foo EXPORTS Main
建議模塊文件名稱與實際模塊名稱相同,但編譯器只會在不同的情況下提醒您。
語法中的其他約定包括命名接口T的導出類型,因為類型通常由它們的全名來限定,所以在名為Foo的模塊內的類型T將被命名為Foo.T. 這有助於可讀性。 另一個類似的約定是在上面的OOP示例中命名公共對象Public。

Modula-3語言功能

Modula-3模塊化

首先,所有編譯單元都是INTERFACE或實現MODULE,具有一種或另一種風格。一個接口編譯單元,從關鍵字INTERFACE開始,定義常量,類型,變量,例外和過程。實現模塊以關鍵字MODULE開頭,提供實際代碼以及實現接口所需的任何其他常量,類型或變量。默認情況下,實現模塊將實現相同名稱的接口,但是模塊可以明確地將EXPORT輸出到不具有相同名稱的模塊。例如,主程序為Main接口導出一個實現模塊。
 MODULE HelloWorld EXPORTS Main;
  IMPORT IO;
 BEGIN   IO.Put("Hello World\n")
 END HelloWorld.
任何編譯單元都可以導入其他接口,但禁止循環導入。 這可以通過從執行MODULE執行導入來解決。 使用FROM模塊IMPORT Item [,Item] *語法可以導入導入模塊中的實體,而不僅僅是模塊名稱:
 MODULE HelloWorld EXPORTS Main;

  FROM IO IMPORT Put;

 BEGIN
   Put("Hello World\n")

 END HelloWorld.
通常,只導入接口,並使用'點'符號訪問接口內的項目(類似於訪問記錄中的字段)。一個典型的用法是為每個接口定義一個數據結構(記錄或對象)以及任何支持過程。在這裏主類型將得到名稱'T',並且使用MyModule.T 中的一個。
如果導入的模塊與模塊內的其他實體之間發生名稱衝突,則保留字AS可用於IMPORT CollidingModule AS X;

Modula-3安全與不安全

某些功能被認為是不安全的,編譯器不能再保證結果是一致的(例如,與C編程語言接口時)。前綴INTERFACE或MODULE前面的關鍵字UNSAFE可用於告訴編譯器啓用該語言的某些低級功能。例如,一個不安全的操作是繞過使用LOOPHOLE的類型系統將一個整數的位複製到一個浮點實數。
導入不安全模塊的接口本身不安全。 安全接口可能由不安全的實現模塊導出。這是連接到外部庫時的典型用法,其中構建了兩個接口(一個不安全,另一個安全)。

Modula-3泛型

通用接口及其相應的通用模塊,在INTERFACE或MODULE關鍵字前加上GENERIC,並將其他接口作為形式參數。 因此(像C ++模板一樣)可以很容易地定義和使用抽象數據類型,但與C ++不同的是,粒度在模塊級別。 接口作為實際參數傳遞給通用接口和實現模塊,編譯器將生成具體模塊。
例如,可以定義GenericStack,然後使用IntegerElem或RealElem等接口或甚至與對象的接口對其進行實例化,只要這些接口中的每一個都定義了通用模塊所需的屬性即可。
注意:裸類型INTEGER或REAL不能使用,因為它們不是模塊,泛型系統基於使用模塊作為參數。相比之下,在C ++模板中,將使用裸類型。
文件: IntegerElem.i3
INTERFACE IntegerElem;
 CONST Name = "Integer";

 TYPE T = INTEGER; PROCEDURE Format(x: T):
 TEXT;

  PROCEDURE Scan(txt: TEXT; VAR x: T):
  BOOLEAN;

  END IntegerElem.
文件:GenericStack.ig
GENERIC INTERFACE GenericStack(Element);

 (* Here Element.T is the type to be stored in the generic stack. *)
 TYPE
    T = Public OBJECT;

    Public = OBJECT
    
METHODS

    init(): TStack;

    format(): TEXT;

     isEmpty(): BOOLEAN;
    
     count(): INTEGER;
     
      push(elm: Element.T);
       
      pop(VAR elem: Element.T): BOOLEAN;

END;
END GenericStack.
文件:GenericStack.mg
GENERIC MODULE GenericStack(Element);

 < ... generic implementation details... >
 PROCEDURE Format(self: T):
 TEXT = VAR
    str: TEXT;
 BEGIN
    str := Element.Name & "Stack{";

    FOR k := 0 TO self.n -1
DO
        
  IF k > 0 THEN str := str & ", ";
  
END;

str := str & Element.Format(self.arr[k]);

    END;
    str := str & "};";

    RETURN str;
 END Format;

 < ... more generic implementation details... >

 END GenericStack.
文件:IntegerStack.i3
INTERFACE IntegerStack = GenericStack(IntegerElem)
END IntegerStack.
文件:IntegerStack.m3
MODULE IntegerStack = GenericStack(IntegerElem) 
END IntegerStack.

Modula-3可追溯性

任何標識符都可以追溯到它的起源地點,而不像其他語言的“包含”特徵。 編譯單元必須使用IMPORT語句從其他編譯單元導入標識符。 即使枚舉也使用與訪問記錄字段時使用的'點'符號相同的符號。
INTERFACE A;

TYPE Color = {
Black, Brown, Red, Orange, Yellow, Green, Blue, Violet, Gray, White};

END A;
MODULE B;
IMPORT A;
FROM A IMPORT Color;VAR  aColor: A.Color;
  (* Uses the module name as a prefix *)  theColor: Color;
  (* Does not have the module name as a prefix *)
  anotherColor: A.Color;BEGIN  aColor := A.Color.Brown;
  theColor := Color.Red;
  anotherColor := Color.Orange;
  (* Can't simply use Orange *)
END B.

Modula-3動態編程

Modula-3支持在運行時分配數據。有兩種內存可以分配TRACED和UNTRACED,不同之處在於垃圾收集器是否可以看到它。NEW()用於分配這兩類內存中的任何一個的數據。在UNSAFE模塊中,DISPOSE可用於釋放未交叉的內存。

Modula-3面向對象

面向對象編程技術可用於Modula-3,但不需要使用它們。Modula-3(模塊,泛型)中提供的許多其他功能通常可代替面向對象。
對象支持有意保留其最簡單的條款。OBJECT聲明引入了一個對象類型(在其他面向對象的語言中稱“類”),儘管對象類型是引用類型,但與Modula-3中的RECORD不同 (類似於C中的結構)。按照慣例,導出的類型通常被命名為T,並創建一個單獨的“公共”類型來公開方法和數據。 例如:
INTERFACE Person;
TYPE T <: Public;
  Public = OBJECT  METHODS    getAge(): INTEGER;
    init(name: TEXT;
   age: INTEGER): T;
  END;
END Person.

Modula-3異常

異常處理基於TRY ... EXCEPT塊系統,它變得很常見。除了Delphi,Python ,Scala和Visual Basic.NET之外,其他語言中尚未採用的一個特性是[EXCEL]構造定義了一種switch語句形式,每種語言都有 作為它自己的EXCEPT子句中的一個例子可能的例外。Modula-3還支持LOOP ... EXIT ... END結構,該結構循環直到出現EXIT,這個結構等同於TRY ... EXCEPT子句中的簡單循環。

Modula-3多線程

該語言支持使用多線程,以及線程之間的同步。運行時庫(m3core)中有一個名為Thread的標準模塊,它支持使用多線程應用程序。實際上,Modula-3運行時可能會使用單獨的線程來執行垃圾收集等內部任務。
內置數據結構MUTEX用於同步多個線程,並保護數據結構免受可能的損壞或競爭條件的同時訪問。LOCK和相應的UNLOCK語句鎖定和解鎖MUTEX。MUTEX是一個對象,因此可以從中派生出其他對象。
例如,在libm3庫的I / O部分,讀寫器(Rd.T和Wr.T)從MUTEX派生,並且在訪問或修改任何內部數據(如緩衝區)之前鎖定自己。
參考資料