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項目始於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的工作而繼續改進,直到它被廢棄為止。

語法

語言的語法一個常見例子是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。

語言功能

模組化

首先,所有編譯單元都是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;

安全與不安全

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

泛型

通用接口及其相應的通用模組,在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 -1DO          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.

可追溯性

任何標識符都可以追溯到它的起源地點,而不像其他語言的“包含”特徵。 編譯單元必須使用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支持在運行時分配數據。有兩種記憶體可以分配TRACED和UNTRACED,不同之處在於垃圾收集器是否可以看到它。NEW()用於分配這兩類記憶體中的任何一個的數據。在UNSAFE模組中,DISPOSE可用於釋放未交叉的記憶體。

面向對象

面向對象編程技術可用於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.

異常

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

多執行緒

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

相關詞條

熱門詞條

聯絡我們