當前位置:
首頁 > 科技 > 開發者編程時應該圍著「程序」轉嗎?

開發者編程時應該圍著「程序」轉嗎?

編程的世界圍繞著程序轉,這是毋庸置疑的。本文的作者則提出了一個更廣泛的、以系統為中心的觀點,他認為「系統」才是編程的最終目標。

以下為譯文:

維基百科「計算機」頁面上的第二句話就提到了「程序」。我們對程序很著迷,了解如何創建程序,如何構建、運行和調試程序,如何可視化程序,選擇哪個語言編寫我們的程序,每個語言的類型系統和語法是什麼......等等。

從表面上看,這似乎並沒有錯,但是這裡面蘊含著一種假設,即編程的世界圍繞著程序轉。

如果我們的立足點是我們想「編寫程序」,那麼我們已經將自己局限在了某個特定的思維框架中,我們必須完整地編寫一個程序,然後提交給系統,經過構建和集成,最後再運行。

但這不是有點過頭了?「程序」真的是最終目標嗎?我的立場是,我們需要使用以系統為中心的觀點重新建立我們的目標,具體如下:

系統由與我們交互的硬體和軟體組成:這包括硬體設備和一些沒有名字的軟體實體或產物。

系統展示行為:我們與系統交互,系統響應輸入,產生輸出(屏幕上的圖像,聲音等)。

我們修改行為。

換句話說:

系統沒有展示我們想要的行為;

我們「採取措施」(包括操控沒有名字的軟體實體);

然後系統展示出我們期望的行為。

這裡的「採取措施」一般情況下指的都是對系統進行編程,而這樣的系統自然是指可編程的系統!程序本身是系統交互的一種類型,也許我們不應該明確地劃分「對系統進行編程」和「使用系統」。

好了,廢話不多說,現在我可以提出這樣一個目標:

我們真正的目標是設計軟體「實體」的形式和性質,而該軟體「實體」即為我們在編寫和使用系統時操控和創作的「可編寫的基板」。

我有意將這項工作全部歸結為設計的問題,在設計中處理概念和抽象的發明,而這些我們可以稱之為基板。這個設計的範圍非常廣闊,你可以非常自由地發明各種記法、概念、工具、媒體等等,以任何方式勾勒「軟體編寫的虛擬世界」——但是我們必須小心地甄別所有引入的概念。

需要引入文件和文件系統嗎?需要編譯器、資料庫、操作系統、可執行文件和操作系統進程嗎?在這個空間中,所有這些計算的附屬概念還都不存在,我們只有一張白紙。在這個後編程時代(或許應該叫做「前編程時代」)的思維模式中,我們該怎麼處理這些自由度?

程序的思想

首先,讓我們回顧一下程序的概念,但要注意程序只是對系統編程的方式之一(請注意動詞「編程」和名詞「程序」的區別)。

我們說「有一個叫做程序的東西」,然後繼續描述這個概念是什麼、如何使用等等,這通常是我們在計算機入門教材或維基百科上「程序」的頁面中所能看到的內容。我們對「編程思想」已瞭然於心,但是我想在這裡談論有關編程思想的事情。

程序就好像程序員撰寫的文章,它有自己的結構,通過一種主要的視覺表現手法呈現,程序員通過這種表現手法(即源代碼)來查看並操控程序。程序包含了一次「執行」的詳細步驟,這意味著它可以在某個時候「運行」,從而產生一個「運行中的程序」。請不要誤解成存在一種「不運行的程序」,這裡的「運行中的程序」只不過是原來的程序加上某種運行時狀態而已,這些狀態附著在程序的各個部分,並會隨著程序的運行而改變。這就引入了兩個階段的概念——運行和未運行。程序的定義也是一種概念一般化,即程序可以擁有多個運行中的實例,每個實例的細節都不完全相同。

操作系統進程也是程序

在Unix(以及Windows和Mac)中,程序的概念通常被當做操作系統的進程。如果我們接受這種關聯,將操作系統的進程看作一種程序,我們就可以繼續提供更多描述性的細節。例如,當一個運行程序停止時,所有運行時的狀態會被立即清除。對於長期的狀態,程序可以在運行的時候修改外部狀態,也就是說我們需要定義外部狀態是什麼,或者至少要定義內部和外部之間的耦合。

我們還需要一些編寫和調用程序的工具軟體,我們通過其他程序(比如編輯器、編譯器、shell和GUI等)從外部操作程序。

最後,我們需要一些顯示和交互的概念,運行程序通過這些概念與我們交互。通常,這就是為用戶設計的「運行時的用戶界面」(程序的第二種視覺表現手法)。在有些情況下,程序員同時也是用戶,但這並不妨礙我們使用兩種不同的表示方法。程序還可以與其他程序交互,這就涉及兩個程序之間如何互相定位,以及交互本身的性質等問題。

我想說明的是,程序有一個框架,即有關程序方面的工作中常見的、不言而喻的假設。我想在這裡註明以下三個方面:

1、我們需要做出很多的選擇,我們可以隨時決定改變方向。畢竟,這些概念都是人為提出來的。例如,我們可以選擇非純文本的方式表示所有。或者我們可以只選擇一種表現手法(而不是兩種——主要表現手法和第二種表現手法,即源代碼和運行時的用戶界面)。我們仍然能得到程序,雖然它們的工作方式不同。

2、似乎我們不能只引入一個單獨的概念。概念之間相輔相成,所以我們需要引入一整套相互關聯的概念。這是否意味著如果我們將「程序概念」引入另一個世界,我們就需要引入許多相關概念?可能吧,如果設計整個軟體世界的話,就需要考慮這些情況。

3、程序或操作系統進程的概念可以解決的問題與不能解決的問題之間有一個界限。例如,如果我想在一個大程序內定義小程序(這個想法很合理,因為所有進程都可以分解成小進程),那麼就只能自己想辦法了。

想想主流操作系統的工作原理,我們還可以確定一系列的設計選擇,這就可以決定包含哪些內容,不包含哪些,例如:

所有外部進程的持久系統狀態都以命名位元組blob的方式保存在分層文件系統中,並由運行中的進程明確進行管理;

IPC和進程內核通信通過C語義實現成API調用;

系統不提供將單個進程分成不同的部分的隔離機制;

不提供保存運行進程的狀態或回滾到前一個狀態的機制;

不提供替換正在運行的進程的某個部分的機制。

系統不提供的內容都可以由「用戶空間」特定的程序解決,但核心抽象仍然可以決定常見且簡單的內容。

有關「程序」的討論夠多了,讓我們繼續看看更有趣的幾個問題:

我們是否需要將「程序」的概念引入到我們的各種軟體中?在沒有「編程思想」的情況下,我們能否擁有一個可編程的系統?

沒有程序的編程

這個問題最簡單最明顯的例子就是各種Smalltalk系統,它們把所有程序視為一個完整的系統。程序並不是在另一個系統內運行的程序(即不是像Unix中的進程,而是啟動後的系統中的一部分)。

Smalltalk系統提供了「對象」和「消息」的概念,而沒有「程序」(或文件)的概念:系統是一組互相發送消息的對象;每個對象都像一個微型系統(負責接收和發送消息),每個微型系統都有自己的行為;一些特殊對象稱為類,它們負責大量類似對象的行為定義;輸入設備、輸出設備和其他用戶界面設備都表示成對象;事件和交互表示成消息。

對這個系統進行編程需要通過發送消息來重新配置對象的集合,或者在需要的時候創建一些新對象和類。但它不需要編寫程序。

該系統中沒有編譯,因此它只有一個「階段」,也就是說系統總是活躍的。系統支持自動持久,因此當系統關閉後再打開時,對象會回到上次的狀態。

這個系統中還有許多有趣的地方:對象可能有多種表示方法,所有使用該系統的人都可以用,無論是用戶還是程序員。

對象間的消息傳遞沒有內置的驗證系統,但是我們可以想像根據某些概念進行分層,比如引入某種一致性檢查,來檢查對象簇,或在對象間的點對點「連接」建立時的進行檢查。

這裡並不是說Smalltalk是一個更好的系統,而是它從根本上揭示了一個完全不同的系統觀點,而且還可能有其他不同且更有趣的觀點。

系統觀點

程序只是大系統中的一小部分。通過編寫程序的方式來製作系統,意味著首先我們需要將系統分割成程序,這些程序有各自的特定特徵。我們也可以用許多其他方法來分割系統——這正是我們應該探索的空間。

我們可以對比一下以程序為中心的觀點和與系統為中心的觀點,如下所示:

系統分割的大部分在我們開始編寫之前就已經完成了,它通過主流軟體提供的概念鞏固自己的地位:操作系統、文件、應用程序、資料庫、編譯器等。在我看來,我們需要重新考慮整個系統分解模型。僅僅發明某一既有部分的新版本(例如新的文本編程語言)不會危害到它,因為我們仍然在相同的模型中運行。

不同軸上的自由度

雖然Smalltalk模型在單個「空間」內保存了大量對象,但我們可以想像有一個系統,裡面的每個對象都有內部空間,空間里保存了一組內部對象,依此類推。這樣就在設計中引入了遞歸。

從另一個方向,我們還可以考慮用增量模型替換先寫後運行的編程思想(即「提交論文」的模型),在增量模型中程序員可以連續提供更多有關期望行為的細節,以及細化該行為的約束求解系統(即「對話」模型)。

另一種方法是引入時間管理,將其作為基板的第一個類概念,這樣可以給所有工作成果加上版本進行管理,並追蹤每個版本的變遷。這意味著你可以在任何上下文中回復或前進,例如暫停或回滾多個跨度。

如果在操作系統里創建一個高級的消息模型,怎麼樣呢?那我們就不需要重實現各個類型的位元組顯示方式了。

或許我們可以運行一個虛擬機,並在這個虛擬機上編程,那麼分配、隔離和分割在多台機器上的執行任務就會更加容易。

我們的系統是否可以成為一個巨大的互連單元網格,擁有Excel的功能、一些合理的命名空間以及自動處理更新?輸入/輸出也可以表示為特殊的單元格。

我們認為在設計新的編程語言時我們有很多自由,但實際上整個主流編程語言只是主流系統的新興模式。不同的基板會產生不同的模式。

如果系統給我們一些響應單元,而不是"文件"和"進程",那麼"編程語言"會是什麼樣子?有關語法的爭論將會大大不同,因為我們需要處理的是單元而不是自由形式的純文本。反應度是系統核心功能的一部分,因此我們根本無需想像和設計構建系統。

語言和工具之間的界限開始變得模糊。

這個領域中有太多的選擇可供探索,甚至是我們引入概念的順序也會產生影響。也許我們可以在這個系統中尋找我們了解的好點子,看看是否可以提煉出本質?接下來該怎麼辦我也不是很清楚,但這讓我感到興奮。

相關的工作

在這篇優秀的論文Semprola paper(https://www.shift-society.org/salon/papers/2018/revised/semprola.pdf)中,Oli Sharpe寫道:

另一種傳統的選擇是,將程序視為一個孤立的數學或其他形式的構造,其語義主要在編譯時參考自身及其導入的庫來確定。考慮到編程的歷史,我們繼承這一觀點是很合理的,但是如今許多「程序」實際上只是一個更大的、「活躍的」程序和服務網路中的一小部分,每個程序和服務都按照自己的頻率更新。因此,沒有統一的編譯時間,而某一部分與整體相關的語義即使沒有更新,也可以跟著整體一起更新。

這段描寫很好地捕捉了我們在以程序為中心的思維模式中採用的觀點。另一篇很棒的文章是Tomas Petricek寫的互動式編程(http://tomasp.net/blog/2018/programming-interaction/),其中寫道:

換句話說,編程語言研究不應該學習程序,而應該學習編程!

Tomas強調了要查看整個工作流程,而不是只關注「輸入程序」的最終產品。

總結

我們不應該考慮「編寫程序」,而是應該將「製作系統」作為首要目標。這個系統是一個不斷發展且永遠存在的實體,我們希望使用抽象的概念(我們稱之為「軟體基板」)來編寫這個系統。那麼我們的核心基板都有哪些想法、概念和抽象呢?這正是我們需要提出的問題。

在初學者的心目中有很多種可能性,但在專家的腦海里卻幾乎沒有。——Shunryu Suzuki

我們需要站在初學者的立場重新思考編程。

原文:https://shalabh.com/programmable-systems/systems-not-programs.html

作者:shalabh,美國軟體工程師,主要從事Python開發。

譯者:彎月,責編:郭芮

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 CSDN 的精彩文章:

阿里全盤調整組織架構意味著什麼?|暢言
如何使用 AOP 和自定義註解?

TAG:CSDN |