寫程式難,就讓我們寫指令碼吧…

作者:Larry Wall
翻譯:ㄚ琪 ,這一篇覺得真難翻,可能是對Perl 還不懂,所以請多多指教!
原文:Programming is Hard, Let’s Go Scripting…

我認為對很多人來說指令碼很像下流的東西,我無法解釋這件事,但是當我看到它的時候我就會知道,以下是一些廣為流傳的事蹟:

    簡單的語言
    "每件事都是字串"
    快速原型法
    膠水語言(Glue language)
    程序控制
    緊湊/簡潔
    更壞的-就是-更好的
    特定領域的
    "內含動力(Batteries included)"

…在這裡我沒有看到任何的中心,至少在技術條件上,如果我必須選一個比喻,那麼就像是一個簡單的交流道系統跟一個慢車道那樣,甚至有一些是可選的快車道。

簡單的交流道

但基本上指令碼不是一個技術術語,當我們稱某些東西是指令碼語言時,我們主要是在做語言跟文化的判斷,而非技術上的判斷。

我認為指令碼是人文學科的一環,這是我們語言的根本,所以談談這個根本…

過去

假如你回到愛達·勒芙蕾絲的時代並且問她指令碼跟程式的差異,她大概會認為你很好玩,然後這樣說:嗯,腳本是你給演員看的,但是節目是給觀眾看的,愛達是一個聰穎的淑女…

自從她之後,我們似乎越來越困惑關於我們所看的指令碼的意義,它甚至也困擾了我,而我應該算是一個專家了說。

所以我恐怕我所能做的就是給你我自己對過去、現在及未來的淺見,讓我警告你們在這裡我可能會一些我的偏見。

BASIC

現在我認為BASIC最初的目的被證明是一種主要的指令碼語言,特別是它的擴充版本DEC把他放在它的迷你電腦上叫做BASIC/PLUS,而且順便加了遞迴函式跟參數,我一開始的時候就是做BASIC的程式設計師,有些人會說我被永久地傷害了,這些人無疑是正確的。

但我不會為此道歉,所有的程式語言設計者都有他們一些怪癖在,我只是比大多數人在這方面還要好一些而已 :-)

RSTS BASIC/PLUS

儘管這樣當我還是使用PDP-11的一個RSTS程式設計師時,我確實把BASIC當作指令碼語言,至少在快速原型跟程序控制的條件上來說是這樣,我確定我的大腦已經永久反常了,Perl的語句修飾符(statement modifiers)直接利用了BASIC/PLUS,甚至有一些可愛的符號加在變數的尾端用來分辦字串跟整數與浮點數。

但是你可以做極限編程,事實上我有一個大學好友還跟我結隊編程,我們上了一個編譯器設計的課程並且從恐龍書(註:Compilers: Principles, Techniques, and Tools (2nd Edition) 這一本的封面因有恐龍而聞名)研究所有別出心裁的玩藝,當然那之後我們的教授宣佈我們可以實作我們自己的語言,叫做PL/0,經過一番思考,我們宣佈我們會在BASIC做我們的專案,教授看著我們好像瘋子一樣,在這個班沒有其他人使用BASIC,而你知道嗎?在這個班也沒有其它人完成他們的編譯器,我們不只完成了而且加了I/O的擴充並且把它叫做PL 0.5,那就是快速原型的道理。

Unix?

我記得有一天我們的電腦中心收到一封來自貝爾實驗室的信告訴我們可以便宜取得Unix V6的帶子,只要$100是因為他們最近會推出V7的版本,我們彼此相望並且說,為什麼我們會想要用這個稱作Unix的東西呢?我們已經有了RSTS。

JAM (no not that one)

我第一個指令碼語言是用BASIC寫的,我在電腦中心第一個工作是寫一個我叫做JAM的語言,Jury-rigged All-purpose Meta-language的縮寫,這是我一生的故事…

JAM事一個很像PHP且徹底的文字處理語言,除了HTML那時候還沒被發明出來之外,我們很多次用它來做BASIC的多樣化巨集處理,不像PHP,在一個命名空間擁有3,000個函式,我們不會為一件事而有這樣的記憶體。

LISP

不知識好是壞,當我去念研究所時,我學了語言學,所以我唯一使用的電腦語言是LISP,這是我個人的麥卡錫時代。

LISP適合作為指令碼語言嗎?雖然你可以很快速地用它來寫東西,但是我卻不會好心地把LISP當成是指令碼語言,按照政策來說,LISP從來沒有真正地照顧到一般人。

當然一般人也不會原諒LISP不迎合他們。

Pascal, Ada

當我進入行業之後,針對一個離散事件模擬器我用Pascal寫一個編譯器,並且垂涎著即將出世的Ada規格,作為一個語言學家,我不認為Ada是一個大型語言,現在的英文跟日文才是大型語言,Ada 只是一個中型的語言。

Unix, shell

幾年後,我終於結識了Unix和各種的指令碼語言,好吧,更精確地說是BSD跟csh。

BSD, csh

是啊,是啊,我知道,我更加的腦殘了…

我也學了一點點的C。

C

那就只是一點點的C,我還在學習那些函式庫。

shell + awk + sed + find + expr…

但是Unix shell語言的挫敗直接引導了Perl的建立,而我卻沒有時間來說,本質上我發現shell的指令碼受限於它的很多動詞沒有在它的控制下因此彼此嚴重地互相牴觸,而且名詞非常地缺乏限於字串跟檔案跟誰-知道-什麼(who-knows-what)的類型。

C xor shell

更具破壞性的就是那種一維的宇宙觀心態:你不是用C來寫程式就是用shell來寫,因為他們是截然不同的連續體的兩端,當我意識到指令碼不必總是得看成跟程式是對立的,應該有一種語言可以在這兩者間都做得很好的時候,Perl誕生了,這開闢了一個巨大的生態區隔,你們很多人有看過我舊的翻蓋圖有兩個manipulexity跟whipuptitude維度。

Tcl

Perl之後就是Tcl,在某種意義上它是比Perl更純的指令碼語言,Perl在方便的時候只是假裝每樣東西是字串,但Tcl真的相信它是一個控制的比喻,字串的比喻往往會有較差的表現影響,但這不是Tcl被冷落的原因,我想,有兩個原因。

首先是Tcl留在Unix的心態,控制工具是創見工具的死對頭,所以他們沒有很多的最佳化,畢竟快速的元件總是可以用C來寫不是嗎。

第二個原因就是缺乏合適的體面的擴充機制,所以最終你會期望有單獨的執行檔,像incr-tcl等等。

雖然我必須說我非常讚美Tcl語義的委派模式,但是卻落入跟LISP一樣的陷阱就是期望每個人使用一個真正的語法。

Python

Tcl之後就是Python,這是來自美國廣播公司給Guido啟發的領感,但是Python社群的心裡卻完全否認來自Perl的啟發,然而我並不是完全夠資格來評論Python,我並未真正瞭解Python,我只是偷了它的物件系統到Perl 5,我自己需要懺悔。

Ruby

我比較夠資格來評論Ruby–那是因為Ruby的很多語法的處理從Perl那裡借來,用Smalltalk語義來分層,我總是把Ruby看成是Perl這個生態區隔的最接近的對手,不只是因為借來的觀念,而是因為Perl跟Ruby這兩者有比Python更多的功能化的程式支援,換句話說,我認為Ruby搞砸了它聲明的語法等等。

*sh

與此同時Bourne shell擴充進Korn shell跟bash,這兩者我都沒有很多的處裡,謝天謝地,當你只是不斷地加入專門的句法功能的時候,我要說的是shell的持續發展只是顯示一個語言是如何的糟糕。

PHP

我們也看到了PHP的崛起,因為它採用較差的就是較好的方法來讓人讚嘆這新的深度,總的來說,PHP似乎也犯了跟早期Perl相同進展的錯誤,只是較慢而已,比較好的一件事就是它的打包,而當我說打包,我的意思不是命名空間。

JavaScript

然後有JavaScript,一個不錯得簡潔設計,它有些問題,但是長期執行下JavaScript實際上可能成為Perl 6執行於其上的合適平台,Pugs已經是JavaScript後台的一部分了,雖然不幸地去年遇到了一些問題(bitrot),我認為當新的JavaScript引擎出來時,我們可能看到JavaScript後台新的興趣出來。

Monad/PowerShell

我也看了一點Microsoft的單子(Monad),而我很高興注意到它的物件管道很像Perl 6,我只是希望他們不要申請專利。

Lua, AppleScript

還有其他指令碼語言的廣泛使用,不幸地,我必須承認我從來沒有仔細研究Lua或AppleScript,可能是因為我不是一個Mac的遊戲設計者。.

其實,我懷疑它比要帶到現在這個階段所要題的還深。

現在

當我看到現在的情況,我所看到的是各個不同的指令碼社群表現了很多像在叢林中的鄰近部落一樣,有時交易,有時交戰,但總的來說,僅維持使用自滿隔離的方式。

我傾向於採取人類學觀點來看這些東西,你們當中在這裡有很多人是Perl的程式設計師,但你們當中有些人是來自其他語言部落的,並根據您的部落的歷史,如果你是C語言的程式設計師,你可能會認為字串是指向位元陣列的指標,或是假如你是一個功能性的程式設計師你會認為是一個列表(list),又或者你是Java的程式設計師你會認為是一個物件,我以大寫字母T來把字串看成是一個文字。

Text

我從後現代的觀點來讀這個詞,當然,後現代這個詞本身是上下文相關的,有一些人認為,後現代主義的手段多了權力的庸俗,有些人認為Perl也是如此。

不過,我把後現代主義解釋為一個文字,不論口頭或書面,是一種需要兩端情報的溝通行為,有時在中間也是如此,我不想討論一個白痴的電腦語言,我想要我的電腦語言可以瞭解我輸入的字串。

Perl是一個後現代語言,很多保守派人士會認為後現代是一個相當自由的概念,所以相當諷刺的是我對後現代的觀點主要就是來自於語言學跟傳教士所教導的翻譯一樣,他們灌輸的一件事就是沒有原始人類語言這樣的事情,其中他們的意思基本上是所有人類語言是Turing完成。

當你離開所謂的原始部落並且分析他們的語言,你會發現他們的結構幾乎跟任何其他人類語言一樣的複雜,基本上如果你工作的夠久你就可以說任何的人類語言,人類語言是Turing完成的就是這樣。

因此,人類的語言不同,並不太能說清楚,但你又必須說,在英語中,你被迫區分單數的複數,在日本,你不必區分單複數,但你必須選擇特定禮貌等級,不只考慮到你正在交談的人尊重的程度,還要考慮到你所說得人或事的尊重程度。

所以讓你不得不說語言不同,顯然,如果你的語言強迫你說什麼,你就不能在某特定的領域簡潔的使用你的語言,這使我們回到指令碼。

對不同的指令碼語言來說有多少不同的方法是簡潔的?

在俄國有多少的羅宋湯煮法?

語言設計者有很多的自由,我要指出一些事情。

早期繫結 / 延遲繫結

繫結一詞就是你決定何時呼叫一個已知的程序名稱的程序,在早期的計算裡,大部分的細節為了效率的理由都相當早完成,不是在編譯時間就是最後的連結時期完成,在靜態類型的語言你仍會看到這樣的方法,然後在像Smalltalk這樣的語言,我們開始看到一個趨勢,這段時期大部分的指令碼語言正趨向延遲繫結,那是因為指令碼語言正試著按我的意思去做(dwimmy,o What I Mean縮寫),而最按我的意思去做的決定通常就是晚一點決定因為你會有比較多的語義跟更多實際的上下文可以使用,否則,你需要預測未來,而這又很難。

所以指令碼語言自然傾向移往物件導向的觀點,這樣細節會直到方法調度時間才會發生,雖然你仍然可以看到像C++跟Java那樣語言的衝突傷痕,C++將預設的方法型別做為非虛擬的,所以你必須說明確的虛擬來取得延遲繫結,基本上Java有final類別的符號,它強迫在編譯時期呼叫類別來約束,我認為這兩種方法有很大的錯誤,Perl 6 會產生不同的錯誤,在Perl 6裡所有的方法預設都是虛擬的,只有作為一個整體的應用程式可以告訴優化程序來將類別定案,大概只有你知道所有的類別如何被程式中其他的模組所使用。

單分派 / 多重分派

在某種意義上,多重分派是一種拖延繫結更長時間的一種方法,你不僅要拖延繫結直到你知道物件的型,而且也要在你挑選一個程序呼叫前知道所有參數的型態,Python跟Ruby只有單分派,而Dylan可以做多重分派,在這裡Perl 6 強迫 呼叫者要有明確的清晰度,我認為這是程式設計師很重要的區別要記住,因為單分派跟多重分派是非常不同的哲學思想,而且是基於不同的隱喻。

對於單分派的語言,你基本上送一個訊息給一個物件,然後這個物件決定如何處理該訊息,然而對於多重分派來說,沒有特權的對象,所有含括在這呼叫中的物件都有相同的權重,所以可將多重分派看成是完全被動的對象之一種方法,但是假如物件沒有決定如何繫結,那麼它是什麼?

嗯,這是有點民主的事,所有這些程序的名稱放在一起,舉行一次政治會議,(嗯,不是真的,但是這是解釋隱喻如何的運作),每一個程序是大會的一個代表,所有有意參選的程序將他們的名字放在帽子裡,然後所有的程序投票看誰是最好的候選者,以及下一個最好的以此類推,最後程序自己決定最好的程序來呼叫。

因此基本上,多重分派就像民主政治一樣,除了所有其他的其外,這是做後期繫結最糟糕的方法。

但我確實認為這是真的,而且很可能隨著時間的流逝成為真實,我花了很多時間在這個多重分派問題上,因為我覺得大型程式是隱含在單分派模式下的命令-控制模式的變異來的,大體來說我認為計算機領域正朝向那種較好決策模式就像由一群蟲子或魚類來做那樣,這種決策單一的個體是無法控制的,而整體來說蟲子的這種緊急行為不知怎地會比任何個體所做的決策還要聰明的多。

及早求值(eager evaluation) / 惰性球值(lazy evaluation)

大部分語言的求值策略,包括Perl 5在內,這些語言的計算所有運算式都盡可能地慢,Haskell就是一個很好的例子,它會直到被強迫才會做計算,這樣做的好處是你可以無限制地做很多很酷的事而不會用完記憶體,嗯,至少,直到有人要求程式來計算整個列表,然後,你幾乎在該區以任何語言,除非你有一個真正的圖靈機。

所以無論如何,我們在perl 6試驗一種及早和惰性的混合體,有趣的是,這個區別在Perl 5的純量環境對比串列環境的觀念非常地漂亮,所以在Perl 6純量環境是及早的而串列環境是惰性的,當然預設情況下,假如你喜歡你可以強迫純量是惰性的或串列是及早的,但是只要你的迴圈在你進入無線迴圈前有一些其他方法可以跳出的話你可以說像1..Inf的事。

及早類型(eager typology) / 惰性類型(lazy typology)

通常被稱作靜態跟動態,對調整旋鈕來說也同樣有不同的立場,我比較喜歡漸進型別方法有很多原因,效率是其中一個原因,人們通常認為強型別是一個原因,但是放型別到Perl 6的主要原因是不能是強型別,但卻是多重分派,記住我們政策性的慣用隱喻嗎?當不同的參選者放他們的名字進帽子中,他們有什麼區別?嗯,每個參選者都有他們自己的政見,這些政見裡的要點就是他們想回應的引數型別,我們都知道政客只善於回應他們想要有的引數型別…。

Perl 6稍微比Perl 5惰性有另一種方式,我們還有內容的概念,但是內容決定的時間已經改變,在Perl 5,電腦通常知道再編譯時期哪一個引數是純量的,哪一個引數是串列的,但是Perl 6延遲這個決定直到方法繫結時間,概念上來說就是執行時期,而非編譯時期,這對你來說可能似乎是奇怪的事,但是它卻可以修正很多Perl 5次優的設計,例如原型(Prototypes),還有外顯參考的需要, 還有其它惱人的小事情,像是在常見的問題中所見的事。

有限的結構(limited structures) / 豐富的結構(rich structures)

Awk、Lua跟PHP全都限制了它們的複合結構到關聯陣列,這有利也有弊,而且awk這樣做的事實讓它跟Perl有所不同的原因之一,以及排序陣列跟雜湊陣列的差異,我只是想他們的不同點,我想很多其他人也這樣做。

符號(symbolic) / 言語(wordy)

Arguably APL也是一種指令碼語言,主要是象徵性的,另一種極端的語言是避免用標點符號而改用文字,像是AppleScript跟COBOL,以及在較小的程度上所有的Algolish語言使用文字來C延伸語言用括弧來表示區塊,我喜歡這裡平衡的作法,每一個符號和識別符做他們最擅長的,我喜歡的是在程式設計師選擇很多實際的話來表達手頭上的問題,我不希望看到的僅僅是語法用字,這種句法函子只是掩蓋了真實的話,我知道這一點是當我從Pascal跳到C的時候,大括弧表示區塊,這只是視覺上的權利而已。

其實還有語言做得比COBOL更糟,我記得有一個Pascal變種需要你的關鍵字大寫這樣子他們才能引人注目,No, no, no, no, no!你不會想要你的函式受人注目,這是錯誤的喊話:IF! foo THEN! bar ELSE! baz END! END! END! END!

無論如何,我們在erl 6提高了那裡使用標點符號,哪裡我們不用的標準,我們擺脫了一些實際上並沒有很重要的標點符號,像是條件表示式周圍的括號以及許多的符號變數,而且我們也正在使所有其餘的標點符號更有效的使用,每個符號根據霍夫曼編碼(Huffman coding)已經足以證明其存在的必要。

奇怪的是,我們有一個正在引入新標點符號的地方,在sigil之後你可以增加一個twigil或是secondary sigil[註1],就像sigil告訴你一個物件的基本結構,twigil告訴你有一個特定的變數有一個奇怪的範圍,這是從Ruby那邊偷來的一個主意,它使用sigils來表示奇怪的範圍,但是藉著在我們的sigils後隱藏twigils,我們讓這兩個世界更好,加上一個可擴展的twigil系統來表達奇怪的範圍是我們之前尚未想過的。

我們擴展了很多思考,我們在思考我們尚未知道如何思考的語言部份,但是對於新的語言在語法的部份保留空間就像是一種對國家公園及國家森林保留一些我們的土地一樣,或者像一個考古學家不是挖考古遺址的一半,因為我們知道我們的後代將有比我們更好的分析工具一樣。

真正設計一個未來的語言需要包括很多的謙卑,正如科學一樣,你必須假設在很長的一段時期,你所思考的很多東西是真實的,卻變成不盡然如此,換句話說,假如你現在沒有做最好的猜測,你就不是真的在做科學,回顧過去,我們知道APL有太多奇怪的符號,但是我們不會清楚在開始的時候APL是否尚未試過。

註1:這個sigil、twigil跟secondary sigil好像沒看到怎麼翻成中文,這是Perl 6加了secondary sigil (twigil)功能,以用來指代不同scoping的變數,例如:

$*foo為全域變數,$=foo為pod變數,$.foo為object attribute accessor。

參見http://sunnavy.net/entry/00386cfe4c1611dfbc4a58baa9a5093e

編譯時期 / 執行時期

許多動態語言會在執行時期評估程式碼,Perl也採用另一個方向並且在編譯時期執行很多的程式碼,這會跟操作定義弄混,舉個例說,你不會想要在你的BEGIN區塊內做很多的檔案I/O,但這樣會引導我們討論別的差異:

宣告 / 操作

大部分的指令碼語言都是站在操作端那邊的,我認為Perl 5有一個簡單的物件系統直到我見到Lua為止,在Lua裡一個物件只是一個雜湊,而且假如它有含程式碼的話還有一點語法糖來呼叫一個雜湊元素,這就是所有的,它們甚至沒有類別,任何類似的繼承都必須透過明確的授權才能處理,那是Lua設計者所做的選擇以便讓語言很小而且可以嵌入,對他們來說,或許這是正確的選擇。

Perl 5總是比Python或Ruby有更多一點的宣告,我總是強烈地感到隱式範圍只是在自找麻煩,而且範圍變數宣告應該很簡單地清楚辨認,那就是為什麼我們有my,它很短是因為我知道我們常用它,霍夫曼編碼,保持常用的事簡短,但不要太短,像0就太短了。

Perl 6有許多不同的範疇,所以我們會有更多像my跟our之類的宣告,但外表會騙人,雖然這語言表面上來看有很多的宣告,但是我們讓大部分的宣告在檯面下運作以保持彈性,舉例來說當你宣告一個變數的型別,你只要用Perl 5的一種格式用tie來做,主要的不同在於你繫結實作到變數是在編譯時期而不是在執行時期,這是很有效率的,或至少有最佳化的潛能。

非可變類別 / 可變類別

在Java裡類別是封閉的,而這是Java可以執行相當快的理由之一,相對來說Ruby的類別是開放的,這意味著你可以在任何時期增加新的東西,保持這種開放的選擇或許也是Ruby執行很慢的原因之一,但是這樣的彈性卻也是為什麼Ruby有Rails的原因。

Perl 6在這裡有一個很有趣的非可變泛型跟可變類別的混合體,以及一個有趣的策略在誰被允許何時關閉類別,舉例來說,類別不被允許自行關閉或是了結,抱歉,為了某些原因我一直在談論Perl 6,由於事實在設計Perl 6時我必須考慮到所有這些層面。

類別基礎 / 原型基礎

這裡有另一個允許兩個方法可以談論的層面,你們有些人可能對無類別語言像是Self或是JavaScript熟悉,不像類別那樣,物件只是從他們的祖先複製或是授權給其他的物件,對於很多模型來說,這是比較接近真實世界的運作方式,真實的生物在他們再一次生產時只是在複製他們的DNA,它們沒有自己的DNA,而@ISA列會告訴你父物件含有他們其餘的DNA。

Perl 6的中介物件協定預設是類別基礎的,但它也有足夠的彈性來設定原型基礎的物件,你們有些人在Perl 5有玩過Moose,Moose基本上是Perl 6物件模式的原型,反正在語義方面,語法有一點不同,希望在Perl 6可以更自然一點。

被動資料、全域一致性 / 主動資料、局部一致性

你對資料和控制的看法會隨著你的大腦如何地功能化或物件導向而決定,人們的思考相異,有些人很數學性地思考,用可證明的普遍真理來措辭,功能化的程式設計師不太關心堆疊跟堆積之間內隱的計算狀態的實作,只要事情看起來很單純且不受副作用影響。

其他的人用社交的方式思考,它是依據每個合作實體都有他們自己的自由意志,儲存在每個個別物件的計算狀態對他們來說相當的重要,在某些地方不會關閉連續性的堆積。

當然,我們中的一些無法決定我們是要跟隨福爾摩斯的邏輯或是華生博士的交際,幸運的是,指令碼既不是很邏輯的也不是很交際的,因為這兩種方法可能對一般人來說更平易近人。

資訊的隱藏 / 範疇的界定 / 附件

最後假如你正在設計一個電腦語言,有無限多的方法可以來封裝資料,你必須決定哪些是重要的,什麼是最好的方法可以讓程式設計師實現關注點分離?

物件 / 類別 / 層面 / 閉合 / 模組 / 樣板 / 特性

你可以使用這些不同傳統的封裝機制的任一種。.

交易 / 反應 / 動態範疇

或者你可以以時間為基礎的不同領域方式來隔離資訊。

程序 / 執行緒 / 設備 / 環境

你可以附加資訊到不同的OS觀念。

螢幕 / 視窗 / 面板 / 選單 / 圖示

你可以在你的GUI隱藏資訊在不同地方,是啊!我知道,每件東西都是物件,但有些物件可能更合適。

句法範疇 / 語義範疇 / 語用學範疇

資訊可以附加各種不同抽象的程序包括很奇怪範疇的詞彙,但是假如你想得夠仔細的話,你會知道詞彙範疇也是動態範疇很有趣的一種,或是沒有正確執行的遞迴,一個state變數是真的比my變數還要單純的詞彙,因為它分享了所有呼叫的詞彙範疇,但是即使state變數複製了閉合的拷貝,只有全域變數才是真正的詞彙,只有在你指涉到全域變數到一給定的詞彙範疇,想想看吧。

因此我們大部分的範疇恰好是連接到一特定的句法範疇的語義範疇。

你可能會想知道什麼是語用學範疇(pragmatic scope),那是使用者的程式儲存在他們大腦中的範疇,或是他們大腦中的某些替代品,像是遊戲盒那樣,在一定的意義上,大部分Internet上的網頁是語用學範疇的一部分,正如大多數資料庫中的資料一樣,語用學範疇的特徵就是你不會真正知道容器的生命週期,它只是在那裡的某個地方,並且最終將由委大的垃圾收集器(Great Garbage Collector )收集所有那些別人遺忘的資訊,Google的暫存只能維持這麼久,最後我們會忘記每一個網址的意義,但是我們一定不會忘記網址的原則(principle of the URL),那會帶領我們到下一個自由的國度。

use Lingua::Perligata;

假如你允許一個語言在詞彙範疇內變異它自己的文法,你如何利落地追蹤?Perl 5發現了一個非常糟糕的方式來做,但即便如此我們已經結束了像Perligata跟Klingon這樣的Perl 的方言,假如我們真做對了它會像什麼?

要正確地處理包括處理語言的演進到一個或一系列的語用學範疇內,你必須能夠命名你的方言,有點像一個網址,所以需要有一個普遍的基礎語言,來歪曲普遍的根本語言到你喜歡的方言,這真的很接近Perl6願景的中心,我們不把Perl 6看成是一個單一的語言,而是視為一個相關家系的基礎語言,作為一個家系,會有共享的文化價值在姊妹語言跟後代語言之間來回地傳遞。

我希望你們對這些自由度會感到非常害怕,我敢肯定還有其他方面會更為可怕。

但是…我認為這是一個可管理的問題,我認為還是把Perl 6當成是指令碼語言可以很容易的就上路是可能的。

我認為它可以管理是因為,對每一個維度來說,它不只是一個二元決策,而是被定位在設計時期、編譯時期或甚至是執行時期的旋鈕,對一給定的維度X,不同的指令碼語言可以做不同的選擇,將旋鈕設在不同的位置。

You can’t even think about X!(你甚至不能考慮X!)

There’s only one way to do X!(只有一個方法做X!)

There’s more than one way to do X!(有一個以上的方法做X!)

There are too many ways to do X!(有太多的方法做X!)

你可以在這裡認識一些口號。

捲縮

所以我不建議所有的指令碼語言把所有的維度都考量進來,即使是Perl 6嘗試這樣做,指令碼範例不是這些維度的任一種,根據不同的理論宇宙是10個或20個維度鋪設成的,但是通常我們只能得到三個半維度,其餘的可以說是被捲縮,或許我們可以活在一個指令碼的宇宙中。

在大部分的指令碼語言中我們稱Perl 6在大部分的時間有大部分的維度捲縮起來,但是不像真實的宇宙那樣,需要使用巨大的機器還使這些維度變直,我們只需要直接保持我們的宣告就可以使這些維度變直,嗯,我們可以試試看,在哪裡失敗,我們就可以依靠文化來讓事情變直。

舉例來說,這正是Perl 5已經發生過的,我們有這個宣告,use strict; use warnings;,但它的文化,決定執行他們的使用,正因如此,我們已經決定,大部分的Perl 6也應該是預設如此,它是蜂巢決策之一,再這個例子裡蜜蜂會變成較語言設計者還要聰明,而這也應該如此。

未來

嗯,所以指令碼的未來是什麼?

就我完全公正的意見裡,那就是Perl 6. :-)

雖然嚴肅一點來說,預測這個生態環境會結束許多小語言以及一些主要的語言是無風險的,有些語言像AppleScript有獨特的生態區位而且也不可能繼續成長,其他的語言習慣他們原來的區位外,總是有一些通才,像是烏鴉跟小嘲鶇,跟專才像是企鵝跟渡渡鳥。(或許不會一直都是渡渡鳥…)

在通才之間,傳統的觀點認為愈差就愈好的方法是比較可以適應的,就個人而言,我對這個論點感到有點厭倦:我的愈差就愈好比你的愈差就愈好還要好因為我的愈好是更糟的!難道愈差就愈好這個方法總是會贏這是真的嗎?現在我們正試圖在Perl 6偷用愈好就事愈好得循環並且希望可以在還回到經驗可靠的愈差就愈好的方法前可以出人頭地,不論是否可行,只有時間可以證明一切。

感謝你看到這裡,很快就可以離開了,但最好的獎勵行動就是按一下幫我分享或留言,感恩喔~

點我分享到Facebook

2 則留言

  1. Author

    這一篇真的很長,也頗難翻的,算是培養耐力吧!

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *