我的雲端生活網 - Life+
Monday, December 28, 2009
Erlang 叫用外部程式很簡單
多行程程式是 Erlang 語言的一項重要特色。而許多時候需要叫用外部程式, Erlang 的程式寫法也表現得很優秀。
由於標榜 Concurrency-Oriented Programming , Erlang 讓開發者將每一個函數視為行程。行程要與其他行程溝通,必須藉由拋接訊息來表示請求或回應。 Erlang 程式的訊息介面與 ! (send) 和 receive 兩個關鍵字有關。而外部程式的訊息介面,則稱為 port 。 Erlang 對 port 送訊息給外部程式,也從 port 接收外部程式來的訊息。 Erlang 的 open_port/2 提供了外部程式叫用的功能,並且提供了外部程式的 port 設定方式。例如:
Port1 = open_port( {spawn, simple_work}, [in, out, use_stdio] )
以上 port 的選項, in 容許 simple_work 外部程式可以從 port 接受輸入訊息, out 容許外部程式可以從 port 輸出訊息, use_stdio 指定外部程式的標準輸入和輸出分別對應為 port 輸入和 port 輸出。 simple_work 可能是以下 perl 程式:
#!/usr/bin/perl -w# simple_work programmy $buffer;$buffer = readline STDIN;print $buffer
Erlang port_command/2 可以指定 port 並送訊息。例如:
port_command(Port1, "hello!\n")
simple_work 送出 port 的訊息, Erlang 程式要用 receive 接受訊息,收到的訊息格式依 open_port/2 的選項決定。
參考資料
- Erlang 參考手冊 open_port/2 說明:
http://ftp.sunet.se/pub/lang/erlang/doc/man/erlang.html#open_port-2
Sunday, December 27, 2009
劍客其實不擅長刀法
在這個 blog 應該是不太適合談msn機器人以外的事務 ,不過這幾天我
有感而發,突然想講一個故事 ,不管你認不認識我 ,不管你是不是跟我一
起努力打拼的夥伴 ,不管你喜不喜歡我說故事風格,不管你是不是想給我
一些噓聲或掌聲 ,也許你會嗤之以鼻 ,也許你會會心一笑 ,總之不管如
何 ,這個故事正要開始
以前一個朋友問我一個問題,他問,你喜歡刀還是劍? 這問題讓我思考了很
久 ,我在想; 刀與劍哪裡不同? 想了很久沒有答案(你可以上網找到類似
這類的圖片http://blog.sina.com.cn/s/blog_4a1b8858010005i8.html)
,這讓我想起了另一個故事 ,一群劍客裡有一個劍法精湛的劍客 ,在相同
資歷的劍客裡他總是能輕易的擊敗對手 ,很多高手名流遇到他總是甘拜下風
,但這個劍客有一個習慣,他總是喜歡跟其他的劍客聊到刀客的刀法 ,說那
個刀客的刀法過慢 說這個刀客遇事只攻不守 ,成不了大氣,尤其是他喜歡
問他的劍客友人 ,某個刀客對他的評論是不是公平...,一天 ;他與自己劍
友聊到類似的事情 ,這個同好恰好有事無法久留,但 ;給了一個建議 ,約好
明天一早上山與某位高僧一起繼續這個話題
第二天 ;劍客依約上山找了老和尚 ,老和尚第一句話就說; 久聞施主是一
個毫無自信之人 ,劍客大驚 ;連忙詢問 ,何以見得? 老和尚端坐一旁不急
不徐的說; 眾知施主的劍藝高超, 但卻常評斷刀客刀法拙劣, 正是尋求外
援以解自我空虛之徵 ,探尋其他刀客對自己的評論是否公平 ,正是自信不
足之兆;劍客下山後從此不再向外尋求解答 ;勤鍊刀法 ,往後10年成為一
代宗師
這故事應該有一些啟示 ;顯而易見的是;他思考過這個老和尚說話的意思 ,
而不執著於刀與劍的關係,因為如果下山後再去問朋友自己是不是常常在意
外人對自己的評論? 恰好正中下懷 ,所以及時反求諸己 ,然而真實的世界
裡 ,我們很少思考一件事的全貌 ,劍客應該勤鍊劍法 ,刀法的優劣與劍客
無關 ,但如果要向另一個層次突圍 ,需要熟悉刀法的優點勤練刀法 ,如此
才能融合多方優點成為一代宗師 ,能夠把別人的武器運用自如 ,劍客就會
變成刀客最後變成宗師 ,不管是故事裡故事外道理都是相通的 ;這故事本
身也許是一種武器 ,但要看拿在誰的手裡 ,巧妙各不同 ;而說故事總要有
一些啟發作用 ,至於是不是有啟發的效果 ,可能還需要多一點思考的空間
與慧根了
有感而發,突然想講一個故事 ,不管你認不認識我 ,不管你是不是跟我一
起努力打拼的夥伴 ,不管你喜不喜歡我說故事風格,不管你是不是想給我
一些噓聲或掌聲 ,也許你會嗤之以鼻 ,也許你會會心一笑 ,總之不管如
何 ,這個故事正要開始
以前一個朋友問我一個問題,他問,你喜歡刀還是劍? 這問題讓我思考了很
久 ,我在想; 刀與劍哪裡不同? 想了很久沒有答案(你可以上網找到類似
這類的圖片http://blog.sina.com.cn/s/blog_4a1b8858010005i8.html)
,這讓我想起了另一個故事 ,一群劍客裡有一個劍法精湛的劍客 ,在相同
資歷的劍客裡他總是能輕易的擊敗對手 ,很多高手名流遇到他總是甘拜下風
,但這個劍客有一個習慣,他總是喜歡跟其他的劍客聊到刀客的刀法 ,說那
個刀客的刀法過慢 說這個刀客遇事只攻不守 ,成不了大氣,尤其是他喜歡
問他的劍客友人 ,某個刀客對他的評論是不是公平...,一天 ;他與自己劍
友聊到類似的事情 ,這個同好恰好有事無法久留,但 ;給了一個建議 ,約好
明天一早上山與某位高僧一起繼續這個話題
第二天 ;劍客依約上山找了老和尚 ,老和尚第一句話就說; 久聞施主是一
個毫無自信之人 ,劍客大驚 ;連忙詢問 ,何以見得? 老和尚端坐一旁不急
不徐的說; 眾知施主的劍藝高超, 但卻常評斷刀客刀法拙劣, 正是尋求外
援以解自我空虛之徵 ,探尋其他刀客對自己的評論是否公平 ,正是自信不
足之兆;劍客下山後從此不再向外尋求解答 ;勤鍊刀法 ,往後10年成為一
代宗師
這故事應該有一些啟示 ;顯而易見的是;他思考過這個老和尚說話的意思 ,
而不執著於刀與劍的關係,因為如果下山後再去問朋友自己是不是常常在意
外人對自己的評論? 恰好正中下懷 ,所以及時反求諸己 ,然而真實的世界
裡 ,我們很少思考一件事的全貌 ,劍客應該勤鍊劍法 ,刀法的優劣與劍客
無關 ,但如果要向另一個層次突圍 ,需要熟悉刀法的優點勤練刀法 ,如此
才能融合多方優點成為一代宗師 ,能夠把別人的武器運用自如 ,劍客就會
變成刀客最後變成宗師 ,不管是故事裡故事外道理都是相通的 ;這故事本
身也許是一種武器 ,但要看拿在誰的手裡 ,巧妙各不同 ;而說故事總要有
一些啟發作用 ,至於是不是有啟發的效果 ,可能還需要多一點思考的空間
與慧根了
Sunday, December 13, 2009
WebGL規格草稿釋出
很久以前網頁上做3D就是VRML了。最近有WebGL釋出,是OpenGL管理社群與瀏覽器開發組織的協議產物。WebGL規格書(https://cvs.khronos.org/svn/repos/registry/trunk/public/webgl/doc/spec/WebGL-spec.html) 可見到一些程式介面。WebGL容許開發者用JavaScript在網頁上畫圖了嗎?
我的第一個疑問是,用JavaScript在網頁上畫圖,是否會讓一些繪圖程式無法不公開?或者,為了讓繪圖程式不公開,要做更多程式混亂工程(code obscurity)?不過通常不要太依賴弄亂程式碼來確保一些安全比較好,這種安全是不穩定的,可見相關討論: http://www.owasp.org/index.php/Avoid_security_by_obscurity 。
Monday, December 7, 2009
自然語言處理
資料統計方式的文件翻譯
2009年三月 Google 的 Alon Halevy 等人放出一篇通俗的文章,題名為 The Unreasonable Effectiveness of Data ,說明了用資料統計方法處理文章翻譯的好處。
他們提到,即使 Eugene 撰文 The Unreasonable Effectiveness of Mathematics in the Natural Sciences 說明物理學學者怎麼都愛用數學式做優雅的表達,但是碰到英文翻譯就不一定都有好處,好比經濟學家用數學也不好處理人文社會的情況。 Google 處理大量的網頁資料,他們的資料庫 (corpus) 特別沒有規矩,存在許多拼字錯誤、用法錯誤、甚至有造假文字。但是他們能用統計方法,處理這些網頁資料,得到他們要的翻譯。
所謂翻譯,是指處理文件及資料。翻譯是自然語言處理的其中一種應用,其他有語源分析、資訊萃取等等。翻譯文件是人們大量使用的應用方式,所以在網路上有各種文件的各種語言版本,不需要多少人力處理。而專用於傳統語言處理的語料庫 (corpus) 則需要相當大量的人力,做語法、語意的定義工作。所以,傳統自然語言處理方法的語料整理工夫已消耗太多人力。然而,考慮到文件翻譯,網路上已經存在許多可用的語料庫了,應絯善用這些網路資料。
在網路文件的錯誤方面,雖然在百萬級 (million) 資料量中,文件中存在的錯誤可能有影響,但是當語料庫數量達到十億級 (billion) 甚至兆級 (trillion) 數量,文件錯誤佔了相對更少的比例。使用統計式的自然語言處理可以收到自然的正確結果。 MapReduce 恰好非常適用於統計式翻譯。
2009年三月 Google 的 Alon Halevy 等人放出一篇通俗的文章,題名為 The Unreasonable Effectiveness of Data ,說明了用資料統計方法處理文章翻譯的好處。
他們提到,即使 Eugene 撰文 The Unreasonable Effectiveness of Mathematics in the Natural Sciences 說明物理學學者怎麼都愛用數學式做優雅的表達,但是碰到英文翻譯就不一定都有好處,好比經濟學家用數學也不好處理人文社會的情況。 Google 處理大量的網頁資料,他們的資料庫 (corpus) 特別沒有規矩,存在許多拼字錯誤、用法錯誤、甚至有造假文字。但是他們能用統計方法,處理這些網頁資料,得到他們要的翻譯。
所謂翻譯,是指處理文件及資料。翻譯是自然語言處理的其中一種應用,其他有語源分析、資訊萃取等等。翻譯文件是人們大量使用的應用方式,所以在網路上有各種文件的各種語言版本,不需要多少人力處理。而專用於傳統語言處理的語料庫 (corpus) 則需要相當大量的人力,做語法、語意的定義工作。所以,傳統自然語言處理方法的語料整理工夫已消耗太多人力。然而,考慮到文件翻譯,網路上已經存在許多可用的語料庫了,應絯善用這些網路資料。
在網路文件的錯誤方面,雖然在百萬級 (million) 資料量中,文件中存在的錯誤可能有影響,但是當語料庫數量達到十億級 (billion) 甚至兆級 (trillion) 數量,文件錯誤佔了相對更少的比例。使用統計式的自然語言處理可以收到自然的正確結果。 MapReduce 恰好非常適用於統計式翻譯。
統計式翻譯方法的缺點是,無法糾正來源的語料庫存在的錯誤,也不容易對抗一些造假的事實。不過,翻譯工作只需要把一個文件變成另一種語言版本,而不是要做推理。
語言的組合性
在語言學中,自然語意的解釋,是指有用一種後設語言 (meta-language) 處理某一種目標語言 (object-language) 的句子意思。例如,用英文解釋波蘭文句子的意思,波蘭文是目標語言,英文則是後設語言。按照這種思維,電腦程式語言是哪個層次的語言呢?
回到語言理論,Allan Keith的書 Natural Language Semantics 提到傳統語言處理。語言是由許多單字組成,而單字的意義是可以組合的。句子或片語的意思可以由所構成單字的意思組成。 Allan James 的書 Natural language understanding 也提到,語言處理在應用上可分為幾個類型,其中一種是將語言應用系統做為問答系統,另一種是將語言系統做為用語言發送指令。我想,採用複雜事件處理的概念,或許可以將一個句子的每個單字當做是各別到達的事件,我們對句子做複雜事件的偵測,把一些關鍵詞的意思抓出來,根據每個關鍵詞的前後順序決定這個句子對應成什麼意思、代表什麼指令,然後對系統發出指令。
自然語言句子做為指令的系統,實作上的基本優勢是:雖然自然語言理論上有無窮數量的語料庫,但電腦系統接受的指令是有限的,所以自然語言對應到電腦的句子語料庫少了很多。至少這是可慶幸的。
Friday, December 4, 2009
Thursday, December 3, 2009
程式風格與系統實作
有個著名的99題程式問題集中有二件基本問題:
- 反轉一列資料。
- 檢查一列資料是不是回文。
用 Erlang 寫,程式如下:
reverse( [ ] ) -> [ ] ;
reverse( [ X | Y ] ) -> reverse( Y ) ++ [ X ] .
palindrome( Xs ) -> reverse( Xs ) == Xs.
這些問題主要是在考邏輯程式語言或函數程式語言解決問題的方法,用 Erlang 寫非常自然。至於考慮到用指令式程式語言,程式會怎麼寫呢?先想想 C 程式。
void reverse(char *x, int xn, char *y, int yn) {
int i;
int i;
yn = xn;
for(i=0; i<xn/2+1; i++) {
y[i] = x[xn-1-i];
y[yn-1-i] = x[i];
}
for(i=0; i<xn/2+1; i++) {
y[i] = x[xn-1-i];
y[yn-1-i] = x[i];
}
}
main() {
char a[] = {'a', 'b', 'c', 'd', 'e'};
char b[] = {'1', '1', '1', '1', '1'};
reverse(a, 5, b, 5);
}
以上程式是反轉一列資料。至於檢查是不是回文,與反轉一列資料有相當的程式結構。所以,照著反轉程式結構可以改出檢查回文的程式。
/* void reverse */ int is_palindrome(char *x, int xn /* , char *y, int yn */ ) {
int i;
// yn = xn;
int i;
// yn = xn;
int result = TRUE;
for(i=0; i<xn/2+1; i++) {
// y[i] = x[xn-1-i];
// y[i] = x[xn-1-i];
result &= (x[i] == x[xn-1-i]);
// y[yn-1-i] = x[i];
}
// y[yn-1-i] = x[i];
}
return result;
}
}
Erlang 程式和 C 程式各自從掌握的不同邏輯意思解決問題。對 Erlang 程式來說,一列資料是回文隱含了將這一列資料反轉會和原資料相同。對 C 程式來說,是考慮到一列資料若是回文,資料每一項在前半段位置的,會和在後半段鏡射位置的資料相同。所以,用 C 寫以上程式,一定要把以上二個程式寫成一樣的結構,因為它們的順序邏輯一樣。但是用 Erlang 寫程式,則可以說是反轉資料問題是檢查回文問題的子問題。不同的語言有各自解決問題的能力。用 C 的程式風格思考, Erlang 真不好寫;並且用 Erlang 的程式風格思考, C 也不好寫。不過,只要用 Erlang 的方式寫 Erlang 程式,用 C 的方式寫 C 程式,都是做對事情了。
所以,本篇文題回到系統實作方面:本來我有個系統是用 Perl 規則持續讀檔案,用檔案時間判斷是否有新的 RFID reader 讀數出現。系統中存在大量這種類型的 Perl 規則,並且反覆判讀檔案消耗大量時間。我可以用 MapReduce 來節省工作時間嗎? MapReduce 本身就是前車之鑑。
在有大量資料需要處理的分散系統上,要直接寫程式,不管是什麼檔案鎖定、程序鎖定、或是信號的控制機制,最後都是普通的程式處理方式:把大量資料塞進一個迴圈裏。 MapReduce 是個漂亮的程式作法,它的思考方向是程式有多少等級的數量,程式也產生出多少等級數量的程序,讓每個程序分配到相當少量的工作,許多程序一起做!所以,前後二種處理方法,在程式的寫法上相當不同。直接的程式,想法依然直接。但是,實作 MapReduce 是先做一個計算框架,框架中有二種空位存放 map 和 reduce 二種類型的程式;而中樞設計不要思考 map 和 reduce 程式可能怎麼寫,而是只思考把一些程序分配去執行 map 程式、另一些程序分配去執行 reduce 程式,並且這些程序如果中斷但沒做完工作,就再分配一次同樣的工作。於是,剩下的工作是 map 和 reduce 程式都比較好寫,而且寫完並套進 MapReduce 架構之後,就可以處理大量的資料。同樣的問題處理,可以用不同的程式方法解決問題。
依我看,現有系統的規則,只有檢查新 reader 讀數的規則可以保留,直接寫成 map 程式。
rfid_read ( File, Reads ) :
for each (Tag_ID, Reader_ID, Time) in Recent(Reads)
emit( (observation, (Tag_ID, Reader_ID, Time)) )
然後交給其他的 reduce 程式處理。至於其他類型的規則,則要按照 MapReduce 的思維改寫成適當的 map 程式或 reduce 程式比較好。
Subscribe to:
Posts (Atom)