口語化修辭在判斷工具型段落會稀釋技術精度
論述基礎與限制
本卡的論述基於 1 個 case(dart Stream 事故的 review)抽出來的觀察。具體限制:
- Keyword bank 是 starting set、不是 exhaustive list:列出的口語詞(一輩子 / 碰巧 / 撞牆 / 啊原來)都是這次 dart 篇出現過的、不代表「口語修辭的完整詞庫」。新類型出現時要持續擴充
- 「精度 vs 可讀性」是情境化取捨、不是 zero-sum:本卡聚焦「判斷工具型段落」(讀者要從中拿到 portable 工具的論述)、在這類段落精度優先;但 hook / 引言 / narrative 段落口語反而幫讀者進入論述、不適用本卡
- Self-case 的修補有效性未獨立驗證:dart 篇修補後讀起來更精準、但「精準度跟讀者實際理解之間的相關性」沒做使用者測試
讀者使用本卡時、先判斷段落是否屬於「判斷工具型」——是 → 套用;否 → 評估口語跟可讀性的取捨。
核心原則
技術文章的「判斷工具型段落」(讀者用來判斷自己 case 的論述)裡、用詞選擇要能對應到具體技術屬性。口語修辭(「一輩子」「碰巧」「立刻撞牆」「沒事」)讀起來流暢、但在這類段落會稀釋精度——精度標準是「用詞能不能反推到具體機制 / 條件 / 契約」、口語修辭多半不能、寫了等於把判斷工具退化成感性印象。
下面三個層次的稀釋是觀察到的 pattern——不是窮舉、實際違規模式可能更多:
| 口語修辭 | 稀釋的層次 | 讀者拿到的訊息 | 真實技術屬性 |
|---|---|---|---|
| 「一輩子只能 X」 | 時間性誇張 | 永遠這樣(無範圍感) | 生命週期內最多承載 1 次 |
| 「碰巧能用」 | 因果模糊 | 運氣使然 | 觸發條件不滿足、限制處於沉默狀態 |
| 「立刻撞牆」 | 結局描述代替契約描述 | 視覺意象、不知為什麼 | 違反型別契約、執行期 throw |
| 「沒事」 | 缺失條件描述 | 沒問題 | 限制存在、但沒有可見影響 |
| 「整個炸了」 | 嚴重度誇張 | 知道很糟、不知糟在哪 | 違反契約導致 X 行為 |
| 「啊原來 X」 | 結局視角的驚訝句 | 事後恍然大悟感 | 在 Y 條件下 X 才暴露 |
三個稀釋層次的具體 case
層次 1:時間性誇張
口語版:「stream 一輩子只能被 listen 一次」
問題:
- 「一輩子」沒有對應的技術概念——是「整個 process lifetime」?「stream object lifetime」?「listener cancel 之後也算嗎」?
- 讀者要靠猜測決定範圍
精度版:「stream 在整個生命週期內只允許被 listen 一次(StreamController object lifetime;cancel() 之後再 listen() 仍違反契約、要重建 StreamController)」
差別:精度版讓讀者能反推「我這個 case 屬於哪個範圍、會不會踩到」、口語版讀者只能感受「應該很嚴格」。
層次 2:因果模糊
口語版:「碰巧能用掩蓋了設計缺陷」
問題:
- 「碰巧」暗示運氣使然、機制不可解釋
- 但實際上「能用」有明確的機制:訂閱者數量沒達到觸發違反契約的條件
- 用「碰巧」會讓讀者學到「這是運氣問題」、不學到「這是條件未滿足的可預測現象」
精度版:「訂閱者單一時、限制處於沉默狀態」
差別:精度版描述「為什麼沒影響」的具體條件、口語版只描述「結果」。讀者能用精度版去判斷自己的 case 何時會觸發、不能用口語版做同樣的判斷。
層次 3:結局描述代替契約描述
口語版:「新加第二個訂閱者就立刻撞牆」
問題:
- 「撞牆」是視覺意象、不是技術描述
- 讀者拿到的是「發生了不好的事」、不是「為什麼發生」「在哪一層發生」
- 套到不同 case(如「使用 cancelled stream」「使用 closed controller」)會推不出對應的修法
精度版:「新加第二個訂閱者直接違反契約、執行期 throw」
差別:精度版指明「違反的是什麼(契約)」「在哪個時間點(執行期)」「具體後果(throw)」、讀者能 generalize 到其他違反契約的情境。
為什麼口語修辭會出現
技術寫作中口語修辭的出現有三類典型來源:
來源 1:寫的當下感性敘事比技術敘事好寫
「一輩子只能 listen 一次」比「整個 lifecycle 只允許被 listen 一次」少 5 個字、寫起來順、語氣強烈。但精度也差距 5 倍。寫作便利度高的版本通常離精度遠(#67 寫作便利度跟意圖對齊反相關 的同骨——寫得順 ≠ 寫得對)。
來源 2:對讀者「直覺感受」的妥協
「碰巧能用」這類詞讓讀者「立刻有共鳴」、感覺像在讀故事。但技術文章的讀者來這裡找的是判斷工具、不是故事——共鳴感換來精度損失、是錯誤的取捨。
來源 3:誤把「事故當下的反應」當成「論述用詞」
事故當下工程師的內心 OS 確實是「啊原來這個 mutation 路徑沒帶」「進入頁面就炸」——這些是當下的口語反應。寫成正式論述時要把這些反應翻譯回技術描述、保留意圖(驚訝 / 嚴重程度)但不保留口語形式。
識別訊號:什麼時候你在用口語修辭
訊號 1:時間 / 範圍誇張詞
「一輩子」「永遠」「整個炸了」「全部 GG」「直接死」——這類詞沒有對應的技術範圍、用了讀者要靠猜測。
修法:問「具體是哪個範圍 / 哪個生命週期 / 哪個 scope?」、把答案寫進去取代誇張詞。
訊號 2:運氣 / 巧合語氣
「碰巧」「剛好」「湊巧」「運氣好」——這類詞遮蔽了背後的機制。技術系統的行為幾乎都有可解釋的條件、不是運氣。
修法:問「為什麼當下沒發生?是哪個條件沒滿足?」、把條件寫出來取代運氣語氣。
訊號 3:視覺意象 / 動作比喻
「撞牆」「炸了」「鎖死」「卡住」「當機」(口語的,不是技術術語的 hang/freeze)——這些是事件的視覺描述、不是契約 / 機制描述。
修法:問「在哪一層、違反了什麼、執行期表現是什麼?」、把答案寫出來取代視覺比喻。
訊號 4:結局視角的驚訝句
「啊原來」「結果發現」「最後才知道」——這些把讀者帶到「事故已發生、回頭看」的視角、依賴 hindsight。
修法:問「在事前、什麼條件成立時這個 X 才會出現?」、改成事前可判斷的描述。詳細處理見 #110 設計檢討用當下三軸論證、不依賴 hindsight。
訊號 5:「沒事」「沒問題」當成段落結論
「運作正常」「沒事」「沒問題」「一切看起來都好」——這類詞代替了「在哪些條件下沒可見影響」的具體描述、暗示「不需要進一步審視」。
修法:問「沒影響是因為什麼條件沒觸發?換條件會怎樣?」、把條件寫出來取代「沒事」。
訊號 6:「下次 X 時、做 Y」結尾段
「下次看到 X 時、先問 Y」「下次寫 Z 時、想 W」「下次面對 V 時、停下來」——這類段落想給讀者實踐建議、但有兩個結構問題:
- 前綴是 wrapper、不增加資訊:讀者來讀這段的脈絡通常已經是「正在處理 X」、「下次看到 X 時」對讀者是廢話、把重點推到後面(違反規則五「最重要的話優先說」)
- 預設讀者會主動回憶:「下次 X 時做 Y」假設讀者下次會自動想起這條建議、實際上讀者多半不會主動 recall——應該寫成「判斷工具」而不是「回憶指令」
修法:把 wrapper 拿掉、把建議改寫成判斷工具的形式:
| 修補前 | 修補後 |
|---|---|
下次看到 Bad state 時、不要先想「我寫錯了」 | 根因落在 stream 定義端的型別契約、不在訂閱端 |
| 下次寫 test 時、想「這份 file 是唯一 doc 嗎」 | 把「這份 file 是模組唯一 doc」當命名的質量門檻 |
| 下次看到自己寫三行 doc、停下來想能不能變型別 | 寫到「三行 doc 解釋輸入範圍」這個訊號時、自問能不能變型別簽章 |
差別:修補前是「下次 X 時、做 Y」的 hortative 命令;修補後是「遇到 X 訊號時、用 Y 工具判斷」的 reactive 工具。前者依賴讀者主動 recall、後者由訊號觸發判斷。
注意 ≠「描述讀者的具體情境」:
「讀者讀完事後諸葛論述、能複述 case、但問他下次遇到不同議題怎麼判斷答不出來」
這個「下次遇到 X」是描述讀者的測驗情境(檢驗論述是否 portable)、不是給讀者的指令——保留合理。
何時口語修辭仍然合理
「精度優先」這條原則在大多數技術論述情境成立、但有合理例外:
| 情境 | 為什麼口語仍合理 |
|---|---|
| 對話 / 訊息 / Slack 討論 | 即時溝通、共識在場、口語反而更快建立 mutual understanding |
| 個人筆記 / scratchpad | 寫給自己看、知道自己當下在想什麼、不需要對他人精度 |
| 故事性引言 / hook 段 | 文章開頭吸引讀者、口語可暫時用、但很快要切回精度敘事 |
| 引用當事人的反應 / 直接 quote | 「事故當下工程師說『啊我哪裡寫錯了』」是引用、保留口語反映真實心境 |
| 反例段落(教讀者「不要這樣寫」) | 故意用口語版讓讀者看到差別、然後切到精度版 |
判讀:寫之前自問「讀者拿這段去做技術判斷時、口語修辭會不會讓判斷模糊?」——會 → 翻成精度版;不會 → 口語可接受。
跟其他抽象層原則的關係
| 原則 | 跟本卡的關係 |
|---|---|
| #67 寫作便利度跟意圖對齊反相關 | 口語修辭比精度敘事好寫——但精度才是讀者要的工具、便利 vs 對齊的同骨展現 |
| #110 設計檢討用當下三軸論證、不依賴 hindsight | 「啊原來」「碰巧」這類詞天生帶 hindsight 視角、本卡是 #110 在「字句層級」的延伸 |
| Compositional-writing 規則一:階段分層(觀察 → 判讀 → 策略 → 執行) | 口語修辭多半混淆四階段——「立刻撞牆」混了觀察跟判讀、要拆開重寫 |
| Compositional-writing 規則二:商業邏輯先於 CASE | 「碰巧能用」隱藏商業邏輯(為什麼能用)、本卡要求把商業邏輯顯式寫出來 |
判讀徵兆
| 訊號 | 該做的行動 |
|---|---|
| 段落讀起來「順」「有畫面」「像故事」 | 停下來掃口語修辭、問「這個詞對應什麼具體技術屬性?」 |
| 用了「一輩子」「永遠」「整個」這類絕對詞 | 換成具體生命週期 / scope |
| 用了「碰巧」「剛好」這類運氣語氣 | 找出背後的機制條件、寫出條件 |
| 用了「撞牆」「炸了」這類視覺意象 | 換成「違反 X 契約 / 在 Y 時刻 throw / 觸發 Z error」 |
| 用了「啊原來」「結果發現」 | 改成事前可判斷的條件描述 |
| 用了「沒事」當段落結論 | 補「在 X 條件下沒影響、換 Y 條件會怎樣」 |
核心原則:技術文章的用詞要能反推到具體機制 / 條件 / 契約。口語修辭的便利在於寫得順、代價是讀者拿不到判斷工具。寫完每段後跑一次「這個詞對應什麼具體技術屬性?」自問、答不出來的詞就要翻譯。
Self-case:本卡的觸發來源
本卡的觸發是修 Dart StreamController:single-subscription vs broadcast 的事故實錄 的第二輪審查。
讀者指出該文有四處口語化問題:「stream 一輩子只能被 listen 一次」「進入頁面就炸」「現在只要有人訂閱、把它記錄下來,UI 就能用」「碰巧能用掩蓋了設計缺陷」。修補時的觀察是這些不是孤立問題、是「口語修辭代替技術描述」這個共通 frame 在不同句子的展現。
修補後對比:
| 修補前 | 修補後 |
|---|---|
| stream 一輩子只能被 listen 一次 | 整個生命週期內只允許被 listen 一次(StreamController object lifetime) |
| 進入頁面就炸 | 第二個訂閱者觸發底層限制 |
| 立刻撞牆 | 直接違反契約、執行期 throw |
| 碰巧能用 | 限制處於沉默狀態(觸發條件不滿足) |
| 啊原來這個 mutation 路徑沒帶 | 暴露出某些 mutation 路徑沒填寫該欄位 |
每一組修補都把「口語視覺意象」翻譯回「技術屬性 + 條件 + 契約」。讀者拿到的是可反推的判斷工具、不是感性印象。
對應本卡:口語修辭的稀釋是字句層級的、容易在第一輪寫作後被忽略——multi-pass review 要在輪 4「Grep-ability / 命名 / 術語」加掃這個 frame、用 grep 找口語詞庫。