OCaml 平台路線圖

本文概述 OCaml 平台為期三年的路線圖 (2024 年至 2026 年)。它定義了我們期望在未來幾年實現的開發者體驗。

OCaml 平台是一系列工具的集合,每個工具都旨在促進不同的開發工作流程。每個工具都有其獨特的願景和路線圖。本文的目的不是規劃這些路線圖。相反地,它是為它們提供一個總體指導方針,確保各個工具的路線圖與 OCaml 開發體驗的更大願景保持一致。

本文的核心目標是闡明我們(OCaml 平台團隊和更廣泛的 OCaml 社群)旨在提供的開發者體驗類型。在這樣做的過程中,我們努力保持以使用者為導向的視角,僅在必要時深入探討技術細節。

此路線圖的結構建立在 OCaml 平台旨在支援的開發工作流程之上。每個工作流程都定義為一系列我們希望在未來三年內實現的陳述。此格式設計有雙重目的:首先,讓讀者清楚了解他們未來可以使用 OCaml 獲得的開發者體驗;其次,讓平台維護者和貢獻者可以輕鬆地將路線圖轉化為不同平台工具的可執行任務或專案。

願景與目標

我們對 OCaml 平台的總體願景是為每個開發工作流程創造無縫的體驗。

我們設想一個開發環境,其中每個開發任務都得到支援和最大程度的優化,並且在可能的情況下,不需要任何人工互動。我們在指導原則中為工具制定了具體的願景指導方針。

在本節中,我們確定了未來三年需要關注的三個主要領域。

(G1) Dune 是 OCaml 平台的前端

遵循 (P5) (工具是獨立的,但又是統一的),Dune 成為使用者在 OCaml 中開發時唯一需要使用的工具。

Dune 已經與大多數平台工具整合,以創建一致的體驗,但它缺少兩個顯著的整合,這迫使使用者必須使用多個工具:套件管理和套件發布。它應該與 opam 和 opam-publish/dune-release 整合,以提供這些工作流程。

它也應該與任何新孵化的平台工具整合作為實驗性功能。

由於 Dune 是 OCaml 平台的前端,因此它成為使用者開始使用 OCaml 唯一需要的工具。開始使用 OCaml 的建議方式是透過系統套件管理員安裝 Dune。安裝 OCaml 變得像 apt install dune 一樣簡單。

遵循 (P2) (體驗是多功能的,但又是無縫的),Dune 應該為所有支援的平台開發工作流程提供簡潔且直覺的 CLI。特別是,它應該協調它們並在需要時自動安裝它們。最終,Dune 的使用者不應知道他們正在幕後使用單獨的工具。

(G2) 支援新的開發工作流程

遵循 (P2) (體驗是多功能的,但又是無縫的),未來三年的首要任務是填補目前開發體驗中的空白。

目標是孵化新的平台工具,以支援最重要的缺失的開發工作流程。根據 OCaml 生態系統的狀態和社群回饋,我們計劃孵化工具 (或在適當情況下擴展現有工具) 以支援以下工作流程

  • 程式碼檢查: 使用一組預定義的程式碼檢查規則來檢查 OCaml 專案。
  • 效能基準測試: 執行 OCaml 專案的效能基準測試,以測試效能改進/衰退。
  • 形式驗證: 將形式規格驗證作為常規測試工作流程的一部分執行。
  • 產生安裝程式: 產生特定平台的安裝程式,例如 .msi.deb,以輕鬆分發 OCaml 專案。
  • 程式碼審核: 使用已知安全公告資料庫審核 OCaml 專案。

(G3) 使現有的工作流程成熟

最後,我們將繼續使支援的開發工作流程成熟。使用者回饋顯示,目前的開發體驗可以改進。常見請求的範例包括從 Dune CLI 執行單個測試的能力;無需供應那些相依套件就供應相依套件的能力;Merlin 查詢執行程式碼重構,例如重新命名值和函數;等等。

「工作流程」部分會更詳細地介紹我們計劃在未來幾年改進的工作流程,但我們重點介紹三個非常重要的工作流程

  • 安裝 OCaml: 安裝完整的 OCaml 開發環境無疑是採用的一個重要障礙。隨著 Dune 成為平台的前端,安裝 OCaml 應該像 apt install dunewinget install dune 一樣簡單。
  • 除錯: OCaml 編譯器支援使用 ocamldebug 進行除錯。為了讓除錯 OCaml 程式更容易;但是,使用者應該能夠從 Dune 或其編輯器執行除錯器。OCaml 平台應該提供 除錯器介面協定 實作,以支援編輯器整合,並且 Dune 應該與 ocamldebug 整合,以便為 Dune 專案提供直覺式的除錯工作流程。
  • 產生文件: OCaml 套件的高品質文件可用性仍然是 OCaml 開發人員回報的主要痛點之一,也是語言採用的一個主要障礙。最近為改善這種情況所做的努力包括 OCaml.org 上的新中央套件文件。但是,可用的文件產生工具不適合建立使用者手冊。為了激勵開發人員為其套件編寫高品質的文件,一個優先事項是改進工具以支援此用例。

工作流程

為了清楚起見,我們將工作流程分為以下用例

  • 開始使用: 安裝 OCaml 開發環境
  • 開發: 建立和開發軟體
  • 檢查: 檢查和理解程式碼
  • 編輯: 使用程式碼編輯器開發 OCaml
  • 維護: 維護專案並確保程式碼品質
  • 分享: 與世界分享軟體

開始使用

OCaml 平台根據用例和使用者類型,提供各種開始使用 OCaml 的方式。

(W1) 從命令列

若要從命令列驅動您的工作流程,您可以安裝 dune

# On Ubuntu
sudo apt install dune
# On macOS
brew install dune
# On Windows
winget install dune

Dune 二進位檔案會封裝在所有第一層級支援的環境中。它也可以作為二進位檔案下載用於其他環境

bash < <(curl -sL https://ocaml.dev.org.tw/setup.sh)

安裝後,您可以下載 OCaml 專案並執行它,方法如下

git clone git@github.com:ocaml/foo.git
cd foo
dune exec my-cli

或執行

dune fmt # To format your code
dune doc # To generate your documentation
dune test # To run the project's tests

在幕後,Dune 使用 OCaml 平台工具作為函式庫或驅動其二進位檔案。但是,這對使用者是隱藏的。如果 Dune 需要工具來執行特定的開發人員工作流程,它會為使用者安裝它。

(W2) 從編輯器

上述設定是為習慣於命令列並希望保持控制的人量身定制的。其他使用者,例如想要快速入門的程式語言愛好者 (U4),可以在他們最喜歡的編輯器上開啟並安裝 OCaml 擴充功能

code --install-extension ocaml.vscode-ocaml # On VSCode
M-x package-install ocaml-mode # On Emacs
Plug 'ocaml/ocaml.vim' # On Vim

編輯器的擴充功能會在使用者系統上安裝 Dune (如果尚未安裝),而 Dune 本身會按照設計原則 (P1) 和 (P5) 按需安裝編輯器擴充功能所需的所有工具,以提供開箱即用的完整編輯體驗。

所有編輯器的擴充功能都與 OCaml LSP 伺服器互動。除了 LSP 協定提供的所有功能 (包括語法突出顯示、錯誤回報、語法完成等) 之外,這些擴充功能還提供 OCaml 平台特有的功能,例如推廣差異、執行 Dune 可執行檔等。

(W3) 使用開發容器

開發容器是與編輯器整合的 Docker 容器,特別是可以與 VSCode 的開發容器擴充功能和 GitHub Codespaces 無縫使用。

它是一個特別適合教師 (U5) 的工作流程,他們必須為學生支援各種不同的環境。

若要讓使用者使用開發容器設定專案,專案本身必須將 devcontainers 設定檔提交到儲存庫。然後,像 VSCode 這樣的編輯器可以選取設定,並透過 Docker 容器提供所有編輯器的功能。

OCaml 平台提供包含完整開發環境的官方開發容器。

開發

(W4) 建置專案

開發者在檢出既有專案後,首要之務就是能夠建置它。

獨特的指令

在 OCaml 中,只需執行以下獨特指令即可:

dune build

這會自動安裝專案的所有相依性,透過讀取專案的中繼資料(位於 dune-projectdune-workspace 檔案中)來推斷。它會安裝套件相依性和函式庫,並設定所需的編譯器版本。它也會根據使用者的系統,輸出相關的套件管理器指令來安裝系統相依性,以提示使用者如何安裝系統相依性。Dune 的快取會在多個專案之間共用,因此設定速度可以非常快。

一個單一指令即可設定和建置專案,這在任何使用 Dune 的 OCaml 專案中都很常見,這使得新的貢獻者更容易快速上手並提高生產力,無論是小型還是大型專案,都遵循 (P1) 和 (P3) 原則。

Dune 也可與非 Dune 套件作為相依性一起運作。它會透過讀取 .opam 檔案,找出遺失的中繼資料和建置指令,並將其嵌入到其建置圖中。

在開發期間,支援兩種建置專案的工作流程:在命令列中和透過編輯器。這兩種工作流程是相容的,可以一起使用。

監看模式

Dune 提供監看模式,其中任何檔案修改都會觸發重建。感謝 Dune 的快取機制,只有受變更影響的部分會被重新編譯。

監看模式會明確指出它執行的目標(@runtest 或 @install),開發人員可以並行重新執行測試或調用其他目標(通常,可以在監看模式下執行建置,並在另一個終端機中在監看模式下執行測試)。

編輯器整合

類似於直接透過編輯器安裝 Dune,也可以在不離開編輯器的情況下驅動 Dune。

編輯器支援透過專用的 UI 建置和執行專案。可以從編輯器檢視 Dune 報告的任何資訊,例如列出專案範圍內的錯誤、跳到報告的位置等等。編輯器使用 Dune 的監看模式執行個體,這表示檔案中的任何修改都會觸發重建並更新報告的錯誤。

所有這些對於使用者都是透明的,他們只需要設定他們的編輯器即可。

在不同環境中工作

Dune 可以使用不同的組態集(稱為環境)來建置專案。環境包含有關使用的 OCaml 編譯器、編譯標誌、環境變數等資訊。它具有足夠的表達能力,可以透過提供要使用的來源 URL 來定義編譯器版本,例如,在編譯器的特定分支上進行測試。

使用者可以為不同的目的定義多個環境,例如測試、發布和基準測試。

環境在 dune-workspace 檔案中定義。要使用的環境的選擇是透過將引數傳遞給建置指令來完成的,以避免任何全域狀態。這提高了可重現性,並避免追蹤目前使用的環境,從而產生更簡單的心智模型 (P3)。

(W5) 管理相依性

相依性的真實來源是提交到儲存庫的中繼資料檔案(即 dune-project 檔案)。專案是使用從 dune-project 產生的鎖定檔來建置的。

若要更新專案的相依性,使用者可以直接編輯該檔案,執行 dune lock 並重建專案。這在監看模式下也運作良好:當專案的相依性發生變更時,Dune 會偵測到,重新產生鎖定檔,並執行包含先前狀態和新狀態之間差異的建置圖。

此外,opam 儲存庫包含每個套件中函式庫的對應。這允許 Dune 和其他 opam 用戶端在目前的環境中沒有函式庫時向使用者提供提示。透過查看套件及其函式庫的清單,Dune 能夠建議安裝特定的套件以使用函式庫。

(W6) 供應商相依性

對於函式庫和應用程式開發人員((U1) 和 (U2)),在開發期間,處理專案的相依性通常很有用,無論是修正在開發期間發現的錯誤,還是需要同時將變更應用於專案及其相依性時。

Dune 提供了一種供應商相依性的方法。

dune vendor <dependency>

這會將相依性的原始碼從建置目錄複製到專案的原始碼樹狀結構中。

供應商相依性的運作方式與它們在建置目錄中時相同,只是它們的原始碼可以由使用者修改 (P3)。通常,供應商相依性與作為其他套件的傳遞相依性不衝突:將其作為相依性的套件將連結到供應商版本。

(W7) 產生專案

看看其他社群,專案產生是新手開始專案最有利的事情之一。

對於簡單的專案,它會向使用者顯示 OCaml 專案所需的基本樣板。

對於更複雜的專案,它允許使用者從已編碼所有慣例和組態的可用應用程式開始。對於初學者來說,閱讀程式碼庫並擴充它遠比學習從頭開始建立所需的所有部分要容易得多。

Dune 提供 dune init 指令來產生專案。

它可以產生包含函式庫、可執行檔和測試的簡單專案 (R1, R4)。

它也可以從遠端範本產生專案,例如,託管在 GitHub 儲存庫上 (P1)。

專案範本是可組態的,而 dune init 提供一個精靈來設定組態。例如,dune init 可以詢問使用者他們想要使用哪個許可證。

從範本產生專案後,dune init 允許使用者透過產生新元件來擴充他們的專案。元件可以是通用的,例如函式庫、測試,但也可以是範本特定的,例如 Web 應用程式中的驗證模組。

(W8) 格式化程式碼

Dune 提供 dune fmt 指令來格式化專案中的程式碼。

在幕後,它與不同的格式化工具整合,以格式化 OCaml 專案中的不同檔案。Dune 的內部格式化工具用於 Dune 檔案,OCamlFormat 用於 OCaml 檔案,Refmt 用於 Reason 檔案等等。

使用者無需設定格式化工具即可格式化其程式碼:有一些很好的預設值可以以慣用的方式格式化程式碼 (P1)。

但是,這些工具是完全可組態的,而使用者 (U1 和 U2) 可以自訂他們想要如何格式化程式碼 (P1)。Dune 為此目的提供了一個節點,該節點在驅動各種工具時會作為組態傳遞。

此外,程式碼格式化是回溯相容的 (P4)。要麼工具本身是回溯相容的,並且它們知道如何使用特定版本的工具進行格式化,要麼 Dune 本身會安裝正確版本的工具以保持回溯相容性。

(W9) 檢查程式碼

雖然 OCaml 編譯器會提供有關程式碼的某些斷言,特別是歸功於靜態型別系統,但它並不能防止所有錯誤和問題。

通常,編譯器不會通知使用者檔案描述器永遠不會關閉。

它也不會提供有關專案採用以確保程式碼品質的慣例的提示。例如,Dune 程式碼庫鼓勵開發人員為每個型別建立一個模組,而不是在一個模組中有多個型別。或者 OCaml LSP 程式碼庫鼓勵使用者將模式比對的最短子句放在最前面。

為此,Dune 透過與 OCaml 程式碼檢查器整合來提供檢查功能。

Dune 也可以僅透過 dune lint 指令執行檢查管道 (R1)。

與格式化組態類似,可以在 dune-project 中指定檢查組態和設定檔。

Dune 會在建置期間將檢查失敗回報為警告,而這些錯誤會回報給編輯器,這歸功於 OCaml LSP 和 Dune RPC 的整合。

(W10) 開啟 REPL

包含 REPL 的語言的優勢之一是,您可以非常互動地進行程式設計,即時從解譯器接收有關正在計算的值的回饋。這對於希望在不費心建立檔案的情況下實驗該語言,並且重視解譯器提供的所有其他資訊的語言愛好者 (U4) 尤其有趣。

可以使用以下方式開啟具有良好 UX、歷史記錄、自動完成和行編輯的 REPL:

dune repl

雖然開啟具有所有可用公用模組的 REPL 是預設值,但 Dune 為函式庫使用者提供了更多選項 (P1, P3)。它可以開啟一個對包含的模組具有更多控制權的 REPL,例如,僅指定一個模組或所有模組(包括私有模組)。它也可以包含不受其簽名檔限制的模組。

最後,開啟 REPL 已很好地整合到編輯器中。您可以輕鬆取得一個具有與目前開啟的檔案之一對應的環境,並在那裡執行一段程式碼以進行測試。

(W11) 跨平台編譯

Dune 利用 OCaml 編譯器的第一級跨平台編譯支援來支援二進位檔的跨平台編譯。

可以將目標新增至 dune-workspace 檔案

(context
  (default
    (targets native windows android)))

這會使 Dune 為目前系統、Windows 和 Android 產生目標。

使用者也可以使用 dune build -x <target> 來為特定目標產生目標。

由於編譯器中原生支援跨平台編譯,Dune 中的跨平台編譯與相依性使用的建置系統無關:如果使用者依賴使用不同建置系統的套件,Dune 仍然能夠為外部平台編譯可執行檔。

Dune 原生支援編譯時的動態或靜態連結,包括在進行跨平台編譯時。

Dune 支援跨平台編譯到以下平台:Windows、macOS、iOS、Android。

(W12) 編譯到 MirageOS

MirageOS 是一個函式庫作業系統,它為各種雲端運算和行動平台建構用於安全、高效能網路應用程式的單核心。

除了允許跨平台編譯到 Windows、macOS、iOS 和 Android 等原生平台之外,Dune 還支援 MirageOS 單核心作為跨平台編譯目標。

dune build -x mirage

此工作流程不需要使用任何第三方 opam 儲存庫。

(W13) 編譯到 JavaScript

OCaml 生態系統的一個重要特性是能夠將 OCaml 程式碼編譯為 JavaScript。目前,這是通過從位元組碼編譯(Js_of_ocaml)或直接從 OCaml 原始碼編譯(Melange)來實現的。

這允許使用者直接用 OCaml 編寫 JavaScript 應用程式。這包括動態部分(作為 JavaScript 的替代方案),也包括前端,例如使用 Tyxml,它也可以受益於 FRP。最後,前端和後端的程式碼使用相同的語言,允許共享程式碼並更容易地傳遞值。

在 Dune 中將目標語言從原生程式碼更改為 JavaScript,只需要在 dune 檔案中添加一行即可。

(executable
  ...
  (modes js melange))

(W14) 編譯為 WebAssembly

對 WebAssembly 的編譯方式與 JavaScript 編譯類似:使用者可以在其 dune 檔案中添加 wasm 模式,以生成 WebAssembly 編譯目標作為其建置的一部分。

(executable
  ...
  (modes wasm))

(W15) 外掛程式擴展性

遵循 (P6)(平台是緊密的,但可擴展),Dune 允許外部工具通過外掛程式系統擴展其語言以添加新的建置規則。

這些外掛程式不會違反 Dune 的可組合性原則。特別是,外掛程式之間不應該有耦合,或最多是鬆散的耦合。

此外,為了遵守 (P5)(工具是獨立的,但統一的),外掛程式可以獨立於 Dune 使用。

Dune 外掛程式系統的基礎是,新的工具可能需要數年才能整合到 Dune 中。為了更好地適應工具的生命週期,Dune 外掛程式系統用於在預孵化和孵化階段進行快速迭代,並限制向後兼容性,直到工具進入活躍階段並作為一等公民整合到 Dune 中。

(W16) 與其他建置系統整合

雖然 Dune 是 OCaml 專案的建議選擇,但開發人員可能因為各種原因選擇或需要使用不同的建置系統。像 Meta 或 Google 這樣的大型組織,為了保持一致性和規模,通常會強制使用特定的系統(分別為 Buck2 和 Bazel)。獨立開發人員也可能根據其獨特的需求(例如 Nix 的可重複性功能)而有偏好。

為了確保 OCaml 生態系統對所有這些使用者保持可訪問性和可用性,無論他們選擇的建置系統如何,Dune 提供了將建置計畫匯出為機器可讀格式的支援。這使第三方工具可以使用匯出的建置計畫並將其轉換為其他建置系統的規範。

我們注意到,先前關於是否存在足夠的解決方案來匯出 Dune 的建置計畫的討論尚無定論。需要與 obazel 等轉換工具的維護者以及其他建置系統的使用者進行進一步的討論和調查,以確定如何改進與這些平台的整合。

探索

(W17) 除錯

OCaml 的除錯可以從命令行和編輯器中完成。

要使用命令行進行除錯,只需運行

dune debug

這會編譯具有除錯支援的專案,並在終端中啟動除錯會話。

除錯程式的另一種方式是通過編輯器。除錯器和編輯器之間的通信是使用 除錯適配器協議 進行的。

(W18) 基準測試

與創建測試套件類似,OCaml 使用者可以為他們的專案創建基準測試。Dune 中對基準測試有一流的支援。使用者可以使用基準測試庫生成一個遵循特定格式的檔案,該檔案可以被工具(例如 current-bench)解讀。基準測試採用使用此庫的普通 OCaml 檔案的形式,並通過 bench 節點添加到 Dune 中,其行為與 test 節點類似。

(bench
 (name ...)
 (libraries ...))

在 Dune 中添加基準測試後,使用者可以運行 dune bench,它將運行所有基準測試以生成輸出檔案。在本地,它隨後會啟動一個基準測試儀表板,其中包含使用者生成的不同基準測試結果。

在推送到其儲存庫時,使用者可以選擇通過 GitHub 應用程式在其儲存庫上啟用基準測試。啟用後,應用程式會監聽儲存庫上的拉取請求 (PR) 並運行基準測試。

然後,基準測試將通過 GitHub 拉取請求提供。

編輯

(W19) 導覽程式碼

程式碼導覽重新組合了常見的互動式開發工作流程,包括:

  • 顯示型別簽名和符號文件
  • 跳到型別、值或模組的定義
  • 查找型別、值或模組的所有引用
  • 從宣告切換到定義
  • 使用語義資訊在檔案中導覽游標

程式碼導覽發生在三個地方:

  • 在本地,在編輯器中,使用者通常從一個檔案導覽到另一個檔案,可以取得值或模組的引用、跳到定義等。
  • 線上,當使用基於瀏覽器的編輯器時
  • 線上,當使用 VCS 時,例如,當審閱 GitHub 或 Gitlab PR 時,或當瀏覽託管程式碼時
  • 線上,當使用 OCaml Playground 時

OCaml LSP 伺服器中所有適當 LSP 請求的實作支援本機編輯器程式碼導覽。基於瀏覽器的編輯器由 OCaml VSCode 擴展的 Web 版本支援,該擴展依賴於 Merlin 的 JavaScript 版本。OCaml Playground 類似地使用 Merlin 的 JavaScript 版本來支援程式碼導覽功能。

(W20) 重構程式碼

兩個值得注意的程式碼重構任務包括:

  • 重新命名值或模組及其所有引用
  • 提取值或模組

OCaml 平台通過 Merlin 查詢以及 OCaml LSP 伺服器中相關 LSP 請求和程式碼動作的支援來支援這些功能。

維護

(W21) 執行測試

Dune 提供了 dune test 命令,該命令會執行專案中定義的測試。測試是使用 (test) 節點定義的。

Dune 具有使用者友好的直覺式使用者介面來執行測試。可以從命令行單獨執行測試,並且 Dune 提供了 shell 完成功能來探索 CLI 語法並發現給定內容或目錄中可用的測試。

測試執行器還與監看模式良好整合,以支援測試驅動開發 (TDD) 工作流程。

編輯器還與 Dune 整合,以提供 UI 來探索和執行測試。通常,VSCode 擴展提供類似於官方 Python 擴展 的測試資源管理器。

此外,Dune 可以生成測試覆蓋率報告:執行測試時,會對程式碼進行檢測以識別已訪問的程式碼路徑,並使用此來測量覆蓋率。

(W22) 形式驗證

Gospel 是 OCaml 程式的行為規範語言。它為開發人員提供了一種非侵入式且易於使用的語法,用於使用正式合約註釋其模組介面,這些合約描述了型別不變性、可變性、函數前置條件和後置條件、效果、例外情況等等!

它的設計目的是為將形式方法引入 OCaml 生態系統提供一個與工具無關的前端。

為了向使用者提供正式驗證其 OCaml 程式的方法,OCaml 平台提供了一個工具,該工具使用 Gospel 規範來驗證 OCaml 函數的實作。

當定義了函數的形式規範時,dune test 會向使用者報告任何形式驗證失敗,並且通過擴展,這些失敗會通過 LSP 伺服器作為錯誤報告給編輯器。

(W23) 安全諮詢

OCaml 在業界用於為關鍵基礎架構提供支援。在這些情況下,安全性極為重要。

OCaml 平台提供了針對發佈在 opam-repository 上的 OCaml 套件提交的安全諮詢資料庫(類似於 Rust 的諮詢資料庫)。

該資料庫由一組安全專家維護,當發現或解決新的安全問題時,社群可以做出貢獻。

與程式碼檢查工作流程類似,Dune 在建置專案時會使用諮詢資料庫來警告使用者專案中的安全問題。

dune audit 命令還可以在將專案的鎖定檔案與諮詢資料庫匹配後生成安全審核報告。

安全警告和錯誤通過 OCaml LSP 和 Dune RPC 的整合報告給編輯器。

最後,OCaml 平台提供 CI 管道,用於監看安全諮詢資料庫,並在從專案的鎖定檔案中檢測到新的安全問題時,向專案儲存庫開啟 PR 或問題。

分享

(W24) 文學程式設計

文學程式設計是一種程式設計實務,其中程式碼和註解的重要性被顛倒。預設情況下,任何文字在編譯中都會被忽略,而程式碼必須放置在特殊的分隔符號內。文學程式設計非常適合教學用途,因為它側重於解釋,但它也可以用作鼓勵記錄大型程式碼庫的方法。

在 OCaml 中,odoc 工具提供了文學程式設計支援。Odoc 通常用於生成文件,但它也可以執行文件中的程式碼區塊。

此行為是選擇加入的,並且可以使用 Dune 節點進行配置,例如

(documentation
  (execute_code_blocks true))

可以在上面的節點中提供其他選項,例如選擇要在其上運行 odoc 的檔案或要包含的程式庫。

每個 odoc 支援的文件都支援程式碼區塊執行,包括 .md.mli.mld 檔案。

.mli.mld 檔案中嵌入式程式碼區塊的語法支援指定執行嵌入式程式碼所產生的輸出。這允許我們將輸出解讀為更豐富的格式,例如表格、影像、圖形等,然後可以由編輯器顯示這些格式,或由 odoc 適當地嵌入到 HTML 中。

Dune 允許我們執行(文學)程式,並檢查執行程式的輸出是否與檔案中的預期輸出相同。

dune test

如果實際輸出與預期輸出之間存在不匹配,Dune 會引發錯誤並提供推廣差異的選項。

Odoc 還支援使用由 JavaScript toplevel 提供支援的互動式程式碼區塊生成 HTML 文件。

(W25) 生成文件

藉由執行指令,例如:

dune doc

Dune 會驅動 odoc 以 HTML 格式產生文件,並在文件起始處開啟瀏覽器標籤 (P3)。產生的文件會包含專案相依性的文件。

odoc 使用的標記語言具有足夠的表達能力,可以撰寫豐富的文件和手冊。特別是,Odoc 支援以下功能:

  • 原始碼渲染,讓使用者在閱讀文件時能夠檢查函式的程式碼。
  • 全域導覽,方便瀏覽整個 API 以及獨立的文件頁面。
  • 搜尋列,方便在文件中搜尋。
  • 針對最常見的標記功能(例如表格、圖片等)提供特殊的語法。
  • 支援 Markdown 用於獨立的文件頁面。
  • 程式碼區塊可以產生豐富的輸出(例如圖片、圖表等)和任意的標記。

文件產生和瀏覽功能與程式碼編輯器整合良好。使用者可以從編輯器快速跳轉到所選模組的渲染文件。編輯器能協助撰寫文件,提供語法高亮、參照檢查以及程式碼片段的常用檢查。

(W26) 套件發布

OCaml 套件發布在 opam-repository 上。若要發布套件,使用者可以建立一個 opam 檔案,其中包含套件的相關資訊,例如其相依性和 depexts,以及允許 Dune 或其他建置系統建置套件的建置指示。

opam 檔案也定義了可以從何處下載套件的原始碼。常見的做法是使用 GitHub、GitLab 或其他 VSC 平台來託管包含套件原始碼的壓縮檔。

Dune 提供 dune release 命令,用於在 opam-repository 上發布套件。它自動化了建立 opam 檔案、原始碼壓縮檔、將壓縮檔上傳到 VCS,以及在 opam-repository 上開啟 PR 的過程。

Dune 知道如何從 Dune 專案合成 opam 檔案,並且可以產生包含在 opam-repository 上發布套件所需的原始碼和中繼資料的壓縮檔。產生的壓縮檔僅包含 opam 所需的檔案。

此工作流程與開發最佳實務整合,並讀取專案的變更日誌,以建立發布封存檔和 opam-repository PR。

(W27) 產生安裝程式

將應用程式發布給終端使用者的一個常見方式是產生安裝程式,其中將包含應用程式、其所有相依性,以及用於安裝兩者的指令碼。

安裝檔案會因使用者的系統而異。基於 Debian 的 Linux 發行版有 .deb 檔案,Windows 有 .msisetup.exe 檔案,而 macOS 則有 .app 檔案。

OCaml 平台提供了一個工具,可以從 OCaml 專案產生安裝程式,而 Dune 提供了一個使用者友善的介面來產生它們。

例如,執行

dune build @installer-msi

會產生一個 .msi 安裝程式,可以將其發布給 Windows 使用者以安裝專案的可執行檔。

仍然需要協助嗎?

協助改進我們的文件

所有 OCaml 文件都是開源的。看到任何錯誤或不清楚的地方嗎?提交 Pull Request。

OCaml

創新。社群。安全。