Falcon

歷史

Haste於2002年編寫一個小型項目，用以實現一小型虛擬機，該項目很快的發展成Falcon語言。2008年，此語言以開源項目的方式成為Ubuntu的附加軟體，並且被包含在Kross。

核心

不同於關注於一個編程風格或範式（paradigm），Falcon在一個簡單的框架（framework）里融合了幾種不同的風格。在實現級別上，Falcon是「服務概念」驅動，當不作為一個單一的工具被使用時腳本引擎被看做一個服務腳本，模塊和內嵌的應用。

Hello Falcon

儘管有各種形式的基本I/O，一個"hello world"（全世界朋友你好!）例子使用fast print(快速列印):
> "Hello World!"
Unicode支持，下面是一個國際化例子的介紹：
// International class; name and street
class 国際(なまえ, Straße)
   // set class name and street address
   नाम = なまえ
   شَارِع = Straße
   // Say who am I!
   function 言え!()
     >@"I am $(self.नाम) from ",self.شَارِع
   end
end
// all the people of the world!
民族 = [国際("高田 Friederich", "台湾"),
   国際("Smith Σωκράτης", "Cantù"),
   国際("Stanisław Lec", "południow")]
for garçon in 民族：garçon.言え!()

過程式

過程式編程通過典型的函數聲明和調用被支持。每一個函數支持隱式變量參數調用和占位參數（Positional Parameters）命名參數（Named Parameters）。提供了一套過程式風格的語句（如for, while, if, switch語句）。
下面，一個完整的過程式程序，突出一部分在Falcon里用來減少一些編程任務中固有的pre-body-post（前置-本體-後置）處理的困擾的設計理念
function sayList( saying )
   for elem in saying
       >> elem
       formiddle: >> " "
       forlast: > "!"
   end
end
sayList( List("Have", "a", "nice", "day") )

函數式

Falcon有個稱為Sigma-reductor的求值引擎，它允許程序人員編寫純函數式程序，看起來和用Lisp沒什麼不同。混合式編程風格允許在函數式語句序列使用不同的範式（例如OOP或者過程化），或者在不同的過程化方式期間中使用函數式求值。
函數式語句序列被描述為標準語言數組；交叉不同的求值和在Sigma-reduction求值方式期間這都意味著語句序列能被程序本身創建，審查和被動態修改。下面的例子在列表循環調用late binding修改一個指定變量的引用。
 pnext = [ printl, '"', &value, '"' ]
 dolist( function(p); seq.value = p; eval(seq); end,
         ["Have", "a", "nice", "day"] )
如果他們第一個成員變量是一個自身可調用元素，標準數組作為函數被調用，如下面的例子。
 [printl "Prompt> "]( "Real data to print" )
同一個級別函數式語句序列（如在上面例子）能被作為存儲的調用來按照定義處理，並且一次性分配給一個變量，它們在語意上等同於一個函數符號。
函數式範式包含一個out of band元素標記。元素能接收一個通過語言操作符和函數被測試的oob特徵標記，並且當在函數式語句序列中移動時指明一個特殊含義的值。例如，很多函數式循環，如floop和times，能重新開始執行循環，或者被從包含的函數返回的無論1或0的out of band中斷。map函數通過一個映射函數轉換一個數組中的所有值，如果它是一個nilout of band將忽略返回值（丟棄它）；通過這個方法可以在某處執行映射和過濾。

物件導向

通過類，一個繼承模型，靜態類成員，屬性初始化和實例構造器，Falcon程式語言提供一個OOP範式。在至多一個潛在的父類是被反射成原生數據的條件下支持多繼承。訪問基類成員被支持。
實例的結構是固定和不變的，但是由於Falcon函數式特質，函數看上去就是一種特定種類的數據，它能動態設置實例成員為無格式數據或者函數（變成他們的方法）。
Falcon支持單一對象，可能是classless或者父類派生，在虛擬機執行主腳本之前實例化和被準備。在可能涉及程序模塊中一個在其他的對象時，實例消除順序由Falcon連結器追蹤以確保單一對象的適當的初始化。
通過函數式語句序列類實例能被創建，如實例化的一個類在語意上等於調用它的符號，因此，對一個第一個元素是一個類的函數式語句序列求值，它有創建一個實例的效果。
Falcon的OOP模型完整支持操作符重載，它允許創建一個針對數學和邏輯的擁有指定的行為操作符的類。

面向原型對象

原型OOP比OOP更簡單，但它去掉類的概念。實例全是classless，他們的結構能被動態改變。Falcon語言字典（排列好的鍵/值集合）能包含函數，那時字典能被祝福，通知語言他們作為classless實例被處理，並且使用點訪問符使他們的值作為屬性或方法被處理。在下面的例子，一個字典變成一個對象：
dict = bless([ 'state' => 0, 'incme' = > function(); self.state++; end ])
dict.incme()
> dict.state  // will print '1'
簡單地運行綁定的數組。
array = [1,2,3]
array.showMe = function()
   for item in self
       > item
   end
end
array.showMe()

面向消息

當一個消息被廣播時面向消息編程允許間接調用一個或者更多註冊的監聽器。消息的內容是任意的並且能包含任何語言元素，包括但不限於哪個創建創建實例的類，函數序列或者表。監聽器不是完整接受消息和執行他們，就是通過有次序的步驟分享在構建中的一個消息的通用應答。消息能被廣播和包含一個實時的應答或者能被保存在環境用來接收和處理更多的後來者（在Falcon里被稱作斷言）。
面向消息編程擁有一個在虛擬機里的直接接口，關於擴展原生模塊和嵌入應用能相互作用。例如，一個多執行緒應用可能拋給虛擬機來自不同的執行緒消息，為了在腳本級別上序列化處理和稍後廣播直接來自腳本的處理解決方案。

表格化

表格式編程能看做是一種OOP編程的特殊擴展，一個類通過一個表格被描述，他們的列是屬性，每一行是一個實例。不同於一起保持全部實例，允許每個實例影響父表周圍的行，關於表的修改被動態反射到每個實例。
表格提供一個方法來在有限選擇的集合之間選擇行為，或者混合行為併合並它們，提供模糊邏輯引擎。如每一行，實質上的一個Falcon數組，能包含表中數據和邏輯或者私有邏輯（通過數組綁定），在表格里一個通過全局選擇邏輯選擇的實體能提供專門的處理能力。

特性

隨著多範式編程，Falcon為編程人員呈現多種多樣的特色。

模板文件

通過預處理符號<? .. ?>或者<?fal .. ?>，Falcon允許腳本成為文本文檔的一部分，、。保存為".ftd"的腳本被作為一個文本文件來處理並且在遇到其中一個預處理符號之前簡單輸出。下面的.ftd例子裡包含其中的腳本被執行：
  You called this script with <? print( args.len() ) ?> parameters.
FTD文件能通過標準Falcon腳本被整合到各式應用，在動態模板（FTD文件）中的是表現邏輯，應用邏輯被儲存在Falcon模塊。
FTD文件能被用來驅動動態網站，一些流行的網頁伺服器（當前的Apache 2），擁有直接分析和執行".fal"和".ftd"腳本的模塊，提供整合到網頁伺服器引擎的一個API。用CGI腳本也能使用動態FTD頁面。

異常

Falcon由raise, try和catch語句支持錯誤處理。raise語句能拋出任何Falcon元素，包括Nil，numbers, strings, objects等等。庫函數和擴展模塊將通常引發錯誤類的實例，或者派生自他的實例。
catch語句能捕獲任何類型的元素，一個某種類型（如string（字串）或interger（整數）），或者某種類的實例。捕獲的類被按層次組織，所以它能像下面的例子一樣支持更多一般性錯誤處理（TypeError是一個派生自Error類庫）:
try
   ... code that can raise ...
catch TypeError in error
   ... if we mixed up types ...
catch Error in error
   ... another generic error ...
catch StringType in error
   ... an explicit raise "something" was issued ...
catch in error
   ... no idea of what has been raised.
end
catch語句中的in子句是可選的（這意味著錯誤可以忽略自身）。
catch語句模仿select語句，能被用一個給出的類型或者類轉向。

可嵌入運行時

使用可連結運行時庫libfalcon，Falcon被設計成可嵌入和可擴展其他系統的。

文檔生成器

Falcon裝載著一個整合的文檔系統，叫做faldoc，是特別設計來提供可維護的文檔的Falcon基礎庫（是原生C++代碼或者用Falcon編寫的模塊）。

虛擬文件系統

所有發生在引擎或者虛擬機（腳本執行器）等級的I/O操作被委派給一個中央虛擬文件系統組件（centralized Virtual Filesystem Provider），外部模塊或者可嵌入的應用設備被允許動態註冊。訂閱的虛擬文件系統抽象I/O操作如目錄讀取，創建文件和打開流，通過URI能在腳本內部尋址。這使得他能從任何VFS（如網絡資源或者壓縮加密的文件）讀取模塊或者打開資源，通過第三方模塊且或通過嵌入引擎的應用程式可以包含特殊的虛擬位置的支持。

並發支持

在更新到0.8.x版本，Threading模塊提供腳本完整多執行緒。執行緒模型是面向代理（agent oriented），跨執行緒數據必須通過幾種可行共享機制明確地共享。每一個執行緒運行一個不同的虛擬機，分離的運行發生在其內部任何操作（如垃圾回收）。這允許有效的並行處理和在腳本開發者控制之外的0競爭。

協同處理

Falcon支持准並發協同處理。協同處理是指通過虛擬機在同一時間片或者在空閒時間裡執行代碼。它們支持一個接近於完整執行緒模塊的更輕量級的並發處理，通過不同的協同處理允許程序的全局數據完全可見。除了每個協同處理的合作，（如在調度讀取之前每個協同處理必須檢查數據可用性）。

元編譯器

'Falcon編譯器有一個支持宏展開的元編譯器，在一個標準編譯器中元編譯器由Falcon虛擬機驅動；自元編譯器生成的輸出被發送到語言的語法分析器就像他是原始代碼的一部分。使用\[ ...\]退出序列，通過列印他能動態記錄被編譯的程序內容。
 \[ printl( "printl( 'Hello world' )" ) \]
macro關鍵字提供一個簡單的轉到編譯時元編程的語法糖果（candy-grammar）接口。

原生國際化

用一個前綴'i'的字符串被認為是一個輸出（國際化）字符串。在一個模塊中通過使用directive語句聲明使用的語言，它能指示哪個字符串用什麼自然語言編寫，如下面的例子：
 directive lang=fr_FR           // uses 5 characters ISO language code
 > i"Bonjour à tout le monde!"
一個命令行工具fallc被用來輸出'i'字符串到XML定義文件，能被作為模板來支持翻譯到不同的語言。
在讀取模塊的時候一個已翻譯的字符表被應用到模塊。

實現

核心VM和官方模塊，（包括特色模塊和社區提供支持的模塊）都是用C++編寫.一些非常底層的模塊和引擎元素是用C和彙編編寫。