Email me: jollen # jollen.org

more: Jollen 的 Embedded Linux 教育訓練

« September 2013 | (回到Blog入口) | November 2013 »

October 2013 歸檔

October 18, 2013

深入淺出 JavaScript Lambda

註:本文節錄自「Node.js & HTML5 開發思惟與入門學習」一書,並原文重現。

本章的目標,是提昇初學者的開發功力。經過前面 4 個章節的介紹,學習到許多基本觀念與技術。接下來,將從三個不同的層面,深化目前所學到的觀念與技術:

  • JavaScript 語言
  • Web Service 架構
  • Node.js 觀念

本章先從 JavaScript 語言開始。JavaScript 最重要的觀念是 Closure,這可以說是 JavaScript 初學者的第 1 堂。Closure 與暱名函數有很緊密的關係,這要由 Lambda 的觀念開始講起。

Lambda

Lambda(λ)是一個希臘字母(Λ 是它的大寫字母),用來表示許多觀念:

  • 物理學家用來表示波長的符號
  • 數學家用來表示空字串的符號
  • 電腦科學家用來表示暱名函數(Anonymous Function)的符號

Lambda 在電腦科學領域,用來表示暱名函數,目的是進行運算。為了尋找一個語法簡易的運算表示方式,電腦科學家會這麼做。

Step 1:取得一個具名的函數

例如一個加法函數:

sum(x) = x + 2

函數 sum() 是具名函數,利用 JavaScript 來實作的話,寫法如下:

function sum(x) {
     return x + 2;
}

Step 2:改寫為暱名函數

Lambda 希望可以找到一個能運算的表示方法,而且要簡單,去除掉函數名稱,就是一個方式。沒有具體名稱的函數,就稱為暱名函數(Anonymous Function)。如果表示暱名函數呢?上述範例,以 Lambda 來表示的話,只要改寫成:

λx.x + 2

用 JavaScript 來實作的話,要如何撰寫呢?方式如下:

(function(x) {
     return x + 2;
})();

這就是第 1 章介紹的 Closure 觀念,最後加上的一對括號,稱為立即函數,意思是立即執行此暱名函數的意思。立即函數,以物件導向的角度來看,也可以解釋為立即實例化。

Step 3:使用 var 來宣告暱名函數

JavaScript 的 var 關鍵字用來宣告變數,所以也可以把暱名函數做為運算子(Operator)來宣告變數。例如:

var lambda = (function(x) {
     return x + 2;
})();

變數 lambda 被指定(Assign)為一個暱名函數。從 JavaScript 語言的角度來看,Closure 用來封裝出 Module,所以 lambda 變數也可以解釋成「一個模組」。宣告一個暱名函數的變數時,可以不需要 Closure。也可以採用以下的寫法:

var lambda = function(x) {
     return x + 2;
};

事實上,這個寫法更為普遍。一些文章也把這種寫法,稱做 Function Expressions。

有一個重要的觀念要釐清,上述的寫法,正規的解釋方式是「宣告暱名函數的變數」,所以 lambda 是一個變數,不能解釋為函數。如果說 lambda 是一個函數宣告,觀念上就不對了。不能單就 JavaScript 語法的角度來做解釋。

以 JavaScript 來說,函數宣告的寫法為:

function lambda(x) {
     return x + 2;
};

這個時候,lambda 就是一個函數。那一種寫法比較好呢?理論上,採用暱名函數宣告的方式較佳,因為 JavaScript 本身是一種 Lambda 的程式語言。

Callback Function

Lambda 本質上是一種表示方法,用來表示 Input 與 Output。所以,要表示一個平方的運算的話,寫法如下:

λx.x*x

這個運算式,也可以做為另一個 Lambda 式子的 Input,請看以下的說明。

Step 1:撰寫第一個計算平方的 Lambda 表示式

做法如下:

λx.x*x

Step 2:把上述的式子做為另一個 Lambda 的輸入

有一個 f(x) = x + 2 的函數,用 Lambda 來表示的話,寫法如下:

(λx.x+2)

如果要把 Step 1 的結果,做當上面式子的 x(輸入),合併後的寫法為:

(λx.x*x)(λx.x+2)

讓我們來筆算看看:

  • x = 3 時,λx.x*x 的 Output 為 9
  • 9 做為 λx.x+2 的 Input,成為 9 + 2,Output 為 11
  • 答案就是 11

(λx.x*x)(λx.x+2) 等價於 9 + 2。

Step 3:使用 JavaScript 來實作

怎麼把 (λx.x*x)(λx.x+2) 寫成程式碼呢?非常簡單,由於 Output 就是返回值,所以等於「讓暱名函數的返回值,當做另一個暱名函數的參數」。程式碼如下:

var lambda = function(x) { return x + 2 };
var result = lambda(function(x) { return x * x} (3) );

console.log("Result: " + result);

這個輸出的輸出結果為 11。這可不是在賣弄程式碼,而是實現出 (λx.x*x)(λx.x+2) 這個 Lambda 演算。以暱名函數來表示 Lambda 是很常見的做法,但其實反應出 JavaScript 語法上的不足。如果能有一個更簡易的語法,讓我們表示 Lambda,這段程式碼就會比較精簡。

所以,這很可能要從修改 JavaScript 語法的角度,來做強化。未來,新的 ECMAScript(JavaScript 的語法標準)或許可以讓我們這樣寫程式:

function(x) { return x + 2 }  // 複雜的寫法
x => x + 2                            // 希望可以有這種精簡的語法

再舉一個例子:

var result = (x => x * x) 3;  // 左結合寫法,輸入值 3 放在最右邊,最後 result 為 9

如果將 Lambda 做為函數的參數:

[1, 2, 3, 4, 5]
     .map(function(x) { return x * x });

未來或許能簡化為:

[1, 2, 3, 4, 5]
     .map(x => x * x);             // 希望可以有這種精簡的語法

在 ECMAScript 還沒有正式加入相關語法前,我們目前還是只能使用暱名函數的寫法。

使用 TypeScript

在深入了解 Lambda 的觀念後,就能知道根本之道在於「新的 JavaScript 語法」。目前有一些 Open Source 程式庫,就試著在解決這個問題。唯有透徹底了解 Lambda 的觀念,才能知道這些程式庫目地何在。

筆者推薦的解決方案是:TypeScript。這是一個由 Microsoft 所開發的工具,實際上是一個 Compiler。TypeScript 提供了擴充的 JavaScript 語法,可藉由 TypeScript 編譯為標準的 JavaScript 語法。

首先,必須先使用 npm 安裝 TypeScript 工具:

$ npm install -g typescript

接著,以 TypeScript 的語法撰寫 JavaScript 程式碼。TypeScript 的語法就是 JavaScript 語法,只是提供了許多好用的擴充語言,因此學習上並沒有障礙。以下是一個 TypeScript 範例:

var square = (x) => x * x
console.log(square(3));

將程式碼儲存為 l.ts 後,再利用 TypeScript 編譯:

$ tsc l.ts

編譯後可以得到 l.js 檔案,以下是 l.js 的內容:

var square = function (x) {
    return x * x;
};
console.log(square(3));

看到編譯後的程式碼後,馬上可以反應出這個觀念:TypeScript 提供一個簡單好用的 Lambda 語法。當然,TypeScript 的功能很豐富,這只是牛刀小試。

October 25, 2013

Publish Early 早期出版新文化

本文章採用 Markdown 語法撰寫(why?),若無法閱讀內文,請點擊這裡。

資訊圖書的出版要進入一個新時代了。因為資訊科技進步神速,以及開放內容(Open Content)的推波助瀾,過去資訊相關圖書的出版模式將再次改變。

過去最明顯的現象就是專業電腦書的輕薄化。輕薄化有二個意涵:第一、內容簡明扼要,甚致沒有太多的鋪陳,讀者的背景知識必須充份;第二、頁數變少,過去幾年,新技術的電腦書,或是主題限定在一定範圍的電腦書,頁數大多維持在 200 頁附近。

輕薄短小、簡潔有力

對筆者來說,這種輕薄化的電腦書,可以帶來無比舒適,以及有效率的閱讀。雖然這類型電腦書的頁數少,但內容可不簡單,不但意簡言賅,直達技術的核心,對於重要觀念的講解,也相當精確。當然,閱讀這種電腦書,就要具備一定的背景知識。

現在,由於技術進步更快,使得寫作到實體出版的速度遠不及技術的變化。實體書已經無法扮演傳播知識的良好角色了。所以,現在我們可以看到資訊出版再度進入新的轉變期。一個是電子書與自助出版的盛行。例如:Amazon Single 可以提供作者一個自助出版的管道。另一個則是 Micro Book 概念的出現。Amazon Single 的出現,其實也是想幫助作者出版 Micro Book 作品。

以電子書、電子出版與微型書的模式,讓知識能快速傳遞到讀者手上,這種新的出版模式,才能跟上技術的快速變化。

微型書

近二年來,電腦出版業似乎出現一波微型書(Micro Book)的出版風潮。所謂的微型書,就是頁數介於 50-80 頁的電腦書。這類型的電腦書,一般都是先採取電子書或電子出版形式,最後出版商再印製實體書上架販售。

Micro Book 本身的文字內容,大多在網路上能免費取得,但網路上的文章形式過於鬆散,所以 Micro Book 在這個時代,有另外一種價值。台積長董事長張忠謀先生,在 2000 年一場講座中說:「網路無益於知識的累積。」如果我們要讓網路上的內容 (Content)變成自已的知識(Knowledge),系統化地整理並編篆這些免費內容是很重要的工作。

就是因為免費內容太多,我們更需要專家為我們去整理並編篆這些內容,Micro Book 就是一個很好的解決方案,因為它的出版相當快速(一般是三個月內),不必等到完整的書寫完後再出版(可能費時一年),甚致可以做到隨時改版(Publish Often)的服務。花一年去編寫並出版的實體電腦書,等到上市後,不但內容也老了(這一點都不誇張),而且技術人員根本等不及它的出版。

微型書是技術工程人員的寶物,它能幫助我們將免費內容形成個人的知識。因為免費內容太多,微型書能讓技術學習者接軌這些免費內容,這是一個免費內容的新時代,微型書有著它的時代價值。

Publish Early, Publish Often

軟體技術的更新速度很快,微型書不但能快速出版,傳遞新知識到每個人手上,也能節省學習者的時間。目前網路上有許多 E-Book 的出版平臺,上面出版的電腦書,很多都是非常新的主題,而且篇幅都不長。這對新知識的吸收很有幫助。

在 Leanpub 上面可以找到很多「寫作中的書」,讀者可以先購買寫作中的書,提早學習新知識。這種讀書與寫書的新文化,頗值得推廣。筆者不只開始養成閱讀這些「早期出版」圖書的習慣,也開始對創作早期出版品產生興趣。

筆者開始在 Leanpub 的平臺上,[嚐試進行早期寫作],將原本部落格式的寫作,轉移成書藉的寫作習慣。這樣的轉變目的,是希望讓寫作的結構更好,成為優質寫作者。

關於 October 2013

此頁面包含了在October 2013發表於Jollen's Blog的所有日記,它們從老到新列出。

前一個存檔 September 2013。

後一個存檔 November 2013。

更多信息可在 主索引 頁和 歸檔 頁看到。

Top | 授權條款 | Jollen's Forum: Blog 評論、討論與搜尋
Copyright(c) 2006 www.jollen.org