EngTW / English-for-Programmers

《程式英文》:用英文提昇程式可讀性
973 stars 45 forks source link

補充「檢查」 情境+命名 範例 #44

Open twy30 opened 4 years ago

twy30 commented 4 years ago

https://www.facebook.com/twy30/posts/2615081322075516?comment_id=2615083622075286

如果每個命名可以附上一個情境+命名的範例,就更清楚能看出微妙的差異點

https://www.facebook.com/twy30/posts/2615081322075516?comment_id=2615083622075286&reply_comment_id=2615104028739912

我可以提供幾個例子當疑問,然後你可以給建議或是看法,選擇哪一個比較合適,或許可以這樣試試。 例如:我要檢查某個 Product 的 instance 毛利率有沒有 > 6%. 例如我要驗證 user 的 IP 是不是合法的。 例如我要確認這是不是加購的商品。 例如我要確保訂單金額不可以< 0。

中文的用詞是我刻意隨便用,而且故意用不一樣的。

hatelove commented 4 years ago

Ensure 的部份,C# 有個常用的:HttpResponseMessage.EnsureSuccessStatusCode()API說明) 如果 HttpStatusCode 不是 200 OK, 就會 throw exception, 這個 Ensure 的方法跟這邊的說法是否一致呢?還是更偏向 assert 一點?

我自己的認知是,assert 驗證狀態或結果的成份更重點,而且會是目的。ensure 則是在這邊做一個驗證前提假設,如果沒問題,流程就可以繼續往下執行。

所以通常 assert 放在文末,ensure 則是往下做某件事的前置檢查。

但這只是我的習慣,對英文的敏感度不夠高,不知道有沒曲解。

adks3489 commented 4 years ago

Ensure 的部份,C# 有個常用的:HttpResponseMessage.EnsureSuccessStatusCode()API說明) 如果 HttpStatusCode 不是 200 OK, 就會 throw exception, 這個 Ensure 的方法跟這邊的說法是否一致呢?還是更偏向 assert 一點?

我認為這個比較偏向執行後的驗證。

我舉一個例子,C++20 加入了Design by Contract概念的語法, 他用了expects 來代表前置條件、ensures 代表輸出前的確保、而assert讓他回歸function body內的檢查。

hatelove commented 4 years ago

Ensure 的部份,C# 有個常用的:HttpResponseMessage.EnsureSuccessStatusCode()API說明) 如果 HttpStatusCode 不是 200 OK, 就會 throw exception, 這個 Ensure 的方法跟這邊的說法是否一致呢?還是更偏向 assert 一點?

我認為這個比較偏向執行後的驗證。

我舉一個例子,C++20 加入了Design by Contract概念的語法, 他用了expects 來代表前置條件、ensures 代表輸出前的確保、而assert讓他回歸function body內的檢查。

有道理,感謝分享。

twy30 commented 4 years ago

Ensure 的部份,C# 有個常用的:HttpResponseMessage.EnsureSuccessStatusCode()API說明) 如果 HttpStatusCode 不是 200 OK, 就會 throw exception, 這個 Ensure 的方法跟這邊的說法是否一致呢?還是更偏向 assert 一點?

短答案:我覺得它偏向 assert 。


assert 在字典上的解釋是「大力宣稱、主張」:

大力、自信地主張一事實或想法

以力量、自信來使它人認可「說話者的權威性、權利」

以有力、充滿自信的方式說話、行動


到了軟體開發領域, assert (動詞) / assertion (名詞) 就是我們這裡在談的這個東西:

(a)「宣告某個布林(Boolean)值條件C為真;如果在執行時間偵測到該條件C為假,就丟出錯誤/例外」 (b) 另外,軟工領域的 "assertion" 的行為還可能受除錯(debug)版、釋出(release)版影響。

ref: https://en.wikipedia.org/wiki/Assertion_(software_development)

我想,可以說:雖然 assert 這個字的字典解釋只有提到「大力宣稱/主張」,沒提到任何後續動作,但在軟工領域的人,大多會認同 assert / assertion 就是會像上述 (a), (b) 那個樣子。


回頭來看 "ensure" ,它的字典解釋是「保證、確保」:

確保某事將會發生、成真

確保某物將會到某人的手上

確保某問題不會發生


在這個「提議把 ensure 加入 PowerShell 官方認可的動詞表」討論串裡, ensure 有被以下這樣子解釋:

ref: https://github.com/PowerShell/PowerShell/issues/11710#issuecomment-579544453

To ensure means to take action if needed so that a desired state is reached.

If the desired state is already in effect, no action or notification is needed. If the desired state cannot be reached, an error must be reported.

而 assert 是這樣被解釋:

To assert means to assume that a given state is already in effect, to make a claim about what should already be true, without implying action toward making it so.

If the assertion fails (turns out not be true), you want to know about, which in the world of software typically means failing instantly and noisily.

(該討論串後半是另一哲理辯論,也很有意思,可以另開主題來聊。)


上述案例偏向把 ensure 當「祈使句 / 命令動詞」來用,去真正執行「確保某事將會發生、成真」這個動作。

而在 https://github.com/EngTW/English-for-Programmers/issues/44#issuecomment-673987707 提到的這種用法:

C++20 加入了Design by Contract概念的語法, 他用了expects 來代表前置條件、ensures 代表輸出前的確保、而assert讓他回歸function body內的檢查

比較偏向「 宣稱 此函式將會去確保某事將會發生、成真」;易言之,我主觀覺得,那其實比較接近 assertion 的性質 🤔


進入主題: HttpResponseMessage.EnsureSuccessStatusCode() 😅

很不幸的, https://referencesource.microsoft.com/ 似乎沒有那部分的程式碼,而 .NET Core 版本的程式碼也沒有提供額外的註解,很難去知道當初設計此方法的考量。

我們能知道的是,當我們拿到 HttpResponseMessage 時,如果其 HTTP 狀態碼(status code)不是 2XX ,其實我們也不能怎麼樣 😅

除了重試(retry)之外,應該沒有方法能 有意義地 去「確保我們拿到的是成功的狀態碼」。

在 .NET Core 早期的版本 (例如 1.0.0) 裡, EnsureSuccessStatusCode() 除了「像是 assert 的行為」外,還會順便 dispose 其 message content ( 參考 https://github.com/dotnet/corefx/blob/release/1.0.0/src/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs#L148-L165 )

在最近的版本 ( 3.1 ) 裡,就只有留下「像是 assert 的行為」 ( 參考 https://github.com/dotnet/corefx/blob/release/3.1/src/System.Net.Http/src/System/Net/Http/HttpResponseMessage.cs#L168-L180 )


與其它的 "ensure" 方法相比,例如 StringBuilder.EnsureCapacity(Int32)

Ensures that the capacity of this instance of StringBuilder is at least the specified value.

確保此 StringBuilder 的容量 (至少要有指定值那麼多)

這樣子的 "ensure" 方法就比較符合「確保」的語意 🤔


結論:在已經有 IsSuccessStatusCode 的前提下,我猜不太到當初設計 EnsureSuccessStatusCode() 時考量的 use case 是什麼 (尤其是,它在舊版本裡會去 dispose message content ), 以及為什麼會選 ensure 作為方法動詞 🤔

twy30 commented 4 years ago

上述案例偏向把 ensure 當「祈使句 / 命令動詞」來用,去真正執行「確保某事將會發生、成真」這個動作。

而在 #44 (comment) 提到的這種用法:

C++20 加入了Design by Contract概念的語法, 他用了expects 來代表前置條件、ensures 代表輸出前的確保、而assert讓他回歸function body內的檢查

比較偏向「 宣稱 此函式將會去確保某事將會發生、成真」;易言之,我主觀覺得,那其實比較接近 assertion 的性質 🤔

找到了比較正式的解釋:英文的 "simple present" (簡單現在式) https://en.wikipedia.org/wiki/Simple_present#Uses ;用來表達「習慣、事實、 一般情況 」。

To refer to an action or event that takes place habitually. In the other hand to remark habits, facts and general realities, repeated actions or unchanging situations, emotions, and wishes.[3] Such uses are often accompanied by frequency adverbs and adverbial phrases such as always, sometimes, often, usually, from time to time, rarely, and never. Examples:

  • I always take a shower.
  • I never go to the cinema.
  • I walk to the pool.
  • He writes for a living.
  • She understands English.

This contrasts with the present progressive (present continuous), which is used to refer to something taking place at the present moment: I am walking now; He is writing a letter at the moment.