後端工坊 2026 年 6 月 4 日

2026-06-04 — Elixir v1.20 漸進式型別、Kotlin 2.4.0、iddqd unsafe Rust

primary=https://elixir-lang.org/blog/2026/06/03/elixir-v1-20-0-released/ primary=https://blog.jetbrains.com/kotlin/2026/06/kotlin-2-4-0-released/ primary=https://oxide.computer/blog/iddqd-unsafe

Elixir v1.20:以 dynamic() 型別為核心的漸進式型別系統正式啟用

Elixir 官方部落格 · 2026-06-03

Elixir v1.20 於 2026 年 6 月 3 日發布,帶來了 漸進式型別系統(gradual type system) 的全面啟用。這是 Elixir 專案自 2020 年確立「Sound Gradual Typing」路線以來最大的語言層面變化,核心機制是推論型別、而非要求標注型別,且以 dynamic() 型別作為「尚未確定」的佔位符。

設計哲學:Sound vs. Gradual 的取捨

Elixir 的漸進型別系統刻意與 TypeScript 的 unsound any 有所不同。TypeScript 的 any 會靜默地吃掉型別資訊;Elixir 的 dynamic() 則在型別不確定時保留此狀態,只在「供給型別」與「接受型別」完全不相交時才回報錯誤。這種設計最小化了現有程式碼的假陽性警告,同時在能夠推論出型別時提供完整的靜態保證。

型別系統以集合運算為基礎:聯集(union)、交集(intersection)、補集(negation) 作為基本操作。舉例而言,is_list(x) and is_integer(y) 的 guard 讓型別系統推論出 x 為 list()、y 為 integer();case 子句處理完某個分支後,後續子句的型別會排除已處理的情況,以交集縮窄推論範圍。

核心機制:型別窄化(Type Narrowing)

Guard 窄化:編譯器追蹤整個 guard 子句的交集與聯集語意,包含 not 和 and/or 的嵌套組合。複合 guard 如 is_map(x) or is_list(x) 的型別被推論為 map() | list(),後續的 map 存取操作若在 is_list 分支中出現,會觸發靜態警告。

Pattern matching 窄化:解構一個 tuple {:ok, val} 後,編譯器將 val 的型別窄化至宣告的元組元素型別。對 struct 的 map 解構(%MyModule{field: x})會讓 x 繼承 MyModule 中 field 的定義型別。

動態存取窄化data.a 在執行後會讓 data 的型別被窄化為「至少含有 a 欄位的 map」,若後續操作與此不一致,在下一個存取點產生警告,而非在不確定的使用處沉默。

編譯效能改善

v1.20 在多核系統上的編譯速度有顯著提升,主要來自改良後的模組依賴分析,減少了不必要的增量重新編譯觸發。新增的 :module_definition 編譯器選項允許以詮釋模式執行模組定義,可在大型 umbrella 專案中加速冷啟動構建。

原始來源:Elixir v1.20.0 Released


Kotlin 2.4.0:Context Parameters 穩定、UUID API、Wasm 增量編譯預設啟用

JetBrains Kotlin Blog · 2026-06-03

Kotlin 2.4.0 於 2026 年 6 月 3 日發布,帶來數項等待已久的穩定化功能。Context Parameters 脫離實驗性狀態正式穩定,UUID API 進入標準函式庫,Wasm 平台獲得預設啟用的增量編譯,Java 26 相容性也已到位。

Context Parameters 正式穩定

Context Parameters(先前稱為 context receivers)允許函式聲明它需要某個型別的上下文物件,而呼叫端在對應的上下文範圍內可以透明地傳遞這個物件。語法為:

context(Logger, Database)
fun processUser(userId: String): User {
    log("Processing $userId")  // Logger 隱式可用
    return query("SELECT * FROM users WHERE id = ?", userId)  // Database 隱式可用
}

這個功能解決了 Kotlin 在 DSL 建構、依賴注入以及領域模型設計中長期依靠 extension function 傳遞上下文的繞道問題。與 extension function 的核心差異:context parameter 不改變 receiver 語意,允許同時宣告多個上下文型別,且型別相同的兩個上下文可以被明確區分。

UUID API 進入標準函式庫

Kotlin multiplatform 開發者長期需要引入第三方函式庫處理 UUID,2.4.0 將 UUID 支援納入 kotlin.uuid 套件。新 API 提供 Uuid 不可變值型別、Uuid.random() 生成器、版本 4 UUID 解析與格式化,以及與各平台原生 UUID 型別的雙向轉換(Java java.util.UUID、iOS/macOS Foundation.UUID)。排序遵循 RFC 9562 的位元排序語意。

平台層面更新

Kotlin/Wasm:增量編譯現在預設啟用,在修改局部程式碼時大幅減少重新編譯量。WebAssembly Component Model 支援進入穩定,允許 Kotlin Wasm 模組與其他語言的 Wasm 模組透過 WIT(Wasm Interface Types)互操作。

Kotlin/Native:Swift Package 現可作為 Kotlin/Native 框架的依賴。CMS(Concurrent Mark and Sweep)GC 成為預設垃圾回收器,取代先前的 stop-the-world GC,減少 iOS/macOS 應用的 UI 卡頓。

Kotlin/JS:支援以 value class 匯出 ES 模組,呼叫端得到符合 JS 習慣的不可變值物件。ES2015 特性(arrow functions、destructuring)現已在 JS 內聯函式中生效,減少產生的程式碼體積。

原始來源:Kotlin 2.4.0 Released


iddqd:從鍵借自值的 Rust Map 如何應對最難處理的 unsafe 情境

Oxide Computer Blog · 2026-06-03

Oxide Computer 發布了一篇深度技術文,介紹 iddqd——一個允許 Map 鍵由值本身借出(key borrowed from value)的 Rust 函式庫。這個設計消除了「鍵與值分開儲存導致的資料重複」問題,但在 Rust 的借用檢查器下引出了極難處理的 unsafe 情境。

問題根源

標準的 HashMap<K, V> 要求鍵與值分開存放,這對於「鍵本身就是值的某個欄位」的場景(例如以 UserId 為鍵、User struct 為值)造成資料重複。iddqd 的核心 trait 要求實作者提供 fn key(&self) -> &K,讓 Map 內部可以直接從值借出鍵。這在 C++ 或 Go 中是簡單的指標操作,但 Rust 的借用規則需要更精細的生命週期管理。

unsafe 的核心挑戰

最艱難的部分是可變迭代器的生命週期延伸。當以 &mut self 迭代所有元素時,借用檢查器只看到連續的索引存取——它無法靜態驗證「每個索引都不同」,即使開發者能保證不重疊。iddqd 使用 unsafe { transmute(...) } 延伸生命週期,在知道索引互不重疊的前提下允許同時持有多個 &mut 引用。

更危險的邊界是泛型程式碼中的 user-supplied 代碼。若使用者提供的 Ord 實作被刻意設計為「永遠回傳 Equal」,Map 的排序邏輯會產生重複索引,兩個索引指向同一塊記憶體,違反 Rust 的 aliasing 規則並觸發未定義行為(UB)。

驗證策略的多層防衛

Oxide 對 iddqd 採用了六層並行驗證,而非依靠單一方法:

  • 每個 unsafe 區塊附帶文字化的安全論證(safety argument)
  • 例子測試與病態測試(adversarial Ord 實作)
  • Model-based testing:對照一個正確但低效的 NaiveMap oracle
  • Panic safety fault injection:探索中途 panic 留下的破損狀態
  • Miri interpreter:偵測 UB 與記憶體別名違規
  • LLM 對抗性評審:找出人工審閱可能遺漏的攻擊向量

文章強調:這種「呼叫 user-supplied trait 方法的泛型 unsafe 程式碼」是 Rust 生態中最難寫正確的類別,任何一個防衛層都不足夠,需要全部六層同時到位。

原始來源:iddqd: the hardest kind of unsafe Rust — Oxide Computer


End of article
0
Would love your thoughts, please comment.x
()
x