撰寫分析器註解


本文件提供如何撰寫分析器所產生之註解的相關資訊與準則。

內容

分析器註解的內容以 Markdown 文件的形式,存放在 exercism/website-copy 儲存庫中。 註解會包含一個指標字串,格式為<track-slug>.<exercise-slug>.<comment-slug>,指向 website-copy 儲存庫中特定的 Markdown 文件。

例如,ruby.two-fer.string-interpolation 指向 https://github.com/exercism/website-copy/blob/main/analyzer-comments/ruby/two-fer/string_interpolation.md。

Note

如果某則註解是特定於某種語言,而_不_是特定於某個練習,請把<exercise-slug>替換成general。 例如ruby.general.string-explicit_return

措辭

  • 避免不必要的冗長註解。力求簡潔。
  • 保持中立客觀,避免帶有情緒的陳述和以偏概全的說法。
  • 明確表達建議。
  • 情況允許時,先提出建議,再說明原因。
  • 避免使用「me」、「I」、「we」等字眼,因為這個機器人並不是人。
  • 避免使用「you」和「your code」,因為這有時會讓人覺得是在評斷人,而不是在評斷程式碼。
  • 避免使用「just」、「simply」、「obviously」這類字眼,它們可能顯得高高在上:如果這則註解有其必要,那它_顯然_就_不_顯而易見。
  • 避免假設別人知道或不知道什麼。唯一的例外,是來自已經完成之_核心_練習的知識。避免使用「as you know」、「as you remember」、「as you learned」、「now that we all understand x」等說法,因為即使某件事已經被提過,對方也未必真的理解。

指引

  • 追求流暢,而非精通:Exercism 上語言軌道的目標,是讓人們能以較低的精通程度,達到高水準的流暢度。 我們追求的是對該語言語法、慣用語和標準函式庫的流暢運用。
  • 情況允許時,建議慣用的寫法。所謂慣用,是指幾乎所有以該語言撰寫程式碼的開發者(非業餘玩家)都會寫出來的程式碼。 如果提出的建議並不慣用,請說明這一點,並解釋為什麼這個建議仍然可能有用。
  • 指出差異:說明對方目前的寫法,與該語言的「慣用」寫法之間有什麼不同。
  • 使用正確的術語與命名,讓人們能在其他地方認出這些概念,也能自行查詢研究。
  • 不要直接給出解答,這是所有 Exercism 引導共通的一般原則。 當人們自己發現答案時,學習才會深植腦海。那是一種極度振奮的體驗,而這種情緒上的衝擊會讓它令人難忘。 不過,如果這個發現無法帶來多巴胺的快感,那麼直接展示答案就完全合理。 舉例來說,對一個已經通過的解答提出小幅改進,其振奮程度會遠低於對一個正在被退回的解答指出學習重點:後者因此可能需要附上範例,而不只是給個連結。
  • 依重要性排序註解,第一則最重要,最後一則最不重要。
  • 控制註解的數量。 每次疊代以 1 到 3 則註解為目標。
  • 不要在同一份分析中加入重複的註解。 同一則註解附上不同參數,_不_算重複。
  • 如果格式化或 lint 檢查是該語言不可或缺的一部分,才考慮只針對格式提出註解。 情況允許時,引導學生使用自動格式化工具,並/或連結到任何官方風格指南。

最初的幾個練習

在軌道最初的幾個練習中,以下幾點_格外_重要:

  • 保持相對簡短,避免長篇大論,或用大量建議淹沒對方。如果他們在第一次練習就有很棒的體驗,就會再回來,你也會有更多機會針對所有你注意到的事情提供意見。
  • 不要過度解釋概念:不要深入探討編譯器之類的底層機制。這裡的重點在於這是語言軌道中最初的幾個練習之一,而在這個階段,簡短且更具指引性的意見更有幫助。
  • 提供一個連結,以教學的方式具體示範這個概念該怎麼做。也就是說:展示怎麼做,而不是討論為什麼。這可能意味著該語言的官方文件並不足夠,因為它們通常是程式碼參考,不會示範如何使用,也不會說明它如何運作。不過,你應該只在需要更深入探索時才提供連結。對方應該能直接從回覆本身理解你的意思,而不必點開連結。

範例

在 JavaScript 中,有位學生用let寫了一個頂層常數。

<!-- not following these guidelines -->

As you know, everyone uses const, you shouldn't use let or var.

這則註解沒有遵循這些準則,原因如下:

  • 建議的行動出現在「解釋」之後。
  • 「As you know」:我們不知道學生是否真的知道。
  • 「you shouldn't」:要表達這句話,並不需要用到「you」。
  • 「everyone uses const」:這並不正確,_而且_會讓學生覺得自己好像犯了天大的錯。
  • 缺少對這個建議_為何_提出的實際說明。
<!-- better -->

Prefer `const` and `let` over `var`. The `const` declaration stops a variable
from being accidentally reassigned, which provides safety, and reduces
cognitive load for someone reading the code. [This article](https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75)
explains the difference between the three.

在 Go 中,有位學生建立了自訂錯誤,而沒有使用內建的錯誤:

<!-- not following these guidelines -->

I see you are creating a custom `error`. This is perfectly fine! If you did not
know about `errors.New` and `fmt.Errorf` have a look at them as they are much
simpler ways to create an error. Custom errors are helpful if you want to check
if an error is of a certain type later.

這則註解沒有遵循這些準則,原因如下:

  • 「I see」:分析器不是人,避免使用 I。
  • 「This is perfectly fine!」:顯然並非如此,否則就不需要這句安撫的話了。這句很可能可以整個省略;如果你想針對某個既有的做法給出通用的提示,可以直接這樣說:「An alternative, equally valid way of doing x is y.」
  • 「If you did not know about」:把這個過於冗長的詞組刪掉。
<!-- better -->

A custom `error` is typically used to provide custom behavior, or to distinguish
on type later. For simpler cases, it's more common to rely on `errors.New` or
`fmt.Errorf`. This [in-depth article](https://golangbot.com/custom-errors/) about
custom errors might be interesting.

CI

由於註解與分析器並不在同一個儲存庫中,每個分析器都應該有 CI,用來檢查該分析器所使用的註解(也就是那些可能成為輸出的註解),是否都是 exercism/website-copy 儲存庫 main 分支上的註解。

撰寫本文時,這個 issue 記錄了這套 CI 通用化(如果真有)的進展狀態。