《程式碼之美》的故事

空軍發表於2014-07-15

 O'REILLY 哪本書封面動物是海鷗?

概況

《程式碼之美》是一本論文集,她彙集33篇技術文章,講述了38位作者認為最漂亮的程式碼。

試列舉部分作者:(對你來說,有幾位是耳熟能詳的?)

  • Brian Kernighan:《C程式設計語言》、《程式設計實踐》作者,前一本書也稱K&R
  • Charles Petzold:《Windows程式設計》、《編碼的奧祕》作者,Windows專家
  • John Bentley:《程式設計珠璣》作者,貝爾實驗室前研究員,普林斯頓大學訪問教授
  • Yukihiro Matsumoto(松本行弘):Ruby之父,是一位日本籍的開源倡導者
  • Simon Peyton Jones:Haskell主要設計者,GHC編譯器首席設計師
  • Douglas Crockford:JSON資料格式發明者,JavaScript領域大牛

《程式碼之美》中文版有七篇推薦序(孟巖、韓磊、熊節、霍泰穩、周愛民、潘加宇、徐繼哲),兩篇譯者序(劉未鵬、聶雪軍),加上目錄共佔據前xxxiv頁篇幅。(似乎很有一部分讀者詬病推薦序太多)

我於2008年10月24日在網上書店購得《程式碼之美》,有趣的是,版權頁印著“2009年1月第1版第1次印刷”(出版社此舉有何深意,不解ing)。購書當日在CSDN論壇推薦,見文末的參考資料1

有一幅當時某電商搞笑風格的宣傳海報(似乎改編自《程式碼大全》的海報),可點選參考資料2檢視。

正規表示式匹配器

Brian Kernigham、Rob Pike 合著的《程式設計實踐》第9章 記法,收錄了許多程式碼示例,很好地說明了優良的記法將產生更好的程式以及更好的設計。(順便說一句,《程式設計實踐》是一本極好的書,強烈推薦)

《程式碼之美》第1章 正規表示式匹配器講述了當時的情景:Brain 提議用一個最小的正規表示式包作為《程式設計實踐》9.2節的程式碼示例,它可以很好地詮釋正規表示式的基本思想,並且能夠識別出一組有用且重要的模式。Rob 聽了提議後馬上回到他的辦公室。一兩個小時後他回來了,實現一個正規表示式匹配器:

字元  含義
 c   匹配任意的字元 c
 .   匹配任意的單個字元
 ^   匹配輸入字串的開頭
 $   匹配輸入字串的結尾
 *   匹配前一個字元的零個或多個出現

只用了不到30行C程式碼:

/* match: 在 text 中查詢 regexp */
int match(char *regexp, char *text)
{
  if (regexp[0] == '^') return matchhere(regexp+1, text);
  do { /* 即使字串為空時也必須檢查 */
    if (matchhere(regexp, text)) return 1;
  } while (*text++ != '\0');
  return 0;
}

/* matchhere: 在 text 的開頭查詢 regexp */
int matchhere(char *regexp, char *text)
{
  if (regexp[0] == '\0') return 1;
  if (regexp[1] == '*' ) return matchstar(regexp[0], regexp+2, text);
  if (regexp[0] == '$' && regexp[1] == '\0') return *text == '\0';
  if (*text != '\0' &&  (regexp[0] == '.' || regexp[0] == *text))
    return matchhere(regexp+1, text+1);
  return 0;
}

/* matchstar: 在 text 的開頭查詢 c*regexp */
int matchstar(int c, char *regexp, char *text)
{
  do { /* 萬用字元 * 匹配零個或多個例項 */
    if (matchhere(regexp, text)) return 1;
  } while (*text != '\0' && (*text++ == c || c == '.'));
  return 0;
}

如此少的程式碼實現如此多的功能,同時還提供豐富的內涵和深層次的思想。Brian 認為這是漂亮程式碼的一個極佳示例:緊湊,優雅,高效,實用。也是絕好的遞迴示例。還展示了C指標的強大功能。(熟悉C語言的讀者可自行補上main()函式,寫出測試程式碼)

為“The Book”編寫程式

《程式碼之美》最後一章說到:數學家 Paul Erdős 經常會談到“The book”,這是一本傳說中的書(在地球上任何一家圖書館裡都找不到),在這本書中記錄了所有數學定理的最優證明。(見參考資料6,推薦數學愛好者閱讀)

Brian Hayes 源於某位朋友的靈感,獲得一個可以寫入演算法藝術領域“The Book”的程式。

這個程式所要解決的是一個非常基本的問題:假定平面內有三個點,那麼這三點是否共線?

Hayes 使用 Lisp 語言編寫程式碼。最初的程式通過比較直線的斜率和截距來判斷共線:

(defun naive-collinear (px py qx qy rx ry)
  (let ((m (slope px py qx qy))
        (b (y-intercept px py qx qy)))
    (= ry (+ (* m rx) b))))

(defun slope (px py qx qy)
  (if (= px qx)
      nil
      (/ (- qy py) (- qx px))))

(defun y-intercept (px py qx qy)
  (let ((m (slope px py qx qy)))
    (if (not m)
        nil
        (- py (* m px)))))

(defun less-naive-collinearp (px py qx qy rx ry)
  (let ((m (slope px py qx qy))
        (b (y-intercept px py qx qy)))
    (if (numberp m)
        (= ry (+ (* m rx) b))
        (= px rx))))

上述程式不夠優雅,對平行於縱座標軸的直線需要特別判斷。

後來,Hayes 閱讀了 Jonathan Richard Shewchuk 的論文,通過計算三角形面積巧妙地解決了三點共線問題。最終版的程式如下:(雖然只有廖廖三行,其豐富的內涵足以寫入“The Book”)

(defun area-collinear (px py qx qy rx ry)
  (= (* (- px rx) (- qy ry))
     (* (- qx rx) (- py ry))))

題外話:C 和 Lisp

《程式碼之美》第一章和最後一章分別用 C 和 Lisp 語言闡述作者認為最漂亮的程式。《實用 Common Lisp 程式設計》譯者田春在譯者序末尾說:

C 和 Lisp 是程式語言的兩個極端,大多數人已經熟悉了 C 的那一端,但如果他們還熟悉另一端的話,那麼迅速理解幾乎所有其他的程式語言將不再是問題。

我的O'REILLY書架

我的其他藏書見參考資料7

參考資料

  1. 推薦《程式碼之美》的CSDN論壇舊貼
  2. 某電商的《程式碼之美》宣傳海報
  3. 豆瓣: Beautiful Code
  4. 豆瓣:《程式碼之美》
  5. 豆瓣:《程式設計實踐》
  6. 豆瓣: Proofs from THE BOOK
  7. 圖靈社群:曬曬我的部分藏書

相關文章