2006/08/31

家庭攤 & Desktop Layout

今天全家到陶板屋。口味不錯,服務態度也不錯。聽了 Skusi-Shockgider 的話點了雞肉,但事實上牛肉不會多難吃啊 XD。

之後買了兩條 USB 連接線,一條是單純的延長線(A 公 A 母),一條是 A-B 型的連接線,以便讓 MX1000 和 SCX-4200 能分供 PB 和 PC 使用。這學期計畫把主機放在桌子底下,把一個 USB 插槽以延長線拉到桌面上,MX1000 的連接座就可以插在 PB 或那條延長線(thus PC)上;同時再拉一個 B 型接頭到桌面,連同 SCX-4200 原先附的那條,SCX-4200 就可以接在 PB 或 PC 上。VP171s 早就有內建的分享機制;MS Natural Keyboard 不需要分享(因為 PB 的鍵盤夠好用了)。這麼一來,桌面的裝置都物盡其用,切換也不會太麻煩。

打完上段後發現兩個失誤:MX1000 後來想到直接接在 Natural Keyboard 上就可以了,那條延長線並非必要,不過拉一個 USB 插槽到桌面也不錯。另外忘了找音源的延長線,這就到台北再找找吧。

AppleCare 的書面通知今天也從新加坡寄到。

--
公母頭的稱呼實在應該換掉,可是又沒有其他通用的名稱。


後來再一想,A-B 型連接線應該也買延長線才方便。上台北再解決 XD。

Blogger yen38/31/2006 3:52 pm 說:

改作頭尾如何,家庭只有寫兩行,朋友寫了三四行,差真多...

Blogger Fall8/31/2006 5:57 pm 說:

囧板屋…

Blogger skusi9/02/2006 10:57 am 說:

它的牛肉好像換了
之前去吃過幾個月就爆出
它的牛肉是組合牛肉的事
也許它換過了吧
但是...
那個價位你還真吃的下

Blogger Josh Ko9/02/2006 11:07 am 說:

你們那攤都吃下去了,這攤如何吃不下?XD

<< 回到頁首

2006/08/30

返北日期

原定 9/9(六)。想必大家看到這日期都覺得很面熟,沒錯,就是倒扁靜坐的開始日期。為了避開可能的車潮,返北提前到 9/6(三)。屆時不知道二二八公園(or 天瓏附近)有沒有活動,如果有的話,可能得拋棄香香提前去天瓏一趟。

--
圖書館計畫蠢蠢欲動 XD。

Blogger yen38/30/2006 2:12 pm 說:

加油啦,話說我也是在認真中(理論上還是比你懶)

<< 回到頁首

2006/08/29

理想課表最終版

又在神的慫恿之下,捨棄【從現代生物學看人類行為】,改修【西洋哲學史】。原本想為星期一或五下午再找門課,後來也打消念頭。【離散數學】若沒辦法簽到雙班也無大礙,我只是為了讓星期五下午早點空出來而已。開學後加簽【高等微積分】、【自動機與形式語言】、【哲學與人生】、【離散數學】四科就完成了,共 27 學分。詳見 Sidebar "Schedule (Fall 2006)" 區段。

--
應該 manageable 吧 :P。

Blogger yen38/29/2006 6:15 pm 說:

公民教育你沒有說到喔XD

Blogger Fall8/29/2006 11:56 pm 說:

小聲說:依稀記得一年前有說要到元智聽課
(真的…夠小聲吧!)

Blogger yen38/30/2006 1:11 am 說:

那個是沒開課,不是沒去聽...Orz

<< 回到頁首

第一階段選課結果

顯然運氣不怎麼好 XD。體育九個志願和兩個通識全部沒上,這學期又上不到體育嘍 :P。【二李詞】就放棄了,【從現代生物學看人類行為】試著加簽看看。星期五下午有齊肖琪教授開的【生命的探索】,也可以納入考慮,但如果謝豐舟教授肯簽大概就不會選這門,因為同一學期修兩門生物學通識怪怪的 :P。星期二 34@ 有大名鼎鼎的傅佩榮教授開的【哲學與人生】,看 NTUCourse 板說只要前三次簽到必加簽,那就試試看啦。只不過這麼一來,星期二就從第 3 節(10:20)連綿不斷上課到第 C 節(21:15),中間沒有任何一節空堂(是的,中午那節也要上課)。唔,那天背包可能得多裝一點乾糧,趁通勤空檔偷吃 XD。大概星期一或星期五下午再找一門課,就可以結束了吧。

說到【高等微積分】,運氣似乎也不是那麼差 :)。金次高微總限 90 人,已選 28 人,剩餘 62 人,其中外系限 40 人已選 13 人,應該不用太擔心加簽不到 :P。真是的,怎麼都沒人要修高微呢?!XD

--
Sidebar 的課表晚上確定最後一門(通識)課後更新。

Blogger yen38/29/2006 6:07 pm 說:

我在想你的大四有多少體育課要修就是了

<< 回到頁首

CRTP 檢驗問題

我寫了這樣的程式碼模擬下面那篇文章所說的 static_assert

 1: #include <tr1/type_traits>
 2: #include <iostream>
 3: 
 4: using namespace std;
 5: 
 6: template <bool>
 7: struct static_assert;
 8: 
 9: template <>
10: struct static_assert<true> { };
11: 
12: template <typename T>
13: class CRTPbase
14:   : static_assert< tr1::is_base_of<CRTPbase<T>, T>::value > {
15:   // ...
16: };
17: 
18: class C : public CRTPbase<C> {
19:   // ...
20: };
21: 
22: int main() {
23:   // ...
24: }

不過編譯結果顯示,tr1::is_base_of<CRTPbase<C>, C>::value 竟然是 0false)。觀察一下具現化過程,L18 首先意圖具現化 CRTPbase<C>,從而意圖具現化 static_assert base struct,最後是作為前者 template 引數的 tr1::is_base_of<CRTPbase<C>, C>。此時可能是因為 class C 和「具現中的 CRTPbase<C>」之間的繼承關係尚未搭起(畢竟 base class 還沒生出來),所以使得 static_assert 具現失敗。唔,有解嗎?

--
HTML 對於 template code 真是太不友善了 XD。

2006/08/28

Curiously Recurring Generics

在《The Java Programming Language, 4/e》p.159 的註腳 3 這麼說:

Enum is actually a generic class defined as Enum<T extends Enum<T>>. This circular definition is probably the most confounding generic type definition you are likely to encounter. We're assured by the type theorists that this is quite valid and significant, and that we should simply not think about it too much, for which we are grateful.

此書作者之一 Ken Arnold 在他的一篇 blog《Generics Considered Harmful》引用這段文字,然後說:

And we are grateful. But if we (meaning David)(JK 注:David Holmes,另一位協同作者,負責 Generics 章節)can't explain it so programmers can understand it, something is seriously wrong.

在我看來,這雖然不是 Java Generics 最令人頭疼的部份,也夠令人頭疼了。今日翻《Thinking in Java, 4/e》,發現若從 C++ CRTP(Curiously-Recurring Template Pattern)類推,解釋變得相當簡單,描述如下。

C++ CRTP 指的是一個 class C 繼承自某個 class template 具現體,並以 C 本身為那個 base class template 的 template argument。被具現出的 base class template 於是獲得 subclass(C)的型別資訊而可「特化」自己的 data members / member functions,而後者又被 subclass 所繼承,最後 subclass 會獲得為自己特化的功能。型如:

template <typename T>
class CRTPbase { /* ... */ };

class C : public CRTPbase<C> {
  // ...
};

這個手法到了 Java 一樣可以實現:

class CRGbase<T> {  // 目前對 T 沒有任何限制
  // ...
}

class C extends CRGbase<C> {
  // ...
}

但我們對於 CRGbase 的型別參數(type parameter)T 實際上並非全無限制:我們希望 CRGbase 只用於 CRG(Curiously Recurring Generics)手法,也就是像 class T extends CRGbase<T> 這樣的形式,其中 T 是任意型別 ─ 哈,那個式子正好是可提供給 CRGbase 的型別引數形式!所以 CRGbase 之型別參數的限制只需照著那形式填進去就行了:

class CRGbase<T extends CRGbase<T>> {  // 我們想要的結果
  // ...
}

C++ 的話,現行可採用《Static C++ Template Argument Constraints Checking》的作法,未來 C++0x 可用 standard library 的 is_base_of type-trait class 搭配 static_assert,即可完成類似檢驗。

--
就算這式子讀得通了,也只是冰山一角,Java Generics 還有更多更不直覺的東西 XD。

Blogger yen38/29/2006 1:10 pm 說:

CRTP感覺上這是一個頗有趣的技法

Anonymous Anonymous8/30/2006 6:20 pm 說:

以前 Bruce Eckel 發表了一篇文章
Self-bounding generics

裡面的討論有說到 CRGbase 中的 T 不一定
等於繼承它的型別 , 因為有這種情況:

class A extends HasF<A>
{
}

class B extends HasF<A>
{
}

Blogger Josh Ko8/31/2006 1:59 am 說:

這樣感覺好像作弊 :P。B 所繼承的 HasF<A> 之所以能通過,是因為前面已經有滿足其型別變數限制的宣告了。

不過這麼說來,單純用 type bound 想強制用戶使用 CRG 形式,行不通呢。

<< 回到頁首

ACM Turing Award Lectures

終於找到《ACM Turing Award Lectures: the First Twenty Years, 1966 to 1985》,從書名就可看出,此書收錄了最先二十年 Turing Award 得主的演講稿!不過此書是 1987 年出版(和我一樣老!),現在似乎很難買到 new copy,幸好台大圖書館裡面藏有此書(而且有兩本)。

--
立刻列入 WishList 之內!

Blogger yen38/28/2006 1:46 pm 說:

這本聽起來一整個就是古老啊,不過..Turing Award看你上次翻的還頗辛苦的,不要看的太累嘿

<< 回到頁首

2006/08/27

心得偶拾

一般人說不要儘鑽(程式)語言,但對於語言卻連基本認知都不完整,恐怕沒資格下這種評論;正如一般大學生說大學不僅是讀書,卻在功課上打混過去「但求 60 分」,是同一種心態 ─ 拿深刻理由當膚淺藉口罷了。

《C++ Primer》一向被評為不適合初學者,我卻認為(單獨)以《C++ How to Program》這樣程度的書籍入門不是好選擇。C++ 本身是複雜語言的事實,不是書簡單就能掩蓋的。比較好的折衷方案是請人指導,或以《C++ Primer》為主、較淺顯書籍為輔。

--
原始出處:Messenger 對談。

Blogger skusi8/27/2006 4:37 pm 說:

你要不要監督我看你出的那本書
也許我才能插的上話

Blogger yen38/27/2006 5:03 pm 說:

如果真的要自修的話,我覺得先看懂C++ How to Program 5/e,再看C++ Primer 4/e的相關章節,前者在於讓你有個初步認識,後者在於讓你了解其機制,當然Josh 認為,以C++ Primer為主,這是可接受的


--
這樣子一說,我要不要親自教我直屬學妹..XD

Blogger yen38/27/2006 5:09 pm 說:

如果用一個很有趣的角度切入,需要有人教導為前提的話,大學教程未必能擔當起這個責任(我對大學程式設計學程教育,哈),如果要私下教的話,能教學的人數必然遠遠不足,或許,這又是一個很有趣的問題

---
這種事都是嘴炮,要實現還真難..orz

Blogger Fall8/28/2006 3:23 am 說:

據說我們用的可是更x的 C primer plus

Anonymous Anonymous8/28/2006 10:50 am 說:

好久沒有看到你…還是一直在c++的世界裡嗎?
這個星期四不知道會不會見到你。

Blogger Josh Ko8/28/2006 11:31 am 說:

哈,的確是好久不見 :)。

大一下學期主要碰 Java,暑假初期碰了一點 Ruby,到後半段(也就是最近)剛好回到 C++ :P。無論如何,我和 C++ 最熟,不管日後轉向哪邊,都會儘量與 C++ 維持適當熟悉度吧。

星期四?大概不會,我不知道那天有什麼活動,而且那天有全家聚餐 :P。

Blogger Celith8/28/2006 6:03 pm 說:

呵~
C++ How to Program,這本我沒看過~
我認為問題不在於書難不難,而在於「語言思維」能否建構出。閱讀如 How to Program 之類的書,也許比較容易意識到語法本身,但「語言思維」是否較容易建立起,這答案見人見智。

<< 回到頁首

Google Analytics

從新聞看到 Google Analytics 開放使用,於是為這個 blog 申請一個試試看。功能似乎沒有 StatCounter 來得完善(或者該說,Google Analytics 的主要對象是商業用戶,針對我這種一般用戶的功能相較少一些),應該只會偶爾看看(Google Analytics 也只提供每週報告,沒有即時報告),甚至試用一陣子後拿掉(那個 logo 真的很難塞 XD)。話說回來,這個 blog 的不尋常人氣已逐漸降溫,大概也不需要怎麼分析了 XD。

--
薪水好像全部入帳了 XD。

Blogger yen38/27/2006 10:10 am 說:

哈哈,不要這樣子想,等開學後就會好一點啦,還有,記得請我喝酒...~

--
人生什麼都不欠,欠酒喝而己

Blogger Fall8/27/2006 2:06 pm 說:

喝酒不好 喝酒不好
我只要檸檬紅就好(夠便宜吧 - ++++++ - )

Blogger skusi8/27/2006 4:42 pm 說:

我回應少是反映內容我看不懂

<< 回到頁首

2006/08/26

幾何

翻過聰明的《數學拾貝》和《數學的發現趣談》,發現自己對於幾何(geometry)相當不熟悉。聰明在課堂上提過:「數缺形少直覺,形缺數難入微」,而我目前預計想修的科目大都是代數分析一類。看來又有 yet another big project:讀歐幾里得(Euclid)的《幾何原本》(Elements),探索這最古老的公理化演繹系統。沒辦法,最基礎的基礎沒打好,只能拚命補,否則根本搆不到高階主題。

--
"Yet another",何時呢?

Blogger yen38/26/2006 8:21 pm 說:

你這樣子一說,我反而想從最基本的數學複習到微積分再一路向上,哈哈,可能是個夢想,最近在搞linux

<< 回到頁首

主攤

地點是曉陽路麥當勞旁新開張的紅敞牛排,共六人。餐廳服務相當高級,服務生均經過特別訓練,中途不小心弄倒一杯水,也立刻換掉桌紙復原桌面。餐點口味也滿不錯。當然,價錢也不低 XD。之後又到隔壁麥當勞聊天,直至方才。

--
所謂「一勞永逸」XD。

Blogger yen38/26/2006 3:30 pm 說:

看來這攤花很大......小破產喔

<< 回到頁首

2006/08/25

琴房租借公告

公告本中心95年10月至96年1月份鋼琴登記使用事項。

公告事項:

一 、登記地點:本中心一0一辦公室。
二 、登記時間:9月19日起上午八時三十分至十五時(假日除外),以先後順序登記,選取每週固定四小時彈練時間,額滿為止。
三 、彈練時間:每週一至週五八時至廿二時,週六、週日八時至十七時。
四 、使用費用:95年10月至96年1月計四個月,每月壹佰元,計新台幣肆佰元整,登記後費用一次繳清。
五 、日後憑證使用。

--
每學期初都得搶一次 XD。

Blogger yen38/25/2006 1:57 pm 說:

加油啊,有空記得錄音給我聽~嘿嘿嘿

Blogger Josh Ko8/25/2006 2:29 pm 說:

在學校大概每次都會錄音,只是都是練習片段,不敢公開釋出而已 XD。

<< 回到頁首

觀天下

今天到久未見面(或說一波三折而未能得見)的國中導師家閒敘。事前邀約名單明明男女均衡,實際上男生卻只我一個到(以及後來以「外賣」名義請來的另一位)。中途還聽老師的小朋友彈琴(破舊的電子琴),雖是簡單旋律倒也富有趣味,不過不知道小朋友自己怎麼想就是了。每首練十次,手又還不太有力,看他直喊痠,有點可憐 :P。

--
觀天下是老師所住的公寓名稱。

Anonymous Anonymous9/02/2006 4:14 pm 說:

那個..真的很抱歉啦!!
因為..張氏兄弟沒有要去+捲毛好像也聯絡不到(應該說..很多人都連絡不到)
所以才會這樣的..
沒差啦...你就把我們都當作男生吧!
反正個性真的都漫像的嘛XD

<< 回到頁首

2006/08/24

瀏覽器多樣性

最近瀏覽器種類大增,拍照留念。

--
好吧,事實上我自己灌了 7 種 XD。

Anonymous Anonymous8/24/2006 1:08 pm 說:

你是禿頭嗎?
快上線...

Blogger yen38/24/2006 1:09 pm 說:

為什麼firefox是第二...嗚....我要第一啦

Blogger Celith8/24/2006 5:29 pm 說:

XD
唉..怪M$太強勢吧..

<< 回到頁首

Java Closures

從 ptt Java 板得來的連結。第一個念頭:太誇張了吧,Java 瘋了嗎 XD!這樣是能簡化語法沒錯,但感覺和 Java 整體的氣味實在不怎麼合呀。Java Generics 還算附屬於 OO 之下,如果 function types & closures 不只是 interface + anonymous inner class 的 syntactic sugar,Java 真的又離開 pure OO language 一步嘍。

這邊有些人在吵架 XD。(← 這篇文章已經反向連結回來了 XD。)裡面看到一個訊息:這大概是 JDK7 的東西,所以最後一句的情況或許還不用那麼擔心 XD。

感覺上大家都在往 higher-order programming 跑耶。Lisp & Haskell 不用說,Ruby 本來就內建,C++ 很幸運冒出一個 STL,Java 也有一點 idea 出現了 ─ 不過我真的看 Java 不太順眼,是成見嗎 XD?大概是因為目前 Java 的 functional paradigm 相當不發達的緣故吧。

--
現在最怕《The Java Programming Language, 5/e》閃電出版 XD。

Blogger Fall8/24/2006 12:31 pm 說:

在一堆英文之後 那末端的中文 看起來真是突兀XDD

Blogger Josh Ko8/24/2006 12:38 pm 說:

我覺得老外說不定看得懂 XD。

想想:

... Java ... Java ... Java ... Java Generics ... OO ... function types & closures ... interface + anonymous inner class ... syntactic sugar(到這裡可能有點感覺 XD)... Java ... pure OO language(這個也滿明顯 XD)... JDK7 ... higher-order programming ... Lisp & Haskell ... Ruby ... C++ ... STL ... Java ... idea ... Java ... Java ... functional paradigm(這段應該也猜得出來 XD)...

最後就 The Java Programming Language, 5/e 啦 XD。

Blogger yen38/24/2006 1:06 pm 說:

Java 是成為pure OO好還是不成為好...還是說Java 本身的定位在那?

Blogger yen38/24/2006 1:10 pm 說:

我回完文才多一行,5/e出版的話,沒差吧,中譯本要保持同步是很累滴

Blogger Josh Ko8/24/2006 6:27 pm 說:

我自己會有這樣的感覺應該是意識形態作祟 :P。大概類似「Java 把 generics 弄成 OO 的附屬品已經讓人(我)不怎麼舒服了,現在又想抄別人的 functional programming construct(說不定又變成 OO 附屬品),八成又要畫虎不成反類犬」之類的想法。目前沒有什麼學理上的佐證(大概也不打算弄)就是了。

<< 回到頁首

PageRank = 2

最近發現這個 blog 的 PageRank 竟然有 2!不過最近看起來要冷卻恢復常態了,趕快照一張留念 XD。

--
It's all meant to be? XD

Blogger yen38/24/2006 4:54 am 說:

看來頗屌,我可能是0...XD

Blogger Celith8/25/2006 3:16 am 說:

我大概也是0吧 XD
不過這要從哪看阿!?

Blogger Josh Ko8/25/2006 3:46 am 說:

安裝 Google toolbar 的話可以看到,有沒有其他方法就不知道了 :P。

<< 回到頁首

測不準原理推論

在「偽基」百科上看到這段令人捧腹之測不準原理推論(corollary):

在歷史上檯灣主權多次易手,頻繁到居民都搞不清楚自己是在那個政府的管暇下,最後檯灣教授引用量子力學的測不準原理提出了檯灣主權隨機論,也就是「當你知道檯灣的執政者是誰,你就不知道檯灣的主權是誰的;當你知道檯灣的主權是誰的,你就不知道檯灣的執政者是誰」,被美國 Un-Science 期刊稱為檯灣學術奇蹟。

--
這個 blog 很少提政治,可是這麼幽默的值得破一次例 XD。

Blogger yen38/24/2006 4:55 am 說:

哈哈哈,神秒的測不準原理,比美金玉良言.XD

<< 回到頁首

2006/08/23

杯水車薪

沒有,完全是成語誤用 XD。我本來還想下個 "Leibniz" 的標題然後說完全無關(事實上有東西能說完全無關嗎?),不過又說不太過去 XD。薪水正一筆筆匯入我的戶頭(因為 ATM 轉帳上限的關係),買書的日子不遠了。眾位好友,請客的日子也不遠了 XD。

--
要不要以此篇回應為請客名單依據呢?好邪惡的樣子 XD。

Blogger Fall8/23/2006 2:17 pm 說:

右!!!
--
我論這篇回應創新高的絕對性XD~

Anonymous Anonymous8/23/2006 2:38 pm 說:

請客請客請客!!!
嘿嘿嘿!!

Anonymous Anonymous8/23/2006 2:49 pm 說:

可以攜家帶眷嗎XD

Anonymous Anonymous8/23/2006 2:49 pm 說:

請客~請客~請客

Blogger yen38/23/2006 2:57 pm 說:

要記得請我喝一杯酒就好,其他則免了,酒也不要求,ice即可,不想要你太破費,畢竟領錢也是要省的

Blogger Thundermyth O.8/23/2006 3:10 pm 說:

> 薪水正一筆筆匯入我的戶頭

這「一筆筆」看起來似乎很多啊!保守估計應該超過3筆吧(3*30k=90k),可以再買壹台MAC BOOK PRO了... XD

> 要不要以此篇回應為請客名單依據呢?

噗... 真這樣的話我要去找「親友團」來回應了,開個壹百桌如何... XDD

Blogger Celith8/23/2006 3:15 pm 說:

酒阿.....
算了,我一杯果汁就行 XD

Blogger Josh Ko8/23/2006 4:48 pm 說:

報名截止,主攤名單已確定,小攤另定時間與模式 XD。

Blogger Thundermyth O.8/23/2006 5:03 pm 說:

啊?這麼快就報名截止啊,「親友團」還沒來耶 XDD

<< 回到頁首

競爭激烈

【從現代生物學看人類行為】共收 200 人,目前登記 252 人;【二李詞】共收 100 人,目前登記 253 人;所選的九門體育各約收 20 人,目前的登記人數都落於 108 到 176 閉區間之中。

--
難道這學期又選不上…

Blogger yen38/23/2006 3:10 pm 說:

請記得我的話
選課時切記"當仁不讓"

<< 回到頁首

2006/08/22

佳麗選秀

此處「佳麗」指的當然是藏書 XD。寄放於宿舍的有 19 本:

  1. 深度探索 C++ 物件模型
  2. Effective Java Programming Language Guide 中文版
  3. Practical Java Programming Language Guide 中文版
  4. Thinking in Java, 2/e 中文版
  5. UML Distilled, 3/e
  6. Concrete Mathematics, 2/e
  7. The LaTeX Companion, 2/e
  8. Design Patterns 於 Java 語言上的實習應用
  9. The C Programming Language, 2/e
  10. The LaTeX Graphics Companion
  11. Assembly Language for Intel-Based Computers, 4/e
  12. Concepts of Programming Languages, 7/e
  13. The Unified Modeling Language User Guide, 2/e
  14. Design Patterns
  15. 敏捷軟體開發 ─ 原則、樣式及實務
  16. Cross-Platform GUI Programming with wxWidgets
  17. C++ Primer, 3/e 中文版
  18. 精通 vi
  19. 重構 ─ 改善既有程式的設計

這樣帶個 2X 本上去應該還好。這就試列清單:

  1. The Art of Computer Programming Vol. 1: Fundamental Algorithms
  2. The Art of Computer Programming Vol. 2: Seminumerical Algorithms
  3. The Art of Computer Programming Vol. 3: Sorting and Searching
  4. Introduction to Algorithms, 2/e
  5. Computer Organization And Design: the Hardware/Software Interface, 3/e
  6. Programming Ruby: the Pragmatic Programmers' Guide, 2/e
  7. Programming Pearls, 2/e 中文版
  8. LaTeX: A Document Preparation System, 2/e
  9. C++ Primer, 4/e
  10. C++ Coding Standards
  11. C++ Template Metaprogramming
  12. STL 源碼剖析
  13. C++ Templates 全覽
  14. Effective C++, 3/e 中文版
  15. The Java Programming Language, 4/e
  16. Thinking in Java, 4/e
  17. 人月神話 20 週年紀念版
  18. 數學的發現趣談
  19. 數學拾貝
  20. 量子重力
  21. 帕洛瑪先生
  22. 蘇菲的世界(上)
  23. 蘇菲的世界(下)

學期中還可以把一些 OO 的書拿回家換。

--
其餘的就暫且打入冷宮 XD。

Blogger Fall8/23/2006 4:52 am 說:

我…無言

--
所以說學長是「皇帝」囉?!

Blogger yen38/23/2006 9:18 am 說:

算起來還是有42本...說真的,我也該來列列了..XD

<< 回到頁首

蓄勢待發

Sidebar "WishList" 區段新整理出 "About to Buy" 和 "NTU Library Entries" 兩個子區段,預計九月上台北後開學前執行。

--
該整理出要帶到台北的書籍清單了。

Blogger yen38/23/2006 3:12 pm 說:

我該是來申請館際合作了,這樣子我也能去台大圖書館借書啦...反正我還蠻常去台大的..XD

<< 回到頁首

打退堂鼓

經過一般斟酌,覺得還是放棄【倫理學】會比較有把握應付得來。雖然對相約同修的神有些抱歉,但總比敷衍了事、不負責任要來得好(這門課有相當份量的小組活動)。至於【高等微積分】,就算簽不到也要旁聽。

--
課表現在看起來讓人比較有信心。

Anonymous Anonymous8/24/2006 1:12 pm 說:

太可惡了,你果然是禿頭...

<< 回到頁首

先睹為快

《視計算機編程為一門藝術》(譯自《Computer Programming as an Art》)目前進度約 57%,摘錄一些有趣句子,供各位先睹為快 XD:

  • 單獨一門藝術的地基,常需要數門科學方能形成。這是人類事務的複雜性 ─ 欲使一件事情得以完成(done),常常需要理解(know)很多事情的本質和特性 … 一般而言,藝術由科學的事實組成,這些事實以「對於實踐最為方便的次序」安排,而非依照「對於思考最為方便的次序」。科學群聚並安排其事實,以讓我們從一個角度儘可能察看宇宙的一般秩序。藝術…結合科學領域中彼此最為疏遠的部份,以及關於「the production of the different and heterogeneous conditions necessary to each effect which the exigencies of practical life require」的事實。
  • 科學的優勢在於它使我們不需要透徹思考每個獨立案例;我們可以將思考轉向較高層次的概念。如 John Ruskin 在 1853 年所寫 [32]:「科學的工作是以事實替代表象,以論證替代印象。」
  • 在我看來,如果我所讀過的作者在當今寫作,他們會同意以下的特性描述:科學是我們透徹理解的知識,透徹到我們能將之教導給電腦;而如果我們未完全了解某件事,處理它便是門藝術。既然演算法或電腦程式的概念提供我們一個極為有用的測試,檢測我們對於任何給定主題的知識深度,從藝術到科學的過程就代表我們學會如何令某件事自動化(how to automate something)。
  • 我們所學關於編程的任何事情都將幫助我們增進本身的藝術技巧。在這層意義上,我們應該持續努力將每一門藝術轉型為科學:過程當中,我們也使藝術進展。
  • 我們的討論指出編程目前既是科學也是藝術,而且兩個面向巧妙地補足彼此。顯然大部分審視此問題的作者都得到同一個結論,他們的科目既是科學也是藝術,無論他們的科目為何(cf. [25])。
  • 然後我發現一本可愛的小書名為 The Gentle Art of Mathematics [31],這讓我有點傷心,因為我不能誠實地描述計算機編程為 "gentle art"(高貴的藝術)。
  • 在我提及的所有書籍中,Mueller 的書最接近於表述我今日談話想提出的中心主題,根據我們現今理解這個字的意義 ─ 真正的藝術技巧 ─ 詮釋此字。他觀察到:「一度人們認為藝術家的觀點對於科學家是致命之物。而科學的邏輯看似抹殺所有可能的藝術幻想力之飛馳。」他接著繼續探討科學和藝術的合成實際上所導出的優勢。
  • 當我談論「視計算機編程為一門藝術」時,我主要是將之視為一種藝術形式(art form),以美學的觀點視之。身為教育者和作者,我的書籍的主要目標是幫助人們學習如何撰寫優美的程式。正因為這個理由,我得知最近我的書籍真的出現在康乃爾大學的美術圖書館時 [32],感到特別高興。(然而,那三集顯然整潔地擺放在書架上而全無使用痕跡,所以我擔心圖書館員可能犯了錯誤,照字面意義詮釋書名。)
  • 我的感覺是,我們準備一個程式時,就如同創作詩篇或樂章;如 Andrei Ershov 所說 [9],編程能給予我們智慧上和感情上的滿足感,因為那是「駕馭複雜性」和「建立具有一致規則的系統」的真正成就。
  • 更甚者,當我們閱讀他人的程式,我們可以認出其中一些是真正的藝術創作(genuine works of art)。我仍記得 1958 年閱讀 Stan Poley 的 SOAP II 組合語言程式時的那股巨大興奮感;你或許認為我瘋了,而且自那時到現在風格也確實改變了很多,但當時那對我意義非凡,讓我見到一個系統程式能夠有多麼優雅(elegant),特別是和同時期我所研讀的其他拙劣程式碼相比。寫出優美程式的可能性(即使用的是組合語言)正是最先讓我一頭栽入編程的理由。
  • 有些程式優雅,有些精緻,有些閃耀著光芒。我的主張是,堂皇的程式、高貴的程式、真正壯麗的程式,都可以寫得出來!
  • 我的目的是傳達編程的良好品味和風格的重要性,(但)所呈現的特定風格要素只是用來展示一般能從「風格」獲得什麼好處。在這方面,我覺得類似於音樂學院裡教導創作的老師:他並非教導他的學生如何創作一部特定的交響曲,而必須幫助他的學生找到他們自己的風格,並向他們解釋那代表什麼。(一直是這個類比促使我談論「編程藝術」。)

以上全是未定稿,subject to change :P。

--
譯不出來的部份還請提供意見 XD。

《Computer Programming as an Art》

這是 Professor D.E. Knuth 在 1974 獲頒 ACM Turing Award 的演講全文。大一下學期我到台大圖書館借《The CRC Card Book》時,在《Literate Programming》裡面看到此文,深受感動。現在正試著翻譯全文,最晚應該明天能譯完(but no promise :P)。不過一樣未得授權不能散播,所以有意者一樣請私下索取,也一樣會有人被強迫做 peer review XD。目前有兩段三段難以翻譯,標示在下面,若有意見歡迎提供:

  • p. 668(PDF p.2)左上:His name: Art Evans. (The Art of Computer Programming, in person.)
  • p. 668(PDF p.2)右上引言:Art . . . brings together from parts of the field of science most remote from one another, the truths relating to the production of the different and heterogeneous conditions necessary to each effect which the exigencies of practical life require.
  • p. 670(PDF p.4)右下引言:There is no taste which deserves the epithet good, unless it be the taste for such employments which, to the pleasure actually produced by them, conjoin some contingent or future utility;

--
目前剛進入 PDF p.3。今日停在 PDF p.5 最起頭處。

Anonymous Anonymous8/22/2006 10:29 am 說:

一語雙關XD

<< 回到頁首

2006/08/21

否極泰來

《蕩到谷底》所述的雙重打擊在昨天全數銷融,心情愉快!唯一的隱憂剩下【高等微積分】能否加簽得到的問題,不過那也是 9/20 的事情了。好個否極泰來!

Never knew I could feel like this
It's like I've never seen the sky before
Want to vanish inside your kiss
Everyday I love you more and more
Listen to my heart, can you hear it sing
Telling me to give you everything
Seasons may change, winter to spring
But I love you until the end of time

Come what may
Come what may
I will love you until my dying day

Suddenly the world seems such a perfect place
Suddenly it moves with such a perfect grace
Suddenly my life doesn't seem such a waste
And it all revolves around you

And there's no mountain too high, no river too wide
Sing out this song and I'll be there by your side
Storm clouds may gather and stars may collide
But I love you until the end of time

Come what may
Come what may
I will love you

Suddenly the world seems such a perfect place

Come what may
Come what may
I will love you
Until my dy...ing... day...!!

--
這的確和戀愛沒什麼不同 ─ 繫結、投入、和盲目 :P。

Blogger yen38/22/2006 2:19 am 說:

沒談過戀愛請不要亂說話..XD

Anonymous Anonymous8/22/2006 5:06 am 說:

推 .... @@

Blogger Josh Ko8/22/2006 5:55 am 說:

本來就應該要到談戀愛的程度。
只是一般人根本就沒和他所研讀的科目戀愛,甚至把一般戀愛也弄得膚淺了。

<< 回到頁首

隨機大危機落幕

隨機客最後如此定案:

經過審慎思考, 加上P老師寶貴的建議, 「隨機客」決定還是維持原來週四週五兩個早上分兩班上課. 給大家造成困擾, 非常抱歉!

可憐的隨機客還是自己背起十字架了…。理想課表繞了一圈,最後還是回到原本面目(近似,因為把桌球往上移兩節)。

--
Sidebar 再度更新。

Blogger yen38/21/2006 5:29 pm 說:

所以事實上,三天過去,什麼事依賴如舊

--
人生就是比當歸大一點

<< 回到頁首

初選完畢

選課系統還真嚴,一堆都學號不符沒辦法選,包括:【高等微積分】、【自動機與形式語言】、【離散數學】。本來一進去系統,必帶四科要退三科,後來只退了必帶的單班【離散數學】以免影響體育。再來就是【二李詞】,選下去的瞬間給我伺服器的錯誤訊息 XD。【二李詞】晚上登入時,已經可以加選啦。所以最順利的狀況下,開學後要加簽四科。最擔心的是【高等微積分】,要是簽不到真的欲哭無淚:我為了它連【資料結構與演算法】都可以放棄耶。

整理一下:

  • 安全的課:計算機組織與組合語言、線性代數、資料結構與演算法。
  • 稍有風險的課:倫理學、公民教育、軍訓(可能靠加簽)。
  • 靠運氣的課:桌球 or 羽球、從現代生物學看人類行為、二李詞。
  • 要加簽的課:高等微積分、自動機與形式語言、離散數學。

對了,剛進系統時,本來即將退掉三科必帶,幸好想起這個 blog 的第一篇(the very first post)《Exception Safety 並非遙不可及》,先處理加選,否則還要費一番工夫 :P。

--
輔系、跨年級的課還要照學號來,真是 XD。

好像又完蛋了

心血來潮到 NTUCourse 板查離散數學陳建輝老師的評價,竟看到:

我覺得這門課好過是好過
但老師和助教的教學態度非常差
上課只會一直照著他投影片的內容唸下去
碰到投影片沒寫的 就說:這是個好問題 給同學當作習題好了
去問他 他也說不出個所以然來
完全學不到東西

以及

上課方面就是講投影片,講的很~~~慢~~~~,而且很少,上課內容完全不足以應付考試。還算是堪稱仔細與力求清楚;嗯,我說的是他「力求清楚」,可是我不覺得他真的把一些東西講的很清楚,在代數的部份還好,組合數學的部份也還ok,圖論就…不太能聽了,很多證明和定義,他都會想用自己的方式講給我們聽,然後還對教材的定義或證明發表他個人的一些批評,在我找出他的定義或證明的幾個錯之後,我圖論就再也不想聽他上課了。

另外這門課別稱離散與人生(好像很多課都會掛上人生),不得不說,他講的那些人生道理有些還滿有意思,甚至說的上是有用的,只是我還寧可他充實一下投影片的內容量,至少不要少課本太多嘛!

總而言之,離散數學的本身是很有趣,而且可以學到很多東西。陳教授嘛,我個人並不喜歡,但是教的真的很慢也許也是某些人喜歡的吧。

這…會不會太衰了點…。(電話先生的翻版?!)有推文曰:

→ showwind:老師的態度很差是真的.不過自學會學到很多
→ Engedi:需完全靠自學的話 就失去選這門課的意義了
→ Engedi:其實資訊系這種教授還挺多的...
推 twoWeek:醒醒吧..上大學就註定要自修了
→ twoWeek:不要再期待那些不會教書的教授了..^^b

如果真如上列評價所言,我大概又要發怒整學期 ─ 只不過這次是自己不熟的科目,恐怕無從發怒起。還有一段更讓我心寒:

推 Mr2:資工系的數學必修大都這樣
→ Mr2:還有用PowerPoint教數學的課
→ Mr2:btw 本系生想轉走大三就要趕快轉喔

不會吧…。不過,這學期另外兩門資訊系的數學課程(線性代數、自動機與形式語言)都是顏文明教授(顏老)開的,修過的人評價都不錯,希望還 OK。唉,離散數學靠自修(預習)吧。

--
至少還是有很多其他好課!:)

Blogger yen38/21/2006 3:06 am 說:

至少你還有好課可以上啦~這是真的,等到主修也是爛課的時候,你就知道有多痛苦了..orz

<< 回到頁首

2006/08/20

最後轉機!

哈!隨機客真是太聰明了!

現在看起來週五早上好像也找不到大教室,
如果必須要排在週六早上, 為了顧慮中南部同學返家的狀況, 可不可能
每次上四個小時, 然後每上三週就放一週, 這樣妥當嗎?

然後是選課開始前的最後結論:

明天就要選課了, 我想還是請大家按照原訂的週四週五兩班的時間選課,
我們開學第一個星期上課的時候, 我們可以討論一下調到週末或是晚上
的可能性, 如果真的行不通, 我們就還是維持兩班上課, 如果行得通,
我們就從第二個星期開始變成合班上課, 這樣好嗎?

不好意思給大家添麻煩了..

還是請大家繼續對於合班上課的可能性表達意見, 特別是

  (1) 週六上課, 然後每次上四小時, 每上三週放一週,

或者是

  (2) 每次上四個半小時, 每上兩週放一週,

「隨機客」都可以配合!

神妙提案!不僅能上到課,又能回家,「隨機客」又不會累垮!哈!Sidebar "Schedule (Fall 2006)" 已更新為最佳化課表!

--
只是週末開課反彈大概還是很大,「隨機客」大概真的得開兩班…。

Blogger Thundermyth O.8/20/2006 3:31 pm 說:

呵~ 恭喜你啊,終於能如願。

看來你這兩天的心情應該猶如在洗三溫暖吧!

Blogger Josh Ko8/20/2006 4:32 pm 說:

哈,謝啦 :P。

> 看來你這兩天的心情應該猶如在洗三溫暖吧!

就是這形容詞沒錯 XD。

Blogger yen38/20/2006 5:13 pm 說:

哈哈,恭喜啦

Blogger Celith8/21/2006 5:28 pm 說:

哇咧..
上二三週放一週阿..
感覺挺不錯的!

<< 回到頁首

感謝挫折 :)

Hi, Josh :

上星期剛結束 10 個大學的演講回來,從南到北。主要談的是輕鬆話題,非關技術。其中在心性修練上,我告訴同學們:"少年得志大不幸"。

人生不可能事事順遂,所以挫折在你還可以調整、還有能力承擔的時候,早些到來,是比較好的。沒有人會刻意追求挫折,所以如果一帆風順,我要恭喜你。這裡要勉勵你的是,當挫折到來,我們想想這些很棒的話,這些前人很棒的經驗,這樣就會生出健康的心態和抖擻的精神。心性的力量很大很大,而我們首先要有一個健康的心態。

這就是我要勉勵你的:感謝挫折。

將來你進入好大學,還會遇到來自全國最精英的年輕人一起競爭,還會遇上許多挫折。但是只要保持正面的、向上的心態,一切阻力都反而會成為動力。

--
侯 Sir 寫的 :)。


不過我還是覺得不要歹戲拖棚了,反正準備都做好了,快直接定案吧 XD。

--
還能糟過現在情況嗎?

The Show Must Go On

Sidebar "Schedule (Fall 2006)" 已更新。雖然得以選修相當吸引人的通識課程【中國人文精神之發展】,卻是用【資料結構與演算法】換來的,幾無歡愉之意。強烈希望隨機客把所有未全心投入的傢伙當掉(包括 ACM/ICPC 培訓班那門課)。

--
Another failed romance...


目前星期五計畫如此:第二節旁聽【資料結構與演算法】,然後把 iPod & iTalk 交給同學,三四節和中午上【高等微積分】時用 PB 錄音,之後取回 iPod & iTalk(或許找個修同一時段離散數學的同學),週末搭配隨機客的投影片聽完。麻煩的是,如果【高等微積分】座無虛席,拿 PB 出來錄音可能沒地方放。這時可能買個外接麥克風,才能把 PB 放在抽屜內。

--
靜靜等著發佈《K.O.》。打個難聽的比方,準備好棺材等死。

Blogger yen38/20/2006 11:39 am 說:

對不起,造成了你很多的麻煩呢,哈哈

人生不如意事十常八九,這不僅僅是對你,也是對我自己

Blogger Josh Ko8/20/2006 12:23 pm 說:

什麼話,幫了我很多忙 :)。

<< 回到頁首

盪到谷底

現在心情差透了。看來註定要放棄【資料結構與演算法】,頂多星期五早上去聽一節,然後剩下兩節請同學幫忙錄音。這樣當然是旁聽,明年還得正式修一次,不過這門課不先自己設法讀起來的話,麻煩比旁聽的麻煩還麻煩。然後又做了個超怪的夢,和現實對照之下,沈重的雙重打擊。

「遊客」所提的情況我確實沒考慮到。不過很抱歉,我暫時沒辦法繼續想下去,得等心情好一點吧。

I was a fool to believe...
A fool to believe...
It all ends today...
Yes, it all ends today

Today's the day when dreaming ends

Another hero. Another mindless crime.
Behind the curtain, in the pantomime.
On and on
Does anybody know
What we are living for
Whatever happens
We leave it all to chance
Another heartache
Another failed romance
On and on
Does anybody know
What we are living for

The show must go on
The show must go on
Outside the dawn is breaking
On the stage that holds
Our final destiny
The show must go on
The show must go on

Inside my heart is breaking
My makeup may be flaking
But my smile still stays on

The show must go on
The show must go on

I'll top the bill
I'll earn the kill
I have to find the will to carry
On with the
On with the
On with the show

On with the SHOW!
On with the SHOW!

The show must
The show must... go... on...!

--
隨機客 bye-bye。

Blogger yen38/20/2006 11:37 am 說:

別那麼傷心啦

<< 回到頁首

2006/08/19

偏離軌道

這暑假的首要目標,本來好像是精通 Ruby 耶,結果一堆文章都是 C++0x XD。

--
可是也回不了頭啦 XD。

Blogger yen38/19/2006 6:20 pm 說:

計畫趕不上變化...我也好多事沒做啊...T___T
不過意外的是,我學了Word排版(挺),還有想了許許多多的事,還意外收了一個直屬學妹...XD

<< 回到頁首

swap using Concepts

延續從《HasSwap》到《Concepts vs. Type Traits (vs. Reflection)》的討論,我擔心的事情果然成真:後面一篇文章所提的 template overloading 會形成歧義(ambiguity)。以下使用 N2042 所述的語法和語意(也就是 ConceptGCC 所實作的 concept system),建議搭配該篇 paper 閱讀本篇(因為這篇是非常典型的跳躍式邏輯 XD)。

auto concept MemberSwappable<typename T> {
  void T::swap(T&);
};

上述宣告引進一個新的 concept MemberSwappable,此類型別必須擁有一個 member function swap,signature 如 concept declaration 所示。ConceptGCC 使用偏向 pseudo-signature 的 concept 表述方式,但應該只是為了實作方便,pseudo-signature vs. usage pattern 的討論應該還沒定案。auto 代表這個 concept 採用 implicit model,省略的話,欲匹配這個 concept 的型別必須用 concept_map 明確宣稱。

Standard library 已經預先定義了 Swappable concept。我們可以用 concept map template 表述「所有為 MemberSwappable 的型別 T 都為 Swappable」:

template <MemberSwappable T>  // for every MemberSwappable T
concept_map Swappable<T> {
  void swap(T& a, T& b) { a.swap(b); }
};

如上述程式碼所示,使用 concept map 時可以把 concept 所要求的語法(e.g., non-member swap)對映到實際型別的操作(e.g., member swap)。這很像 OOP 的 virtual functions,例如:

template <Swappable T>
void f(T& a, T& b) {
  swap(a, b);
}

T 單純是個 Swappable,那麼會喚起 Swappable 所指定的 non-member swap;但若 T 是個 MemberSwappable,則 Swappable 所指定的 non-member 呼叫語法(i.e.,介面)會被轉換為 MemberSwappable 所指定的 member 呼叫語法(i.e.,實作):行為正與 virtual functions 類似。

故事還沒完。事實上,到此編譯器會抱怨 "ambiguous class template instantiation for 'concept std::Swappable<Test>' ",因為在 concept-enabled STL 中,std::swap 乃如此定義:

template <typename T>
  where Assignable<T> && CopyConstructible<T> {
inline void swap(T& a, T& b) {
  T tmp = a;
  a = b;
  b = tmp;
}

template <typename T>
  where Assignable<T> && CopyConstructible<T>
concept_map Swappable<T> { };

因為 STL 為所有「既為 Assignable 又為 CopyConstructible」的型別提供了 non-member swap,所以用 concept map template 宣稱「所有AssignableCopyConstructible 的型別均為 Swappable」很合理。但這在定義 f、實施 concept-checking 而試圖(自動)檢驗 Test 是否為 Swappable 時,卻發生麻煩:編譯器不知道應該把 Test 歸類為 Assignable && CopyConstructible 還是 MemberSwappable(而不知道該喚起 std::swap 還是 Test::swap)!

我試著解釋目前我理解(猜測)的內幕:auto concepts 事實上是由編譯器暗自產出 concept maps,然後所有操作再根據 concept maps 進行(無論是由編譯器暗自產出的還是使用者明確宣告的)。兩個 concept maps 所指明的關係如下面這個集合圖所示:

而且左右側兩個子集所對應的實際操作不同,所以匹配時必須獨一無二地讓型別落在其中一個子集內。如果,例如,把 Test 的 copy ctor 放在 private 區段,使 T 不為 CopyConstructible,那麼對 f 的呼叫就會成功,喚起 Test::swap。但現在 Test 剛好位於兩個子集的交集內,無法判斷從通用介面呼叫時,要的是哪個子集所定義的操作。喔,這不正是惡名昭彰的鑽石型多重繼承的 compile-time version 嗎?!真是糟糕啊,感覺上沒有比較好的一般解決方案。

--
一篇文章還沒看完就忍不住了 XD。

Anonymous Anonymous8/19/2006 6:19 pm 說:

還有一個疑問, 不知道算不算問題?

f 說它要 Swappable, 而身為 Swappable
的人必須用 concept_map 說 "Yes, I am"

但 MemberSwappable 說只要你有 T::swap
那麼你就是 MemberSwappable

問題來了, 某個人有 T::swap 但沒有說它是
Swappable, 但結果它確實會是 Swappable
所以它可以呼叫 f, f 或許不會納悶, 但是
T 自己不覺得奇怪嗎?

Blogger Josh Ko8/19/2006 6:51 pm 說:

好問題!這感覺上和 concept 的(新)本質有關,我一時難以直接推導或類推。

我先把那堆 papers 看完好了,看看有沒有解答或得到一點 insight :)。

Anonymous Anonymous8/19/2006 7:45 pm 說:

在下想到 function template overloading
又要增添新成員, 實在是滿恐怖的一件事!!

這個讓人說法不一個例子:
http://phpfi.com/142595

以前 VC 跟 g++ 持不同意見, 現在不知怎樣
還有更複雜的例子, 通常應該會讓 cpper 放棄跟 overloading 搏鬥 =.=+

Blogger Josh Ko8/19/2006 8:09 pm 說:

哈,同意 :)。

我在去年 12 月一篇 blog 裡面寫了一些初探 C++0x 的感想,其中像

「程式語言從 typeless B/BCPL 走到 typed C,算是一個極大的 evolution。而現在 C++ 即將演化出 type of types,又是一次 evolution。」

這句已經值得商榷。而另一句

「多了一個層級出來,不僅新層級裡面的東西要處理好,新舊層級間的互動也要注意。例如以後 function template overloading 可能就要同時考慮 template-parameter-based overloading 和 function-parameter-based overloading,不知道會產生什麼樣的 overload resolution rules 出來。」

就如你所言 :)。現在光 plain function overloading 和 function templates 兩者個別出現,程式員就有點招架不住(讓我想到《C++ Primer》每次都被抓住裡面的 overload resolution 部份當作它很難讀的證據 XD),兩者結合起來真的很嚇人 :P。

把 N2036 ~ N2042 全印出來了。這種東西當睡前讀物最好 :P。

Blogger Josh Ko8/19/2006 9:03 pm 說:

我自己的問題先解決了 :P。太急著發文,往下多看一段就知道該怎麼做了 XD。

我們現有兩個 concept maps,分別對映到圖中兩個子集,同具兩邊陣營特性的型別會搖擺不定,不知該倒向哪邊好(該使用哪個 concept map)。

解法事實上很簡單:只要再造出第三個陣營(即中間那個交集部份)就行:

template <typename T>
  where MemberSwappable<T> && Assignable<T> && CopyConstructible<T>
concept_map Swappable<T> {
  void swap(T& a, T& b) { a.swap(b); }
};

如此兼具兩邊特性的型別就有家可歸了。

這樣的東西似乎就沒辦法和 OOP 平行類推了?

Blogger Josh Ko8/19/2006 10:51 pm 說:

睡不著,試著提出一些解釋 XD。

剛剛看 N2042 後面的規格部份,p.23 提到

"Whenever a constrained template is used, there must be a concept map corresponding to each concept-id requirement in the where clause."

並在 p.16 說

"a concept with a preceding auto specifier is an implicit concept. When a concept map is required for an implicit concept but no concept map can be found through concept map lookup, it shall be implicitly generated."

所以一個 type 能否與一個 concept 匹配(whether a type matches a concept),取決於能否找到那個 type 與那個 concept 之間的 concept map ─ auto concepts 只是特例而已。(有 concept map 存在 ==> 這個 type 就匹配那個 concept)

當一個 concept 為 explicit concept 時(即未受 auto 修飾),這個 concept 需要由 type 那邊明確寫出 concept map 宣稱匹配。所以若 Swappable 為 explicit concept,則僅具有「可通過型別檢查的 non-member swap」尚且不足,還必須由 type 那邊明確宣稱(語意符合)才行,如先前所討論。而 implicit concept 就代表「只要語法符合,就保證語意符合」,所以編譯器型別檢驗通過後,就直接產出 concept map。(implicit concept ==> [語法符合 ==> 產出 concept map(因為語意也符合)])

當我們寫下一個 concept map 時,我們就明確宣稱這個 type 匹配那個 concept。同理,當我們寫下 concept map template 時,我們是明確宣稱一整族的 types 都匹配那個 concept。所以在此處,所有 MemberSwappable 的 types 都被「明確」宣稱為 Swappable,而沒違反「Swappable 要求明確宣稱」的規則 ─ 我們確實明確提供了所求的 concept maps。

也就是說,當我們寫下「宣稱所有 MemberSwappable types 都是 Swappable」的 concept map template 時,意思就是「只要是 MemberSwappable types 就必然匹配 Swappable(連同語意考慮在內)」,因為寫出 concept map 就一併保證語意符合,而我們的確寫出了。

而 MemberSwappable 的匹配條件就寬鬆一點,因為 MemberSwappable 是個 implicit concept,所以保證只要語法符合語意就符合。全部合起來,只要 T 具有 member swap,就一定(在語法、語意上)匹配 Swappable。

主要關鍵應該在於,我們寫出 implicit concept 時,就代表保證「語法符合時語意亦符合」,而非「不考慮語意」。

基本上我還滿喜歡這樣的設計:explicit & implicit concepts 並存 :)。

--
寫到後來覺得自己在寫天書,一堆 Swappable、concept map,快混淆在一塊了 XD。

Anonymous Anonymous8/20/2006 4:20 am 說:

> 這樣的東西似乎就沒辦法和 OOP 平行類推了?

好像是這樣耶!!

這樣可以自己決定要用哪一個成品; 如果是一般
的多重繼承, 應該是語言會決定一個採用順序

像 Python 有什麼 __mro__ 好像滿複雜的
而 Ruby 的 mixin 也跟它的 include 順序有關

一個是自己決定, 一個是語言決定 (但使用者要學習認知)

Anonymous Anonymous8/20/2006 4:45 am 說:

之前的疑問癥結是:

某 T 有 T::swap 就是 MemberSwappable
而後又明確宣稱 MemberSwappable 就是 Swappable

所以光看 f 的 prototype, 我以為要一個
explicit Swappable, 但是因為我有 T::swap
所以我隱然 (implicit) 是一個 Swappable
甚至我連 MemberSwappable 這個 concept
的存在也不知道, 就發生了


看起來滿像這個: Conversion Sequences =.=+

猶記得那一串吧?
standard conversion -> user-defined conversion -> standard conversion

不知道它有否限制轉換次數, 還是說這個問題在 concept 中有等於沒有? 某 T 有 A 的特徵, A 說他是 B, B 說他是 C, 所以 T 是 C


其實, 只要小心使用, 就沒有問題 =.=+

Blogger Josh Ko8/20/2006 12:35 pm 說:

我剛剛想試 namespace 能否解決問題,但因為 concept map 必須和所對映的 concept 處於同一個 namespace 裡面,似乎沒輒。至於「限制轉換次數」的問題,我覺得應該是以 concept map 的存在與否為準。

這種從客戶端觀之全然無異,但語意可能突然改變的情況,似乎在 C++98 裡面就有了?(例如,private section 裡面加個較為匹配的 member function 重載版本。)如果依照現況,恐怕真的只能「小心使用」了吧 :P。

Anonymous Anonymous8/20/2006 1:04 pm 說:

之前我有無意間看到你回那篇, 我覺得那篇所
說的應該沒錯! 不過不知為何突然砍掉了?

以語法來說, 它這樣設計個人覺得算滿優的 ^^

Blogger Josh Ko8/20/2006 1:13 pm 說:

哎呀,我以為我刪得夠快了 XD。

我本來在實驗時,以為我的觀點正確。可是後來一想不對,又發現實驗裡少了個 const 而導致不正確結果(以及不正確推論),所以趕緊刪了那篇 XD。

想用 namespace 控制這問題,前提是 concept maps 必須能定義於任意 namespace,才不會在使用者未引用那個 namespace 時流瀉出去。不過這前提目前不成立 :)。

Anonymous Anonymous8/20/2006 1:25 pm 說:

哦, 原來如此 :-D

(歹勢,事情就是那麼巧。)

<< 回到頁首

ConceptGCC

今天才偶然發現,我從來沒看過 WG21 六月的 mailing list 全部內容,都只看到其中的 N2011 "State of C++ Evolution" XD。目前正在讀 N2042 "Concepts" by D. Gregor & B. Stroustrup,裡面提到一個實作品 ConceptGCC ─ 實作品耶!迫不及待立刻下載試用,網站上剛好提供了 Mac OS X 10.4 PPC 的 binary 檔案,省下不少麻煩。ConceptGCC 還只是 alpha version,最顯而易見的缺陷是:慢到爆炸 XD。第一次編譯時,我還以為餵檔失敗,看著 manual 的一句 "It provides the same behavior as GCC's g++ compiler driver" 百思不得其解 XD。

我寫了這樣的程式碼,觀察 concept system 面對錯誤的反應:

#include <algorithm>
#include <iterator>
#include <iostream>

using namespace std;

int main() {
  copy(0, 5, ostream_iterator<int>(cout, " "));
}

ConceptGCC 給我的錯誤訊息是:

test.cpp: In function 'int main()':
test.cpp:8: error: no matching function for call to 'copy(int, int, std::ostream
_iterator<int, char, std::char_traits<char> >)'
/opt/conceptgcc-4.1.1-alpha-3/lib/gcc/powerpc-apple-darwin8.6.0/4.1.1/../../../.
./include/c++/4.1.1/bits/stl_algobase.h:405: note: candidates are: _OutputIterat
or std::copy(_InputIterator, _InputIterator, _OutputIterator) [with _InputIterat
or = int, _OutputIterator = std::ostream_iterator<int, char, std::char_traits<ch
ar> >] <where clause>
test.cpp:8: note:   no concept map for requirement 'std::InputIterator<int>'
test.cpp:8: error: invalid use of undefined type 'concept std::IteratorAssociate
dTypes<int>'
/opt/conceptgcc-4.1.1-alpha-3/lib/gcc/powerpc-apple-darwin8.6.0/4.1.1/../../../.
./include/c++/4.1.1/bits/iterator_concepts.h:65: error: declaration of 'concept 
std::IteratorAssociatedTypes<int>'

下列則是一般 g++ 所產出的錯誤訊息:

/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h: In instantiation of 'std::iterator_traits<int>'
:
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_algobase.h:309:   instantiated from '_OI std::__copy_aux(_II, _II, _OI
) [with _II = int, _OI = std::ostream_iterator<int, char, std::char_traits<char>
 >]'
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_algobase.h:326:   instantiated from 'static _OI std::__copy_normal<<an
onymous>, <anonymous> >::copy_n(_II, _II, _OI) [with _II = int, _OI = std::ostre
am_iterator<int, char, std::char_traits<char> >, bool <anonymous> = false, bool 
<anonymous> = false]'
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_algobase.h:387:   instantiated from '_OutputIterator std::copy(_InputI
terator, _InputIterator, _OutputIterator) [with _InputIterator = int, _OutputIte
rator = std::ostream_iterator<int, char, std::char_traits<char> >]'
test.cpp:8:   instantiated from here
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h:129: error: 'int' is not a class, struct, or uni
on type
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h:130: error: 'int' is not a class, struct, or uni
on type
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h:131: error: 'int' is not a class, struct, or uni
on type
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h:132: error: 'int' is not a class, struct, or uni
on type
/usr/local/lib/gcc/powerpc-apple-darwin8.6.0/4.1.0/../../../../include/c++/4.1.0
/bits/stl_iterator_base_types.h:133: error: 'int' is not a class, struct, or uni
on type

相較之下,ConceptGCC 的錯誤訊息明確程度有滿大改進(主要是長目錄名稱在亂)。其餘功能等我看完 papers 再貼心得(今天大概沒辦法)XD。

--
預計先看完 N2027, N2036 ~ N2042。

Blogger yen38/19/2006 6:23 pm 說:

相較之下,原本的訊息是很難以理解的,不過....似乎,學習C++的人觀念還要更好才行,從以前的型別錯誤改改就行,現在可能要學習更多,才能知道自己錯在那裡,未必不是一件好事。

<< 回到頁首

多數暴力

完蛋了,隨機客竟然要投票表決星期四或星期五了 Orz。超暴力的手段 Orz。

--
我要修金次高微和演算法啦!Orz


看來大局有點底定了…雖然目前表決文的推文內,星期四的票數微微領先,但卻有「和雙班計算機組織完全衝堂」的因素在,這比「星期四票數微微領先星期五」的影響大得太多了。現在恐怕只能等「隨機客」給予致命的一擊…T.T。

--
難道上一個 session 最後的吶喊終將無功嗎…?Orz


有轉機!有轉機了 T.T!

「隨機客」很樂意配合大家的時間, 不過想當然爾是牽一髮而動全身..

如果乾脆改到星期六早上會不會引起眾怒?

週間晚上其實也可以

就這麼辦!避開二四晚上,都好!避不開也沒關係,不要撞到高微,一切都好調!

--
神哪,助我一臂之力!

Blogger yen38/19/2006 9:06 am 說:

幫你推了

Blogger Josh Ko8/19/2006 9:51 am 說:

實在沒辦法,弄到這地步簡直是拚個你死我活 Orz。

Blogger yen38/19/2006 11:26 am 說:

如果是禮拜六早上或者是禮拜日晚上...都會間接影響到回,但是....對你而言應該沒差..(你不常回家)XD

<< 回到頁首

狹義相對論筆記

繼微積分之後,剛剛完成普通物理學筆記的掃描。放上狹義相對論的六頁筆記為證 XD。

       

       

--
到底能不能同時修【高等微積分】和【資料結構與演算法】呢?Orz

Blogger yen38/19/2006 9:06 am 說:

第一頁怎麼那麼多黑點啊..?

Blogger Josh Ko8/19/2006 9:51 am 說:

湮滅塗鴉證據 XD。

Blogger Celith8/19/2006 1:15 pm 說:

哇咧..
沒想到這麼亂 XD

<< 回到頁首

2006/08/18

隨機大危機!@@

「隨機客」教授竟然在第一階段選課蓄勢待發的前夕說

請問..

如果「隨機客」把原先打算開在週四和週五早上兩班的「資料結構與演算法(上)」 合成一個大班, 會不會引起一陣大混亂?

「隨機客」想替ACM/ICPC程式競賽培訓班的同學開一門課. 但是又覺得一學期開 三門課太辛苦..

熱心的 yen3 幫我推文,「隨機客」竟然回覆曰

→ yen3:可能會引起一陣混亂,很多同學課表都排好了....
→ yen3:若有雙主修或輔系的同學,則課表更難以變動...
→ yen3:所以...真的要好好考慮這個問題
→ hil:「隨機客」是好好考慮之後才覺得應該合成一班 :)

一副大勢已定的樣子!天啊!如果併到五 234 或其他硬科目的時段,那就等於要痛苦地二擇一了 Orz。【高等微積分】和【資料結構與演算法】二擇一?讓我死了吧 Orz。

--
會瘋掉啦我的天!T.T

--
有種人為刀俎我為魚肉的感覺…。

Blogger yen38/19/2006 9:07 am 說:

這...我只是好心而己,熱心談不上啦...Orz

<< 回到頁首

iTalk 復出

今天用 iTalk 錄 Mov. 1 中段。因為就放在鋼琴旁邊,高音全部爆出雜音,幾無倖免,不過低音聽起來竟滑潤如高級鋼琴之音色。錄音器材之影響實在大得驚人。

--
話說光這七天的留言數就超過七月整個月了 XD。

Blogger yen38/19/2006 9:08 am 說:

新功能有好處
為什麼高低音會差那麼多,還是說...? italk只適合錄低音的嗎?

<< 回到頁首

World Wide Web

來自 "Taiwan" 以外國家的訪客也出現了,而且國別還不只兩三個 :P。應該滿多是從 Blogger NavBar 連過來的。

才發完文,又多出三個國家 XD。

--
好個萬維網!

Blogger yen38/18/2006 8:52 am 說:

其他國人怎麼看懂你的blog的? 只看英文?
改天來試試跳ip再來參觀你這裡看會發生什麼情形..XD

Blogger Josh Ko8/18/2006 10:36 am 說:

所以 visit lengths 大都不超過 5 秒 XD。

<< 回到頁首

歡迎下載 Archive Pages

歡迎各位下載 archive pages 留念 :P。改版過程中,我一直朝著「讓 archive pages 自給自足」的目標修改,所以 archive pages 的意見直接放在各篇之下,sidebar 基本上不會隨時間更動,且 sidebar 的連結都指向那一頁 archive page 的 bookmarks。下載後有一個地方可能要修改:我用 Firefox(不知 Windows Firefox 有沒有同樣問題)以「完整封裝」模式下載,"Monthly Statistics" 的內容重複了兩次。解決方法是打開文字編輯器,搜尋第二個 "Monthly Statistics",然後刪去 <ul style="margin: 0.5em 0pt 0pt;"> 之後的

 1: <script>
 2: 
 3: n_days = last_day.getDate();
 4: 
 5: document.write('<li><font color="#258">' + n_days...
 6: document.write('<li>每日平均張貼...
 7: document.write('<li>每日平均回應...
 8: document.write('<li>每篇平均回應...
 9: if (commenters.length > 0) {
10:   document.write('<li><p>回應次數排名:</p>');
11:   commenters.sort(function (a, b) {...
12:   var current_rank = 0;
13:   var prev = 65536;
14:   for(i = 0; i < commenters.length; ++i) {
15:     if (commenters[i][1].length < prev) {
16:       ++current_rank;
17:       prev = commenters[i][1].length;
18:     }
19:     document.write('<p>' + (current_rank == 1 ?...
20:     document.write('<span class="hiddensection"...
21:     commenters[i][1].sort(function (a, b) {...
22:     for(var j = 0; j < commenters[i][1].length; ++j) {
23:       document.write('<li><a href='...
24:     }
25:     document.write('<li><a href="javascript:toggle...
26:     document.write('</ul></span></p>');
27:   }
28:   document.write('</li>');
29: }
30: </script>

和後面的

1: <noscript>
2: <li>這個部份必須啟用 JavaScript 方能瀏覽 :)。</li>
3: </noscript>

這兩段即可。想下載其他頁面當然也歡迎,不過 main page 和 item pages 都是設計為反映現狀(尤其是 main page),沒像 archive pages 經特別設計為自給自足。

--
這主要當然也是為了自己方便 :P。

Blogger yen38/18/2006 8:56 am 說:

沒寫過Java Script 果然看不太懂
正在猜其中的意思中

ps.這種功能適合大的blog

Blogger Josh Ko8/18/2006 10:18 am 說:

沒用到什麼功能呀,只有變數(dynamically-typed)、迴圈、Array、Date、還有 "document.write" 而已。

Blogger Thundermyth O.8/18/2006 11:19 am 說:

> 讓 archive pages 自給自足

嗯? 什麼時候的事??
有學我的嫌疑喔!

(我來亂的 XDD)

<< 回到頁首

2006/08/17

Sidebar Quick Links

就在 main page 和 archive pages 的右上角,方便快速跳到 sidebar 的某一區段。與 CSS 的浮動性質奮戰許久,最後束手無策時靈光一現,輕鬆解決困惑許久的問題。

這個暑假還真是把整個 blog 大大翻修了一遍,強迫學了些(複習)CSS 和 JavaScript :P。

--
說「不會再有新功能」都是假的 XD。

--
為了保持一致(for consistency),item pages 也加入 sidebar quick links。

Blogger Josh Ko8/17/2006 10:04 pm 說:

3.14 這不就回來了嗎 XD。(這次沒破壞了喔 XD。)

Blogger Fall8/18/2006 2:49 am 說:

我在想能夠撐多久XD

Blogger yen38/18/2006 8:48 am 說:

不久了,等我回完文,還有,說不新增功能,結果現在整個blog滿是功能

不過,有新功能比較好..XD

<< 回到頁首

Blogger in Beta

看起來不錯呢,不過和其他 Google 服務一樣,目前只有少量試用名額。我特別注意到的功能有:

  • Dynamic Serving:現在的 Blogger 是靜態網頁,有新內容必須重新發佈。而新的 Blogger 會隨需動態生成網頁,完全不用重新發佈。
  • Display posts in reverse, or non-chronological order:這個功能是在 wishlist 看到的,在我看來是非常重要的功能 :P。Archive pages 哪有人用 top-posting 的啦!XD
  • Access Control:這是某 T 的祕密網誌亟需的功能 XD。
  • Labels:這是某 C 的網誌想加入的功能 XD。

http://beta.blogger.com 好像可以直接註冊新帳號了(新的 Blogger 是用 Google Account),不過目前似乎沒有 porting 的服務,只好慢慢等啦。

--
把 179 篇 blog posts 手工搬過去可不是什麼小工程。

Blogger yen38/18/2006 8:47 am 說:

我暫時不想再搬家了,搬一次家,流失一次客源,這邊好不容易才熱鬧起來,你要三思啊

Blogger Josh Ko8/18/2006 10:20 am 說:

呵,我沒打算搬家 :P。時機成熟時 Blogger 會有平滑(smooth)的搬遷方案吧。

Blogger Thundermyth O.8/18/2006 11:24 am 說:

嗯? 是這樣嗎?

應該是經過測試後的功能會加入原來 blogger 服務裡面吧,我不太相信 google 會搞出要"搬遷"才能用新功能這種麻煩事

Blogger Josh Ko8/18/2006 12:11 pm 說:

Blogger 用的是 "switch" 這個字,大概是得把現行 Blogger 帳號轉移到 Google Account 才能用的關係吧。

<< 回到頁首

流量統計分析 & 反向連結

昨天凌晨啟用 StatCounter.com 的免費流量統計分析服務,並悄悄把連結放在 "Recent (Monthly) Statistics" 最後。昨天共有 166 次 pageloads(不包括我自己:我為 PB 的 Firefox、Safari 和 PC 的 Firefox、IE7 都植入 blocking cookie,不會被統計在內),33 位 first-time visitors(以 cookie 為判定基礎),有點超乎我的預料 :P。抓取到的資訊詳細得有點可怕,最慘重的災情當屬某 T(XD)的非公開 blog 也被抓了出來(幸好這個 blog 剛好要換網址 XD),在此懺悔一下 XD。

另外也啟用 Blogger 的反向連結功能。和流量統計分析相比,這個功能算溫和一些。不過感覺上搜尋不是很有效(effective),還沒看到哪篇文章有反向連結(而我確定應該會有幾個:因為是我自己放在別的 blog 上的 XD)。

--
不會有人因此不光顧了吧?XD

--
看來作為反向連結基礎的 Blog Search 不會搜尋意見,所以「我放在別人 blog 上的連結」都不算數 XD。

Blogger yen38/18/2006 8:53 am 說:

我從來沒連過(挺)
不過....你的blog功能真是越來越完備了

<< 回到頁首

輔修數學系獲准

好極,第一步總算成功了,再來就得應付有點複雜的選課。感覺和去年申請上資訊系一樣,很快樂(因為科系的關係):)。往數學系取經去啦!

--
幸好沒被刷掉 XD。

--
忘了恭喜神(數學輔系)和為晋(電機輔系)!

Blogger yen38/17/2006 6:46 am 說:

恭喜啊,期待有更精采的表現

Blogger Thundermyth O.8/17/2006 11:32 am 說:

恭喜啊!
以後艱難的數學就靠你了 XDD

Blogger Josh Ko8/17/2006 12:20 pm 說:

艱難數學 XD ─ 我是抱著被當的決心修高微的 XD。

Anonymous Anonymous8/17/2006 1:33 pm 說:

恭喜囉~

期待你在數學系也能擁有自己的一片天唷^^

Blogger Fall8/17/2006 2:07 pm 說:

看來投幣娃娃系統準備要更新了 ( ̄□ ̄|||)a

Blogger Celith8/17/2006 2:55 pm 說:

哇咧~
那數學也可以問你啦 XD

雖然有在考慮要修輔系
但還是先看看狀況..
更何況,我還不知要修哪個輔系..

Blogger Josh Ko8/17/2006 5:50 pm 說:

> 期待你在數學系也能擁有自己的一片天唷^^

呵,謝謝 :)。這麼說感覺好像轉到數學系一樣 XD。

> 看來投幣娃娃系統準備要更新了 ( ̄□ ̄|||)a

看不懂 XD。

> 那數學也可以問你啦 XD

完全無法保證答得出來 XD,不過歡迎討論 :P。

Anonymous Anonymous8/18/2006 2:56 pm 說:

筆記記得抄整齊點

Anonymous Anonymous8/18/2006 4:19 pm 說:

嘖嘖,一定沒有看微積分成績XD

<< 回到頁首

2006/08/16

Taylor 定理筆記

微積分筆記掃描和大一上學期的索引已經完成,轉換為 PDF 後大小 47.5MB。放上偉大 Taylor 定理的四頁筆記為證。當天的讚嘆請見 external link。

   

--
侯 Sir 的字真好看!XD

Anonymous Anonymous8/17/2006 1:01 am 說:

They're Back.
Turbos inspired a generation to program
- they're back to do it again!

http://www.turboexplorer.com/

有興趣就看看吧XD
說實在的,莫名的一股熱血上來

Blogger Fall8/17/2006 1:06 am 說:

決定還是申請帳號來po文好了 省的把記分板給炸了XD

Blogger skusi8/17/2006 4:02 am 說:

微積分筆記喔
聽起來是我很需要的東西(泣)

Blogger Josh Ko8/17/2006 6:13 am 說:

你可以帶光碟來我家燒筆記檔和錄音檔啊 XD。

Blogger Josh Ko8/17/2006 6:15 am 說:

> 省的把記分板給炸了XD

你故意的嗎?XD
有點符合惡搞的定義了 XD。

Blogger Josh Ko8/18/2006 5:56 am 說:

Turbo C++ 已非吳下阿蒙嘍。

"Turbo C++ contains support for the industry standard ANSI C and ISO/ANSI C++ languages and libaries. Turbo C++ also includes the Dinkumware C++ runtime libraries and support for the popular Boost library."(應該寫 Boost libraries 比較恰當。)

Blogger Fall8/18/2006 1:48 pm 說:

那確實也是重點之一:p

<< 回到頁首

海若無涯天作岸

「海若無涯天作岸,山到窮頂我為峯」。去年考上台大資訊,兌現與侯 Sir 的約定,到侯 Sir 家拜訪(詳情請見 external link)。下面就是侯 Sir 在《STL 源碼剖析》上的簽名。

然後是當天往新竹的車票,背面有侯 Sir 簽名,經護貝後作書籤(或護身符 XD)使用。

--
有圖有真相!XD

Blogger Fall8/17/2006 2:42 am 說:

你說!閃光可以這樣一放再放嗎?
但是別怕我已經戴好墨鏡了-■■-

Blogger Celith8/18/2006 3:04 am 說:

XD

Blogger yen38/18/2006 8:57 am 說:

老實說...我覺得Josh的字比較好看怎麼辦..XD

<< 回到頁首

阿基米得的估算

剛剛無意間在 "Recent Statistics" 裡面看到一個熟悉數字:

沒錯,3.14,那不就是國小(還是國中?)所用的圓周率近似值嗎?今天凌晨略讀聰明的《數學拾貝》,正好在 p.67 看到阿基米得(Archimedes)估算 π 的不等式:

而右側那個「3 又 1/7」(22/7)正好就是「張貼 22 篇」除以「7 日」。真巧!

--
不過貼了這一篇後就消失了 XD。

Anonymous Anonymous8/16/2006 9:38 am 說:

兇手!!(指)

Blogger yen38/16/2006 11:40 am 說:

誰叫你破壞的.Orz

<< 回到頁首

SCX-4200 到手

所以數位化計劃第一部份要啟動了!目標:至少把一年微積分筆記解決(讀高微才方便)。

--
明天輔系就要放榜嘍。

Blogger yen38/16/2006 5:20 am 說:

加油啊...期待你的成果....
也希望那些檔案對你能夠有所幫助~^^

Blogger Josh Ko8/16/2006 5:41 am 說:

幫助可大得很呢(雖然要低調 XD),謝啦 :)。

Blogger yen38/16/2006 11:47 am 說:

附帶一提,你的wish list中的scx-4200該去掉了,都買到了..XD

<< 回到頁首

2006/08/15

回應「遊客」意見

(因為太長了,張貼在正文看起來比較舒服。)

精闢見解!

《The Java Programming Language, 4/e》以 "contract"(契約)的概念貫串全書。作者在 p.41 如此描述:

一個常見的假設是,class 宣告的函式就是 class 的完整契約。函式語意也是契約的一部份,即使它們可能只描述於文件內。兩個函式可能擁有相同的名稱和參數,並擲出相同的異常(JK 注:即 signature 相同),但如果它們的語意不同,兩者就不等同

因此當程式員用 interface construct 描述一個介面(一份契約)時,語意也是其中非常重要的一部份,即使那可能無法在語言內表現。JavaPL4e 在 p.125 介紹擴充(或實作)多個「帶有同名函式」的 interfaces 時,就舉了一個滿有趣(但不知道實不實際)的例子。

當然, 這樣泛用性, 就小了一點點 ..

嗯,現行 C++ GP 的模式下,"entity --- concept --- entity" 兩兩之間皆不相依(e.g. std::sort --- RandomAccessIterator --- std::vector<int>::iterator),而 OOP 的 "entity --- interface --- entity" 兩兩之間仍有相依關係(e.g. java.util.Collections.sort --- java.util.List<T> --- java.util.ArrayList<T>)。前一種模式便引發「有相同的操作介面者, 不一定皆符合特定領域的語義」的問題,因為「符合契約與否」並非由 rhs entity 自己明確宣稱(which is much easier and can be more certain),而是從 concept 那一端檢驗,但既有的語言沒辦法闡明「語意」供 concept-checking mechanism 檢驗,所以「從 concept 那一端檢驗」有麻煩。

C++0x 的 concept system 多以 STL 為例,我也用 STL 的組件為例比較清楚。目前的 concept system 提案確定會把 "algorithm --- concept" 這一段(以及 concept 本身)明確表示出來,而 "concept --- data structures (incl. iterators, containers, ...)" 這段則有兩種提案(ref. N1799 p.29 ~ 42):一種是不指明(implicit model declarations),一種是明確宣告模塑關係(explicit model declarations,也就是讓我憂心的提議)。倘若指明了,那又和 OOP 的模式有何不同?只是從 "programming to the interface" 變成 "programming to the concept",並從執行期變成編譯期而已。所以我在《Collected Papers of Alex Stepanov》裡面說 "compile-time object-oriented programming"。在現行 C++ GP 模式下,兩側的 entities 可以獨立發展又能無隙組合(thus "generic")。如果最後走到 explicit model decl.,C++ concept 大概就真的變成 Java interface 的 compile-time counterpart,而減少 C++ GP 的泛用性;但若採用 implicit model decl.,又不能檢驗語意。實在是兩難哪!

不過還有一種可能 ─ 我的論證方向(i.e. 抽象化)錯誤。OOP 那邊因為讀了《Object-Oriented Analysis and Design with Applications, 2/e》所以比較清楚,而 GP 這邊的基礎相較不穩。所以我希望能「見到 generic programming 的本質」:)。

--
「遊客」真是神祕耶 XD。

Anonymous Anonymous8/16/2006 3:26 am 說:

讚, 你作學問真的很踏實!!

那就是我想的說, 沒想到書中都有寫了 ><
有沒有其他解法, 自己也不懂, 且覺得
再思考下去, 好像有點不切實際.

像 Haskell 的作法應是 explicit model
它用 declare (Eq a where ..) 來讓資料
跟某個 type class 產生關聯, 並賦予行為
但他的模型較特別, 資料與行為天生是分離的

不過就如你所說, 這樣跟 OOP 有什麼差別?
也因此, 雖然 Java 它們的「泛型」綁介面
讓很多人說, 泛型也不泛型了! 後來我覺得
其實這很重要嗎? 這只是純粹不純粹的問題!
除非你選擇 implicit model

(好啦, 還有一個問題: 一個 construct 的概念被 overloading 了. 是福是禍, 端看語言設計者的選擇. Ruby 說 multi-way; Python 說 one-way 各有各的想法)


不過話說回來, metaprogramming 這東西
C++ 要跟 Ruby 比真是相形見拙; 但我還是
滿喜歡 C++ 的, 畢竟最熟悉 XD

(只是 C++ 的發展已非我所能想像 ...)

Blogger Josh Ko8/16/2006 4:53 am 說:

天啊,你簡直說到我心坎裡!:D 例如

> 覺得再思考下去, 好像有點不切實際

這句 :P。發完文後我又想了想,採用 implicit model 所獲得的泛用性是否必要,還是得以實際使用模式為依歸,不是這樣單純抽象論述一番就可以解決,而「實務經驗」正是我所欠缺的。像 Grady Booch 在學理和實務都有深厚素養和經驗,他的論述才這麼具說服力(at least to me)。

> metaprogramming 這東西
> C++ 要跟 Ruby 比真是相形見拙

沒錯,Ruby 那靈活程度真是嚇死人 :P。我最感到震撼的就是 Singleton pattern 的實現手法:一行 require 'singleton' 再一行 include Singleton 就完了,乾淨又優雅!

> 但我還是滿喜歡 C++ 的, 畢竟最熟悉 XD

天啊,又說到我心坎裡!:D

以後歡迎多多討論 :)。

<< 回到頁首

發表是最好的記憶

先摘錄侯 Sir《發表是最好的記憶》的第一段(因為侯 Sir 的繁體網站銷聲匿跡好一陣子了,摘錄於此,方便各位看倌):

●發表是最好的記憶

這話是胡適先生說的。

一直以來想用一句簡單的話來說明自己的寫作動機、寫作態度、寫作方向。可嘆書讀得不多,辭窮!前些日子看到這個句子,覺得胡適這句話真是道盡我的寫作旨趣。

可以說,侯捷書寫,為了自己。

寫的東西有人看,因而得以支撐自己的生活,是件重要的事(否則就該改行了)。 寫的東西有人愛看,並且從中獲得幫助,更是樂事一件。

我在寫作過程中獲得了沉澱、學習、與成長,心得則以我最喜歡的方式與成份整理下來。說方式嘛,必須自己看了不厭不愧,喜悅自在;說成份嘛,必須足夠我日後回頭檢閱時有足夠的飽足與方便。

通常,能夠讓自己滿意的,也能夠讓別人滿意。自己想吃的麵,絕對不會放餿水油。 沒有什麼比又幫助別人又幫助自己,再好的事了。

有人用像片寫日記,侯捷以發表做記憶。對技術書籍的寫作態度是如此,對雜文的寫作態度亦是如此;有酬的如此,無酬的亦是如此。

因為與讀者互動的緣故,寫作帶給我的人生一種全新的境遇與感動,也使我在觀察事物的敏銳度和學習度上更加積極,同時也讓我得到了成為一個公眾人物之後必須具備的容忍功夫。原本只寫技術性的東西,慢慢地發現自己能寫、想寫,於是決定以寫作來完成記憶,包括技術面的、思想面的、人生瑣事面的。

早些年雜文發表在電腦雜誌上,不但成為一份精美的印刷成品,還有稿費可拿。後來接觸網路,愈來愈無法忍受一篇文章完成後一、兩個月才發表的漫漫等待,遂漸漸將文章全部發表在網路上,只揀自認為最重要的、非關私人趣味的文章才轉投雜誌。有時做了轉投的打算,時候一到人一懶,又縮了手(雜誌文章的版面非我所能控制,這一點常澆熄我的轉投意願)。

總之,「發表是最好的記憶」這句話幾乎可以總括侯捷的寫作動機。在方式與成份上,我不為取悅任何人,只為取悅我自己。在閱讀的舒適度和順暢度上,我願意同時取悅自己以及任何我所設定的讀者。

這個功利社會中,若有人願意做點無酬的事,用心很是難得。所以每當我在網路上看到一些很用心的、長長的、有組織的文章,或是一些出沒於網路上為人排憂解難的熱心朋友,我就有很大的敬意。我相信他們也以「發表是最好的記憶」潛意識來做這樣的事情。網路上的 Weipo、william、Gauss、watts、dyliu、AlbertB、QueenLin、ctang、davidko、wolfgang、xshadow、Tomm… 以及一下子沒想起來的其他一些未曾謀面的朋友,都贏得了我的敬意。我相信,這些朋友因為曾經做過相同的事情,更能夠以同理心來看待或體會技術主題內寫作的困難,以及冰冷環境中熱忱的可貴。

我在大一下口述歷史報告《先生之風,山高水長 ─ 一位足列典範的華文電腦技術作家》之中這麼寫:「侯老師秉持『發表是最好的記憶』的原則,將絕大多數散文、重要討論串、眾多讀者去信都放在侯捷網站上,整個網站概略瀏覽一遍,就能對侯老師的形象以及主要歷史有梗概的認識。」自去年三月撰寫 blog 至今,自己也相當程度地體認(並贊同)這句話。

我常喜歡把一個概念(或一個事件或一段歷史或…)想作是一張網子:你很難支手托起整面網子(很難用語言精確完整地描述一個概念),大都是抓起網子的某些點(語言僅能片段地描述概念),將整面網子懸吊在空中(傳達或習得概念的全貌,和英文的 "pick up" 一詞有暗通之處)。因此,能不能完整傳達一個概念,端視能不能「抓到重點」或「夠不夠詳細」(抓起足夠多的點)。

我的 blog 到上了大學以後,發文漸趨頻繁,大概就是受「抓起足夠多的點」這想法驅使。雖然有些較隱諱的部份我沒怎麼描述,但大部份的大學生活與思考,我都已寫在 blog 裡面。可以說,我希望這個 blog 能夠將我這個人的形象表現出來,如同侯捷網站傳達侯捷其人的形象一樣。每一篇 blog 都是一個 snapshot,多個 snapshots 積分起來,就是成長歷程的近似,愈密集誤差就愈小。

沒觀眾雖然無大礙,但若有觀眾能分享(甚至參與,e.g. 透過留言)我的成長歷程,更好。眾位朋友,感謝你們的留言,有相當不小的支持力量 :)。

這個 blog 裡面常常寫我的事,卻似乎很少寫關於這個 blog 本身的事,就把此文獻給這個 blog 吧 :)。許個願:希望這個 blog 能持續寫下去(按照「發表是最好記憶」的理念),並希望能持續有觀眾參與 :)。

--
感謝各位!:P

Anonymous Anonymous8/16/2006 3:57 am 說:

我只希望侯捷先生的書快點出!!
(加上這篇, 就躍升第二名了 XD)

Blogger Josh Ko8/16/2006 4:56 am 說:

這大概是所有讀者的共同心聲(吶喊)吧 XD。

Blogger Celith8/16/2006 5:10 am 說:

呵~發表的文章有人看的確是種樂事..

不過..
Josh Ko 提到...

這大概是所有讀者的共同心聲(吶喊)吧 XD。

是這樣嗎? XD

Blogger Josh Ko8/16/2006 5:15 am 說:

邏輯上無誤啊,「大概」是推測語氣 :P。

Blogger yen38/16/2006 5:19 am 說:

留言變多是從設計新功能開始的
不管如何,發表是一種最能省視自己的方式,blog的文章,我經過許多次思考,決定還是述說自己的想法,當然,偶爾發個牢騷是好的,一個blog只是流於型式,在記述所生的事,意義是不大的,能夠述說自己的想法,每天所學到的事物,這對我而言就是一個100分的blog

但是Josh的blog,我未必是每篇看的懂^^

Blogger Josh Ko8/16/2006 6:11 am 說:

> 留言變多是從設計新功能開始的

連我自己感覺上都變得比較愛留言 XD。

如同「發表」,增進這個 blog 的瀏覽便利程度和統計一些數據,主要都是為了自己方便 ─ 希望順便帶給各位觀眾方便 :)。

> 但是Josh的blog,我未必是每篇看的懂^^

技術方面,大部分是有新知或新領會,或沉澱出有趣的東西,才會貼上來。有時候只是重點式地概述留著給自己參考,細節、過程就沒怎麼提,旁觀者大概很難跟上這種跳躍式邏輯 :P。

Anonymous Anonymous8/16/2006 9:37 am 說:

那…不介意的話,我可以去貴班版幫忙宣傳XD

Blogger Celith8/16/2006 3:52 pm 說:

呵~
發表自己的想法與看法阿
不過,這東西挺抽象的
有時候不好表達

<< 回到頁首

Concepts vs. Type Traits (vs. Reflection)

我在《HasSwap》一文裡面試著以 HasSwap type-trait class 改寫 std::swap,並在最後提到「Type traits 基本上可算是 compile-time reflection 吧」。無獨有偶,C++0x proposal N1775《A Case for Reflection》亦在 "3 How we use reflection - 3.2 Algorithm Tailoring" 提到類似應用:

Among the most common use cases is the desire to take advantage, in generic code, of a specific client class’s features. If a class provides, say, a member sort(), a generic algorithm is typically better off to call it rather than std::sort(), for instances of that class. While numerous coding practices have been proposed to handle such a scenario, none has achieved widespread acceptance, and some have even (with some justification) been labeled “arcane.”

正好呼應我的說法。(Reflection in C++ 目前的狀態是 "not ready for C++0x, but encourage work to continue",所以應該不會出現在 C++0x 之中。)然後我又想到:concepts 不也是一種描述型別特徵的方式嗎?以 Stroustrup et al. 所提議的 usage pattern 表述的話(C++0x proposal N1782, N1886, ...):

concept Swappable<typename T> {
  Var<T> t;  // 若單純寫 "T t;",會被詮釋為「T 為 default-constructible」
  Var<T> u;
  t.swap(u);
};

(或許還得加上一些「喚起 swap 後,tu 的值互換」之類的語意描述,不過我不知道 concept system 能不能(應不應該)這麼做。)然後再透過 template overloading:

namespace std {
  template <CopyConstructible && Assignable T>
  void swap(T& a, T& b) {
    T temp(a);
    a = b;
    b = temp;
  }

  template <Swappable T>
  void swap(T& a, T& b) {
    a.swap(b);
  }
}

就可完成在 C++03 必須以「一個攜帶型別資訊的額外參數」和「函式重載」實施的 dispatch。看看 TR1 裡面的 type-trait classes,判斷的都是一些比較本質上的型別特性,例如 is_integral, is_array, has_trivial_copy, has_nothrow_assign,乃至於二元的 is_convertible, is_base_of,相較於 concept 描述型別行為("usage pattern" 很清楚指出這個性質),兩者的著重點不太相同,看來很難用哪一邊取代另一邊。在 HasSwap 的情形,concept 會是比較好的解決方案,因為我們要的東西的確是那種「使用模式」,用 concept 表述相當自然(至於「語意的描述不夠完整」這個問題,不只 concept system 遇到麻煩,Design by Contract 也遇到相同問題),而《HasSwap》最後也提到用 trait class 實作的缺陷。

--
可以試著實作 TR1 "4 Metaprogramming and type traits" 的所有內容,練習 TMP 技巧。不過有些可能要從編譯器層級直接支援?

Anonymous Anonymous8/15/2006 6:53 pm 說:

嗯, 語意問題, 初淺看來, 像是選擇問題!

就好像動態語言跟靜態語言之差, 差在一個彈
性大, 一個語意安全!

像 C#/Java 那種需要 implements 式的語
法, 對 Python 之類的語言來說, 是多此一舉

但我覺得這也是它高明之處, 就因為需要 implements 所以彈性較小, 但也因此留
給實作者一個決定語意的空間

有相同的操作介面者, 不一定皆符合特定領域
的語義, 如果它們真的是可通用的概念, 就請
implements 來確定, 算是另一種選擇方案

當然, 這樣泛用性, 就小了一點點 ..

Anonymous Anonymous8/15/2006 7:02 pm 說:

boost 有一個 concept_check library
用來模擬 concept 的支援, 其實 gcc 裡
面的 STL 似乎有用到: function_reuqires<>

雖然做法不難理解, 不過再怎麼說也比不上
直接支援來的簡單 XD

<< 回到頁首

Collected Papers of Alex Stepanov

以前好像也曾發現這個網站,但當時似乎還不完整。第一篇就來《Operators and Algebraic Structures》,然後裡面一堆 group、semigroup、abelian group,真可惜這學年修不到代數導論。(離散數學應該也有一點點,不過就真的只是「離散的一點點」XD。)

又看了一些 C++0x concept system 的東西,突然覺得憂心忡忡 ─ 其中一種 proposal 感覺上正把 C++ generic programming 引導到 compile-time object-oriented programming。如果該種 proposal 勝出而且我的擔憂是正確的,C++ GP 大概會完蛋。前面那項條件還未知,而後面那項條件成立與否,就得看我能不能見到 generic programming 的本質了。

--
Stepanov 的網站已新增到 sidebar 的 "Links - People" 區段。

Blogger yen38/15/2006 1:55 pm 說:

感覺上有走回頭路的感覺,好不容易獨立出來的東西,為什麼又要搞回去呢...Orz

反正一切未定論,繼續看吧

Anonymous Anonymous8/15/2006 2:19 pm 說:

GP 跟 OOP 不是殊途同歸?

Blogger Josh Ko8/15/2006 2:54 pm 說:

分解問題的方法似乎不太一樣。(現在還說不出個確切所以然 XD。)

<< 回到頁首

2006/08/14

Boundary Case 測試

測試看看回應排名有兩個第一名時,顯示是否正確。

--
事實上是想搶第一名的位置 XD。

--
測試結果如右,一切正常。(XD)

Blogger Josh Ko8/14/2006 12:57 pm 說:

測試方式當然是回應此篇 XD。

Blogger skusi8/14/2006 3:18 pm 說:

我該說啥
不然就說...

軒五其實還不錯啦

Anonymous Anonymous8/14/2006 3:31 pm 說:

幫你測試~= =+
錦源好帥~...

Blogger yen38/15/2006 1:51 pm 說:

看來這個月的第一名是josh啦啦啦啦,沒事換帳號也是有好事的

<< 回到頁首

建議使用

Sidebar 的 "Powered by Blogger" 圖示之後多了幾個新夥伴,分別代表建議使用 Mac、Firefox、Safari。Firefox 和 Safari 直接抓 Mac 應用程式的 .icns 檔轉存,就是背景完美透明化的 .png 檔,而 Mac(Finder)的圖示一時在 PB 內找不到,直接上 Google 也抓得到 .icns 檔。Mac 圖示擺第一,當然是因為「只要在 Mac 上看,什麼都好看」的緣故 XD。

  

--
要買筆電的一定要考慮一下 MacBook 啊!

Anonymous Anonymous8/14/2006 6:43 am 說:

沒錢拉!沒錢拉! (打滾~

Blogger Thundermyth O.8/14/2006 6:59 am 說:

在沒看到價錢時一定會考慮,精品級的..

但是看到價錢後,唉~ 只能乖乖的買一般的NB

Blogger Josh Ko8/14/2006 7:12 am 說:

MacBook 現在的價錢也算公道啊(要是非 MacBook Pro 不買又另當別論 XD)。而且 Intel-based Mac 可以 Mac OS X / Windows 兩棲,不習慣或有需要的時候儘可切換回 Windows,多划算 XD。

Anonymous Anonymous8/14/2006 9:26 am 說:

沒錢拉!沒錢拉! +1

Blogger Josh Ko8/14/2006 10:31 am 說:

哈,好久沒留言的也出現了 :)。

--
留言數有機會超越藍色叢林了 XD。

Blogger Thundermyth O.8/14/2006 10:40 am 說:

>> MacBook 現在的價錢也算公道啊(要是非 MacBook Pro 不買又另當別論 XD)

不是吧,比一般NB貴了約1萬耶(將近30%)

Blogger Josh Ko8/14/2006 10:51 am 說:

可是功能比較多、比較有質感 ─ 所以我說價錢「公道」而非「便宜」嘛 XD。

Blogger yen38/15/2006 1:49 pm 說:

MacBook 等Intel和Mac整合的更好再說吧,雖然大部分的程式尚可執行,但是photoshop還是不行,大概可以看出PowerMac為什麼還沒有換Intel CPU的原因了

當然還是有好處,PC上要灌Mac的機率高了不少,實用性大嗎?老實說,這是爽度問題

<< 回到頁首

可收展留言清單

昨天才說「應該不需要其他功能」,今日就為 sidebar 裡面 "Recent (All) Posts" 、"Recent Comments" 和「回應排名」加上可收展的留言清單。其中 "Recent Comments" 仿用了 Mac OS X 10.4 Tiger 的 Spotlight 的用詞。短期內「應該」不會再有新增功能了吧。

--
整個 template 已經有點 dirty 了 XD。

Blogger yen38/15/2006 1:47 pm 說:

你的短期是多短啊,不過說真的,新增了好多功能啊

<< 回到頁首

2006/08/13

Boundary Case

剛剛把 "Recent Comments" 區段改為至多顯示 10 項,並慫恿眾位好友「到此一遊」,不料 yen3 卻持續霸佔第一個位置,不肯讓位給明明更為 "recent" 的意見。於是發現,原來我把 12:\d\d AM 想成 00:\d\d AM,以致於排序時出了差錯。現已修正。

--
這個事例告訴我們 boundary test case 的重要性 XD。

--
"Anonymous" 步步進逼我的排名 XD。

Anonymous Anonymous8/14/2006 6:39 am 說:

我好像就貢獻了三次 (逃~~

Blogger yen38/15/2006 2:03 pm 說:

Josh不要害我啊..想說換個名字繼續低調的說

<< 回到頁首

訂購 SCX-4200

一個小時前,隨口向我媽借到錢(沒辦法,老闆那邊沒消息 XD),已經訂了 Samsung SCX-4200。按照 PC home 的速度,兩三天左右會送達吧。然後就是瘋狂實施數位化計畫第一部份啦 XD。

--
微積分筆記是大重點。

Blogger yen38/13/2006 5:46 pm 說:

真是令人期待,我的動物也動的很讓人期待呢...真高興這次有幫上忙

<< 回到頁首

Monthly Statistics

Archive pages 內的 sidebar 新增 "Monthly Statistics" 區段。六月的回應第一名是我喔 XD,而七月的第一名簡直神妙無比。至此除了「讓 archive pages 依時間先後排列」之外,應該不需要其他功能了。但這最後一項功能牽涉 Blogger 和 JavaScript 整合的一個嚴重本質性問題,目前我沒有解決辦法。事實上,各位客倌現在就可以利用這問題搞爛我的 blog XD。我現在沒辦法從技術層面預防,所以只好學學 P 老師的「秋後算帳系統」 ─ 要是有人蓄意破壞,一律殺無赦 XD。

--
第一道防線就是 ─ 不講明問題是什麼 XD。

Blogger yen38/13/2006 5:08 pm 說:

而七月的第一名簡直神妙無比。
這句話是什麼意思... .___. /
這年頭當第一名都那麼歹命嗎...(泣)
放心,知道問題,我也不會這樣子做的.. 嘿嘿

<< 回到頁首

Recent Statistics

右側 sidebar 再新增一個 "Recent Statistics" 區段,其中「回應次數排名」第一名會被特別標示出來喔(「Joshsoft 之友」?)XD。

--
這有沒有「鼓勵回應」的效果呢? XD

Blogger yen38/13/2006 11:21 am 說:

鼓勵回應.XD
我是第一名耶~(挻)

Anonymous Anonymous8/13/2006 11:29 am 說:

人數最多的, 應該是我們遊客集團!!

Blogger Josh Ko8/13/2006 11:39 am 說:

> 人數最多的, 應該是我們遊客集團!!

要回應才算數 XD。

Anonymous Anonymous8/13/2006 2:15 pm 說:

香香到此一遊。

Anonymous Anonymous8/13/2006 4:50 pm 說:

Elroy到此一遊

Anonymous Anonymous8/13/2006 4:51 pm 說:

Charlie愛死你了

Anonymous Anonymous8/13/2006 5:16 pm 說:

...誰用我的名義亂留言...

Blogger Josh Ko8/13/2006 5:30 pm 說:

這篇果然特別熱門 XD。

Blogger yen38/13/2006 5:45 pm 說:

換個名字繼續留言.XD

Anonymous Anonymous8/13/2006 6:06 pm 說:

上來徵求暴肝戰友!! XD~

Anonymous Anonymous8/13/2006 6:07 pm 說:

8月份 好像還沒留言過耶 汗顏~

Anonymous Anonymous8/13/2006 6:08 pm 說:

遊客?!

Anonymous Anonymous8/13/2006 6:09 pm 說:

八月份好像都好像沒有回覆過 = =""

Blogger Celith8/14/2006 2:56 am 說:

....
我也來湊ㄧ腳

Blogger Celith8/14/2006 2:59 am 說:

剛看了一下原始碼..
只能說...強大..
改天來研究研究@@

Blogger Josh Ko8/14/2006 3:29 am 說:

事實上這應該只有國中程度,因為沒什麼 abstraction,全部都是 hard-coded(e.g. 資料結構除了 Array 還是 Array;named function 僅有一個)XD。

這篇的意見數量猶如幫我做高壓測試一般 XD,感謝各位 :)。

<< 回到頁首

2006/08/12

數位化計畫

目前有兩個:

  1. 以 SCX-4200 將大一所有筆記掃描為圖檔,並製作簡單文字索引。
  2. 蒐集所有 CS 相關書籍的目錄和索引(PDF or plain text file)。

--
老闆好像忙到爆炸了,還沒回信 ==> SCX-4200 還不能入手 XD。

--
剛剛著手進行第二項,結果第一本 TC++PL 馬上碰壁 ─ 沒有 index 的檔案。難不成真的得買比 SCX-4200 還貴的掃描筆嗎 XD。

--
不對不對,SCX-4200 好像有 OCR,只不過這麼做下去是大工程哪。幸好 JavaPL4e 有電子檔,不然索引一百多頁會掃描到死 XD。

Blogger yen38/12/2006 4:26 pm 說:

TC++PL 的index
我有....(小聲)
我去家族旅遊三天,你竟還沒收到信.Orz

<< 回到頁首

Swatch

父母自瑞士歸來,帶給我一隻錶,還滿不錯的 :)。錶的長相請見 external link。

Blogger yen38/12/2006 4:24 pm 說:

皮的錶帶耶~小心遇到水...我的也是swatch的,不過是舊款嘍,對了,你要不要考慮換個鋼錶帶,會比較方便行動喔

Blogger Josh Ko8/13/2006 7:51 am 說:

我媽也問我相同問題 XD。
一來懶得換,二來覺得皮質看起來比較舒服。

<< 回到頁首

小試 FP in Ruby

def mem_fun(mf)
  lambda {|obj, *args| obj.method(mf.to_s).call(*args)}
end

給予此函式一個函式名稱字串或 Symbol,就可以把 member function call 的形式轉換為 plain function call(當然,Ruby 所謂的 plain function 其實也是 member function)。不過相較於 C++ 的 member function adaptor,Ruby 是在執行期以 reflection 喚起那個函式,較為動態但間接層數較多,而不像 C++ 經最佳化後效能幾乎無損(也比較僵硬)。舉個使用例子:

plus = mem_fun(:+)
plus.call("abc", "def")  # --> "abcdef"

lambda 所接收的 block 參數列內的 *args 功能相當於 C++ 或 Java 1.5 的 "..." 參數,傳入的剩餘引數會被打包成一個 array(即 args),因為 Ruby array 是異質(heterogenous)容器,這個設計運作良好。而 block 主體內的 *args 則反其道而行,將 args array 打散為個別引數。lambda 本身的作用在上一篇文章已經提過,是將其後隨附的 block 轉換為可呼叫的 Proc object。因此整體效果是將 mem_fun(:mf).call(obj, arg1, arg2, arg3, other arguments) 轉換為 obj.mf(arg1, arg2, arg3, other arguments)

接著試寫 bind,將一個 Proc object 的某些引數綁定為特定變數或固定值。例如:

bind(plus, :_1, "def").call("abc")  # --> "abcdef"
bind(plus, "def", :_1).call("abc")  # --> "defabc"
bind(plus, :_2, :_1).call("abc", "def")  # --> "defabc"

在那之前,我們先寫 adapt,把傳遞給 p 的引數全部先經另一個 unary_p 處理後才真正傳入。

def adapt(p, unary_proc)
  lambda do |*args|
    p.call(*args.collect {|x| unary_proc.call(x)})
  end
end

接著 bind 就很好寫了:

def bind(p, *a)
  lambda do |*args|
    adapt(p, lambda do |x|
               x.class == Symbol && x.to_s =~ /_(\d+)/ ?
                 args[$1.to_i - 1] : x
             end).call(*a)
  end
end

接著我們可以試寫函式合成(function composition)。或許風格不佳,我把語法設計為 f + g,如此造出的 function object 將先喚起 f,然後把結果再傳入 g+ 運算子必須定義為 class Proc 的 member,而 Ruby 正允許我們這麼做:

class Proc  # reopen class Proc
  def + (unary_p)
    lambda {|*args| unary_p.call(self.call(*args))}
  end
end

用法如:

g = plus + lambda {|x| puts x}
g.call("abc", "def")  # prints "abcdef"

當然,以上程式碼全部都是「泛型」(generic)的 ─ Ruby 是個動態型別語言,靜態型別語言所講的「泛型」對它沒有意義。

不過,實用上似乎不太需要這些 higher-order functions,因為 Ruby 的 block 機制本身就相當好用了。而且效率也是問題,每次經過一個 higher-order function,就得負擔 *args 的打包、拆散成本,closures 的時間、空間花費,以及 Ruby 本身的函式呼叫也算昂貴。因此寫這些函式純粹只是好玩而已 XD。

--
好想要 C++ lambda expressions XD。

Anonymous Anonymous8/15/2006 10:36 am 說:

講到泛型, 目前還是覺得 Haskell 那種較純
道地的 generic + constraint

但是很抽象就是了, Monads 遊客到現在還搞
不懂

Blogger Josh Ko8/15/2006 12:54 pm 說:

嗯,的確,目前「感覺上」泛型和 functional programming 血緣關係比較近(所以「同步率」較高 XD)。為了把「感覺上」三字去掉(或換成較具確定性的詞彙) ─ 輔修數學系(17 日放榜)!

雖然僅只接觸很淺顯的範例,Haskell(and pure functional programming)感覺上真的很有趣呢 :)。

Anonymous Anonymous8/15/2006 1:16 pm 說:

不過 Haskell 是 static typing 喔 ^^

只是它有 type inference, 而且在真正
需要 constraint 的場合中,「感覺上」說
來跟跟靜態語言也不是差很多!

不過這是了解不深的說法, 呵呵, 有待繼續
學習~

<< 回到頁首

2006/08/11

Lambda Expressions in C++0x

Lambda expressions 指的是在使用地點即時定義、建立 function objects(or functions)的式子。在 functional programming languages 裡面,函式是第一級(first-class)物件,且大量使用 higher-order functions(接收其他函式作為引數的函式),此類能力直是天經地義。例如 Common Lisp 這麼寫:

(lambda (x) (+ x 1))  ; 定義一個 function,接收一個引數 x,回返 x + 1 的值

Haskell 這麼寫

\x -> x + 1  -- 定義一個 function,接收一個引數 x,回返 x + 1 的值

Ruby 少用迴圈而大量使用 blocks,意義與 lambda expressions 幾乎相同:

(1..5).each {|x| puts x + 1}  # 將 1 到 5 間的每個數傳入隨附於呼叫的 block 之內,
                              # 對於每個傳入的 x,印出 x + 1 的值                            

如果要產生第一級(first-class)的 blocks,也可使用 Kernel.lambda 將 block 轉換為 Proc object:

lambda {|x| x + 1}  # 產出一個 Proc object,接收一個引數 x,回返 x + 1 的值

JavaScript 的語法也很直覺:

function (x) { return x + 1; }  // 定義一個 function,接收一個引數 x,回返 x + 1 的值

Java 雖然語法囉唆且必須和 interface(or (abstract) classes)一同使用,但也透過 anonymous inner classes 支援此事:

interface Int2Int {
  int apply(int x);
}

// ...

new Int2Int() {
  int apply(int x) {
    return x + 1;
  }
}  // 至此生成一個實作 Int2Int interface 的 object

C++ 面對示例裡這種簡單的 function objects 仍遊刃有餘:

bind2nd(plus<int>(), 1)  // 造出一個 function object,接收 x 回返 x + 1

但相較於上列語言,這個奠基於 library 的機制顯然不夠一般化,意義也不那麼明顯。Boost Lambda Library 的效果不錯:

_1 + 1  // 造出一個 function object,接收一個數(作為第一引數),回返那個數加 1

但內部所用的 expression template 技巧需要較長編譯時間,而且有所侷限。(詳見 proposal N1968 Sec. 1.1, p.2)因此,C++0x 很可能內建 lambda expressions,這將大大鼓勵 standard library algorithms 的使用。

目前(如 proposal N1968 所述)提議的語法像這樣:

<> (int x) { return x + 1; }

這將使一個 class 被定義出來,具有一個 public operator(),並在那個 lambda expression 出現的地方即時建立一個該 class 的 object。上述 lambda expression 並未指明造出的 function object 的 call operator 回返型別,因為 C++0x 另外有個 proposal 是 autodecltype(ref. proposal N1705)。前者我已多次提及,而後者可用來推導算式的型別。上面那個 lambda expression 就等價於:

<> (int x) -> decltype(x + 1) { return x + 1; }

Lambda expressions(or more specifically, closures)最有意思的特性在於能夠存取所處語境(context)的狀態(state,i.e. 變數的值),例如:

vector<int> v;

// fill v with some values...

int n;
cin >> n;

for_each(v.begin(), v.end(), <> (int& x) -> void { x += n; } );

(關於「for_each 的 "non-mutating algorithms" 身分與此處用法相衝突」的討論請見《for_each??》此文與我的回覆。)上示的那個 lambda expression 會在產出的 function object 之內以 by-value 方式儲存一份 n 的複本。如果想要的是 by-reference 語意,可以這麼寫:

ofstream fout;

// open fout...

for_each(v.begin(), v.end(), <> (int x) -> void extern(fout) { fout << x << endl; } );

如果這個 lambda expression 所造出的 function object 被喚起時,fout 已經退離作用域(gets out of scope),將導致 undefined behavior。(很好想像,如同提領使用 dangling pointer 一般。)

相較於 Ruby、Java 兩個非函數式語言(和函數式語言還有什麼好比 XD),C++ 對 "function as a first-class object" 的支援最為漂亮,主要關鍵在於重載 operator() 的能力。而 lambda expression 加入後,程式員使用 function objects 的意願必然會大為提高,對於 functional programming in C++ 絕對有相當大的正面影響。(目前 C++ functional programming 的勢力相當弱,類似當年 generic programming(或 template 的應用)被視為附屬於 data abstraction 之下;不過 C++ functional programming 的勢力應該沒辦法成長到像 generic programming 那般規模,畢竟 C++ 本質上是 imperative language。)關於 lambda expressions 的其餘細節請參閱相關 proposals,或等到 2009 年(根據《Effective C++, 3/e》)閱讀《The C++ Programming Language, 4/e》或《C++ Primer, 5/e》:)。

--
Lambda expressions 在我的 C++0x wishlist 上排名很前面,因為實在太好用了 XD。

--
本文同時展示四種註釋(comment)形式 XD。

Anonymous Anonymous8/11/2006 4:22 pm 說:

好像語法還是滿難看的, C++ 這樣下去很難說會真的比較好 -_-''

Blogger Josh Ko8/11/2006 4:55 pm 說:

要拚語法乾淨漂亮,怎麼拚得贏 Ruby 呢 XD。Java 的 API 介面那麼 verbose,還不是活得好好的,語法醜沒差啦 XD。

C++0x 的成敗關鍵,應該還是在 concept system 吧。Lambda expression 這種規模的東西,終究是 syntactic sugar 而已(但我沒說 syntactic sugar 不好不重要喔 XD)。

Blogger yen38/13/2006 1:31 pm 說:

_1 + 1 這種東西熊熊看起來,是不太能了解
我只能說,boost 真的很厲害吧
即時定義是個好主意,但是是否會讓程式碼較為難讀呢?

<< 回到頁首

Recent Comments

主頁右側 sidebar 新增 "Recent Comments",採 top-posting。JavaScript 一出來,要 top-posting 要排序要怎樣都隨心所欲,等於是 webpage metaprogramming,天下無敵 ─ 只要使用者沒把 JavaScript 關掉 XD。

--
玩 Blogger 順便溫習 JavaScript(應該說「重學」了)XD。

Blogger yen38/12/2006 4:22 pm 說:

排名第一名的有沒有獎品..XD
開玩笑的...那有人把blogger用到那麼變態的啦....(淚奔)

Blogger Josh Ko8/13/2006 7:52 am 說:

目前回應次數第一名的就是你啦 XD。

Blogger Celith8/13/2006 2:09 pm 說:

哈..
blog..真想來個大改造..
不過 javascript 真令人頭痛..
一堆奇怪的內定object...

Anonymous Anonymous11/29/2009 6:21 am 說:

Hello. And Bye.

<< 回到頁首

External Link 標誌

有鑑於「帶 external link 的標題」和「不帶 external link 的標題」看起來完全相同(除非滑鼠移上),我在附有 external link 的標題之後加上一個小箭號(沒錯,就是 sidebar <li> 標籤的那個小圖示),應該清晰許多。

--
玩 Blogger 順便學 CSS XD。

iTalk II 復得

學期中丟失的 Griffin iTalk 是二代,頂端有個錄音鈕,不需把 iPod 整台拿出來操控,很是方便。到了暑假決定重購(此購非彼構),上那個即將收費而被罵得臭頭的拍賣網站一搜,不僅 iTalk 的數量大減,二代竟然找不到了!於是查找 Belkin Voice Recorder 的資料(因為還 in stock),卻發現在音質方面所有評比都說和 iTalk 相差滿多,最致命的因素是,這個產品竟然是設計為近距離錄音用的,根本不符所需;又看到 Griffin iFM(舊版)兼具 FM 收聽、線控、錄音三個功能,但錄音品質一樣不理想。最後終於打算退一步,趁 iTalk 一代還沒全面消失之前買一個,卻十分幸運地在同一個拍賣網站找到了(僅剩的一個)iTalk 二代!(剛剛去搜,只剩下唯一一個 iTalk,而且是一代。)下標匯款後,賣家方面卻沒有回覆,讓我著實擔心了幾天,還以為這賣家搬到別的拍賣網站去,這邊都沒在顧了 XD。等了幾天給了負評,賣家才現身道歉。今早宅急便把東西送到,我也就把給賣家的評價改為良好。歷經千辛萬苦,總算復得 iTalk 了 :)。

--
再丟一次就大麻煩啦 XD。

Blogger yen38/12/2006 4:21 pm 說:

買個東西真辛苦....
順帶一提...ipod加再上一堆有的沒有的,應該有15k了吧
我最近拿我姊的benq joybee 125在聽了,果然是以前的好物啊,哈

<< 回到頁首

彰中今年榜單

臺大資訊一個,然後其他學校的資訊系都一堆(e.g. 中央、中正、清華、逢甲),人數少一點的好像也幾乎沒落單。唉,經過大一下的暴怒,我也不好意思招人來讀,只是覺得…有點失落吧。不過說實在,真正算認識的學弟不到五個,要中的機率還挺渺茫的 :P。然後看到一些人上了奇異科系,以及一些本身就很奇異的科系…又是一陣失落 :P。

--
窮則獨善其身,達則兼善天下。

Blogger yen38/12/2006 4:19 pm 說:

那麼....全台灣不就沒有資工系可以念了..XD

<< 回到頁首

2006/08/10

手痠

練到 Chopin's Piano Concerto No. 1 Mov. 1 中段,右手滿滿都是連續的十六分音符,多練幾次手就痠了 ─ 有錄音有真相。另外針對其中一段催快速度,終於達到和 CD 相當的數量級,一樣有錄音有真相

--
練成速度不代表可以聽 XD。

Blogger Thundermyth O.8/10/2006 4:07 pm 說:

挺幸福的,還有鋼琴可以玩 XDD

我無聊時還是只能打鍵盤 orz

另,催快速度那段"聽起來像是"在趕拍子啊

Blogger Josh Ko8/10/2006 4:15 pm 說:

手痠了嘛 XD。

Blogger yen38/12/2006 4:19 pm 說:

那麼要練到怎麼樣啊....聽起來真恐怖

<< 回到頁首

[轉貼] Static C++ Template Argument Constraints Checking

去年暑假貼在彰中華陽夢想家的文章,和下面那一篇使用相同手法,轉貼於此。


話說 C++ TR1 裡包含了一些令人熱血沸騰的東西,其中一個是所謂的 type traits,可用以萃取型別的一些特性,譬如說是不是 POD、A 型別是不是衍生自 B 型別之類。基本上,就是 Boost Type Traits Library 的那些東西吧。這些 traits 的判斷動作都是在編譯期執行(應該吧 XD),所以判斷結果的值(true or false)都是constant expression,可以在編譯期使用。

以下是一段 Andrei Alexandrescu 設計的 IsDerivedFrom template,此 template 有兩個 type parameters,可判斷第一個型別是否衍生自第二個型別。

既然是 Alexandrescu 的手筆,沒看過的恐怕會有點不適應 :) :

template<typename D, typename B>
struct IsDerivedFrom {
  class Yes_ {};
  class No_ {
    Yes_ a_[2];
  };
  static Yes_ check_(B*);
  static No_  check_(...);
  enum{value = sizeof(check_(static_cast<D*>(0))) == sizeof(Yes_)};
};

使用這個 template 的方法很簡單,例如 IsDerivedFrom<ifstream, istream>::value 會是 trueifstream 的確繼承自 istream),IsDerivedFrom<int, double>::value 則是 falseint 並非繼承自 double)。至於實作,就牽扯到一些語言細節。

首先,IsDerivedFrom struct 裡定義了兩個 classes:Yes_No_。其中 Yes_ 雖然內部沒有任何資料,但仍保證會得到儲存空間。而 No_ 裡面配置了大小為 2 的 Yes_ 陣列,使得 sizeof(No_) != sizeof(Yes_)

接著是最下面的 enumeration,定義了一個 enumerator 稱為 value,這是個常見的 class 內常數定義手法。這個常數以一個看起來有點複雜的算式初始化,判斷兩個東西的大小是否相同。Equality operator 的右側沒有問題,至於左側喚起了 static member function check_(),有兩個 overloaded 版本。其一接收 B 型別的指標,另一個是省略符號。當 equality operator 左側的 sizeof 算式被求值時,並不會真正喚起 check_(因此不需要提供函式定義),但仍然要依據 check_ 獲得的引數進行多載決議程序。這個引數是一個 D 型別指標,從 0(null)轉型而來,如果 D 繼承自 B,那麼 D* 就可以自動轉換至 B*,決議結果就會是傳回 Yes_check_,於是等號成立,讓 value 被初始化為 true。然而如果 D* 無法轉換至 B*(亦即 D 並非衍生自 B),那麼這個呼叫動作便無法匹配 check_(B*),所幸還有另一個 check_,接收的參數是最寬鬆的「...」,於是會決議為該函式,傳回值為 No_。最後因為兩邊的 sizeof() 結果不等,value 所獲得的初值就是 false

上面長長的一大段,看起來有點嚇人。幸運的是,身為 library user,我們並不需要煩惱實作細節。類似的 templates 可由 Boost Type Traits Library 獲得,甚至幾乎可確定下一版的 C++ Standard 會把這類 templates 納入 standard library 之中。

顯然還沒切入我們的主題「static template argument constraints checking」。有了上面的 template,我們可以搭配 class template partial specialization 完成條件限制的檢查。假設有個 Test class 的 T parameter 必須衍生自 std::istream

template<typename T> // T must derive from std::istream
class Test {
  // ...
};

我們可以在 T 後面加上一個檢查用的 non-type template parameter,並給它一個初值

template<typename T, bool Check = IsDerivedFrom<T, std::istream>::value>
class Test; // Note: only declaration

請注意這裡只是個宣告,真正的定義只能在 Checktrue 時才能出現,因此定義應該出現在針對 Check 進行 partial specialization 的地方(註):

template<typename T>
class Test<T, true> { // partial specialization
  // class definition goes here
};

註:當然也可以把定義寫在 primary template,然後把 Checkfalse 的情況導到會產生編譯錯誤的地方。做法很多種。

因為 Check 有預設引數,我們可以依平常的習慣來使用 Test

Test<std::ifstream> t; // suppose there exists a default ctor for Test

而當我們寫

Test<int> t; // error: int does not derive from std::istream

編譯器會企圖找到 Test<int, false> 的定義,但 primary template 只是個宣告,又只針對 Checktrue 提供定義,於是便形成編譯錯誤。

若要讓編譯訊息較為好懂一些,以下是個可能的做法:

template<typename T>
class Test<T, false> { // partial specialization for Check == false
  Test Test_template_argument_constraints_check_failed;
};

我們也針對 Checkfalse 的狀況提供特化,裡面是個顯然有問題的變數,名稱是我們想顯示的訊息。因為未具現化的 template 不會進行 type-checking(此部份尚待查證),因此若未牴觸 template argument 的限制,就不會造成編譯錯誤。然而若有牴觸,編譯器就會嘗試具現化這個有問題的定義,進而產生編譯錯誤,錯誤訊息內會有個變數名稱,也就讓 programmer 了解到出了什麼問題。

事實上寫這篇的動機是看到 Java SDK 1.5 新支援的泛型,其中可以直接指定 generic parameter 必須 extend 什麼類別,於是心血來潮也用 C++ template 做類似的東西。

--
原文發表時間 2005/07/13 Wed 17:21:49。

2006/08/08

HasSwap

睡前讀先前評為「走火入魔」的《C++ Template Metaprogramming》,讀沒幾頁就想試寫「判斷一個 class type 是否具有 swap member function」的 type-trait class。成果如下(在 g++ 3.4.2/4.1.0 & Visual C++ 2005 Express Ed. 之下測試成功)。

 1: template <typename T>
 2: class HasSwap {
 3:   class Yes { };
 4:   class No  { Yes a[2]; };
 5: 
 6:   template <void (T::*)(T&)>  // signature of member swap
 7:   struct Wrapper {
 8:     Wrapper(int) { }
 9:   };
10: 
11:   template <typename C> static Yes check(Wrapper<&C::swap>);
12:   template <typename C> static No  check(...);
13: 
14: public:
15: 
16:   enum { value = sizeof(check<T>(0)) == sizeof(Yes) };
17: };

這個 trait class 仍採用奠基於 SFINAE(Substitution Failure Is Not An Error)原則(ref.《C++ Templates ─ the Complete Guide》p.106)的標準手法:先定義兩個大小不同的 types(L3~4)作為兩個同名函式(L11~12)的 return types,然後(L16)引發函式重載決議(overload resolution)機制,並用 sizeof 判斷選用的是哪個函式。(ref.《Modern C++ Design》Sec. 2.7, p.34)

此處值得注意的是「避免無效算式爆炸」的技巧,即當 &T::swap 為無效算式時如何避免編譯器報錯。SFINAE 原則是在 function templates 具現化失敗時生效,而不會只因為「可能核算無效算式」就生效(ref.《C++ Templates ─ the Complete Guide》p.107)。因此我們必須讓編譯器遇見無效算式時同時令 SFINAE 生效(否則編譯器會因為遇見無效算式而報錯),即無效算式必須使函式無法被具現化。作法是將 &T::swap 包覆於一個 class template 之內(即 L6~9 的 class Wrapper),從一個算式轉為型別。這個型別便可當作函式參數型別使用,而與重載決議機制掛鉤,進而能在那個「被包覆於內的算式」無效時觸發 SFINAE(因為無法具現化函式參數型別)。最後為了在 SFINAE 有機會介入時才試著核算那個算式,兩個 check 都是 function templates,不會在 HasSwap 被具現化時直接被具現化(因為 L11 的 check 可能不得具現化)而引爆無效算式。

有了這個 trait class,std::swap 便可改寫如下(假設可改寫):

namespace std {
  template <bool>  // value-to-type technique again
  struct __Bool2Type { };

  template <typename T>
  void __swap(T& a, T& b, __Bool2Type<true>) {
    a.swap(b);
  }

  template <typename T>
  void __swap (T& a, T& b, __Bool2Type<false>) {
    T t = a;
    a = b;
    b = t;
  }

  template <typename T>
  void swap(T& a, T& b) {
    __swap(a, b, __Bool2Type<HasSwap<T>::value>());
  }   
}

如此一來,只要 T 具有 member function swap,對 std::swap 的呼叫就會自動轉發給那個 member swap,不需再為 T 手動特化(specialize)std::swap

這個 HasSwap 仍可再一般化為檢測任意 member 存在與否,但我不知道能不能避開 macro 而寫出不冗贅的使用介面(或者該問介面應如何設計)。即使維持原樣固定檢測 swap 的有無,這個 class 也有一個地方稍有侷限:swap 的 signature 被寫死為 void (T::*)(T&)。只要 signature 稍有不同,HasSwap<T>::value 就會回返 false。而《Exceptional C++ Style》p.29 如是說:

The standard library specification deliberately gives some leeway to implementers when it comes to member functions. Specifically:

  • A member function signature with default parameters might be replaced by "two or more member function signatures with the equivalent behavior".
  • A member function signature might have additional defaulted parameters.

... Because the signatures of standard library member functions are impossible to know exactly ─ unless you peek in your library implementation's header files to look for any peekaboo parameters(JK 注:即 library 實作者被允許任意加入的額外參數), and even then the answer might change on a new release of the same library ─ the bottom line is that you can't reliably form pointers to standard library member functions and still have portable code.

因此嚴格說起來,HasSwap 對於 standard library classes(e.g. vector<T>list<T>)並不可攜(not portable)。不過此處影響應該不太大,正如《Exceptional C++ Style》所說:

In practice, though, the problem might not be all that bad. I don't know whether library implementers widely avail themselves of the leeway to add extra parameters, or intend to do so in the future. To the extent that they don't do so, you won't encounter these difficulties in practice.

--
Type traits 基本上可算是 compile-time reflection 吧。

Blogger yen38/09/2006 5:54 pm 說:

同一句...這一次真的要很努力才能看懂了..XD

<< 回到頁首

2006/08/06

Oh My Gosh!

Haskell is beautiful!! 看看這個 Fibonacci 數列函式定義:

fibs :: [Int]
fibs = 0 : 1 : [ a + b | (a, b) <- zip fibs (tail fibs)]

第一行說 fibs 這個函式的(回返)型別是 list of Int。第二行是 fibs 的定義:

  • ':' 是 list concatenation,e.g. [1, 2] : [3, 4] = [1, 2, 3, 4],所以 fibs 這個 list 的前兩個元素是 0 和 1,後面是另一個 list。
  • 後面這個 list 的語法很像數學上集合的記號。數學上我們寫 {(x, y) | x, y \in R},說的是「這個集合內放的是 (x, y) 數對,其中 xy 屬於 RxyR 裡面的所有數)」,而 Haskell 此處的寫法是「這個 list 內放的是 a + b 的值,其中 (a, b) tuple 是 "zip fibs (tail fibs)" 這個 list 的所有元素」。
  • 最後,zip 會把兩個 lists 同一位置的元素綁在一起形成一個 tuple,例如 zip [1, 2, 3] [4, 5, 6] = [(1, 4), (2, 5), (3, 6)]。而 tail 會回返一個 list 捨棄第一個元素的結果,因此 zip fibs (tail fibs)(不覺得這段很像 Lisp 嗎 XD)這個 list 的第一個元素是 (0, 1),然後是 (1, 1),再來是 (1, 2),無止盡地下去。沒錯,recursion 已經進來了,而且姿態輕盈又優雅。因為 Haskell 的 lazy evaluation 特性,fibs 所代表的 list 長度雖然無窮長,但只會產生使用者要求的值。

神妙無比!Wonderfully elegant!

--
不用說,偉大的 vi 又認得 .hs 檔案了 XD。

Blogger yen38/07/2006 12:48 pm 說:

偉哉~~~vi~~~
事實上本文還沒看..XD

<< 回到頁首

Peopleware & Haskell

今天拿到從博客來訂的《Peopleware》中文版。此書中譯名為「天才當家」,我不怎麼喜歡,不過 "Peopleware" 的確難譯得很。這本書經常和《人月神話》(The Mythical Man-Month,這個中譯名我就相當喜歡)一同提及。Peopleware 雖以大量軟體工程專案為例,但和 MMM 相較,此書更接近一般管理,對象是「腦力密集的開發團隊」,軟體開發團隊就是個 instance。慢慢再看。

先前看到 Common Lisp 的迴圈語法後,對 Lisp 的熱情瞬間大減,但應該不至於放棄,list processing 和 macros 應該都還值得一觀(看 Paul Graham 講得天花亂墜 XD)。另一方面,Haskell 似乎值得一學:其一,Haskell 是個 pure functional programming language,而 functional programming 正是我想學 Lisp 的一大原因;其二,Haskell 有個 extension 稱為 Generic Haskell,是 generic programming 的另外一個重要分枝(besides C++ templates)的活躍場地。所以計畫得修改一下,把 Haskell 加入「預期能熟練使用的語言清單」之中。目前這份清單的成員有 C++、Java、Ruby、Lisp、Haskell,依目前熟識程度排列。目標大三開學前全部達到適當的熟練程度,應該不算太苛。

--
其他語言應該就不需要學得那麼紮實了(除非有新的 paradigms 出現)。

《被遺忘的資訊教育~》回應

【我的回應】

> 造究電腦課宛如軟體課,挑選出與日常生活較相關的教材
> 讓電腦成了不懂基本知識就會使用的機器

電腦普及化而平易近人是好事。現在汽機車滿街跑,一般人誰需要了解熱力學定律和引擎構造才能駕駛騎乘?:)

> 而繁瑣的計算機概論,逐漸被淡忘~

對一般使用者而言,的確不需接觸計算機概論。想成為 power user,計概當然是必要的,但不是每個人都願意花心力(或能夠)成為 power user。普遍的資訊教育不應扼殺「培養出 power users 」(甚至專才)的可能性(這需要老師加注心力輔導),但也不應強求每個人都得成為 power user。工程師應該讓科技可為人用,設計親和易用的介面隱藏實作細節,而不應要求使用者那邊得了解多深,甚至直接把使用者當傻瓜最好(e.g. 傻瓜相機)。插播一段滿有趣的相關引言:"Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far the universe is winning." ─ Rich Cook. 或許這段話也可證明普遍資訊教育的必要性吧 :P。

> 因此,從國中到高中,Excel、powerpoint、front_page(dreamweaver)等等不斷出現~

高中是真的可以考慮朝「培養 power user」的方向走,例如學個高階易用的 script language,對日常使用很有幫助。

> 然而,我也想說,學「文言文」、學「化學」等.. > 這跟我以後的課程有何關係?這跟我的生活有何關係?

我們的國文課,基本上也融入中國哲學在裡面(esp. 儒家思想),這非常非常重要,而古文正是中國哲思的載具,本身又相當優美。(課本不可能選那種沒意義又不優美的文章。)倘若捨棄國文課而荒廢了普遍的文化教育,那會是大災難。而高中的數學、物理、化學、生物,本來就是為大學打下基礎,本就不是人人必修。

> 加上中學不注重資訊教育,難怪台灣的資訊展業比不上他國了..

的確不注重,但中學資訊教育的重點應該是培養普遍的資訊能力,而不是培養專才。

> 將「資訊科」列為必考科目

我寧願不要。我不想看著這門科目也淪為學生的學習夢魘。看看現在每一門要考試的科目,都被(補習班)扭曲成什麼德行 ─ 不忍卒睹。一般補習班對知識的殺傷力大得驚人,而考試正是使補習班生意興隆的一大主因。

一點意見供參考 :)。

--
不小心寫那麼多,不轉載過來有點可惜 :P。

2006/08/05

再論

這次軒伍的主角設定和神隱少女有雷同之處 :P。然後剛看到巴哈姆特 GNN 採訪 DOMO,裡面說:

除了背景的改變,本作中 DOMO小組最自豪的,就是劇情的完整性和豐富度。

又說:

以《軒轅劍肆》來說,因為推出時程上的關係,劇情作了很多調整,有些地方變化太快,這次《軒轅劍伍》則致力於劇情的完整,至少希望在故事的起承轉合和高潮起伏上,都有合理的解釋和安排。

我倒比較喜歡軒肆的劇情 :P。

--
The Task III 老闆說下星期一給我答覆。

Blogger yen38/05/2006 11:48 am 說:

最後一行跟上面似乎沒啥關係..XD
要回覆了啊,真期待

Anonymous Anonymous8/05/2006 2:07 pm 說:

完全反映了我想說的XD
PTT的軒劍版幾乎都是負面評價阿XD
→ mars3:大家一直呼籲大宇不要用ShitForce這套整死正版玩家的防拷,他們偏要用,真的不知道是什麼心態?以整正版玩家為樂??話說玩盜版的只要用某種虛擬光碟軟體+拔光碟機......就能輕易破了ShitForce;真不知道用它有何意義?@@a。

<< 回到頁首

然後就完了

狂用絕技輕鬆擊退兩隻特大魔王,結果就到了尾聲。這次的劇情…淡淡的沒什麼味道耶,又不迴轉又不深刻,而且和開頭動畫幾乎沒關係(宣傳不是都用開頭動畫的場景嗎 = =)。開頭動畫和劇情的相關程度,大概就像高中科展做的那個「駭客任務:重裝點燈」與其「標準字」一樣,有關連是有關連,但開頭動畫 / 科展作品的標準字幾乎是做爽的。(像那隻放在官網前導頁的機車大鎖,根本 irrelevant,特地放在那種地方還以為多重要 = =。)然後招式…是這一代的招式催生方式不同嗎?為啥打最後大魔王的時候(lv. 42),各個角色的招式大概都只五招上下?而絕技更直接在說明書裡面寫「每個角色都有一招絕技可使用」。角色是多了很多沒錯,招式的威力也會隨等級提升而可復用,但就是覺得很貧乏(復用是復用軟體組件,遊戲玩家最討厭復用了 XD)。比較值得一提的大概就是這次機關解謎比較多吧。喔對了,畫面品質和蒼之濤的確差不太多,不過我覺得這一代戰鬥的運鏡不錯,可惜就是招式少。我玩軒轅劍一向不把重點放在遊戲系統上,比較注意劇情(從而「劇情」一項在遊戲評分上佔較大比例),而這次劇情…真是白開水 Orz。

--
不要每下愈況啊。

Blogger Thundermyth O.8/05/2006 11:28 am 說:

啥? 破啦!? 這麼快 @@"

Blogger yen38/05/2006 11:47 am 說:

好快的刀啊

Blogger Josh Ko8/05/2006 3:15 pm 說:

> 啥? 破啦!? 這麼快 @@"

對啊,我以為差不多打到一半而已,怎麼魔王就這麼強,練功要練得很辛苦了 XD。

事實上是家長不在,把全部時間投入軒伍,很快就走完主線了 XD。

我本來以為可以玩到八月底 XD。

<< 回到頁首

被軒伍惹怒

昨天下午拿到軒伍,已花了不少時間,就在剛剛遇到兩場連續(即中間無自由操控之時間,從而沒得存檔)的特大號魔王戰鬥(配樂就是黃帝戰蚩尤的音樂)。第二場尤其變態,魔王出一招星火燎原,四個必死三個。打到最後彈盡援絕,差不多就得投降了,但最後總算是勉強收拾掉。然後就如各位以及偉大的墨菲定律所料,當機啦!我你勒 TOYOTA,我絕不想再打一遍啦!準備用 GM8 修改 XD。

--
這是你逼我的,怪不得人。

--
然後發現我根本不會用 GM XD。

Blogger Celith8/05/2006 10:50 am 說:

阿?
軒伍是什麼?
哪類型的遊戲!?

Blogger Josh Ko8/05/2006 11:02 am 說:

軒轅劍伍,很有名的一款老招牌老字號國產 RPG。

<< 回到頁首

2006/08/03

彰中 & 危險心靈

今天回彰中看愈來愈帥的錦源,聊了半日。出門時看香香沒穿制服,我也就把已經穿好的制服換掉,結果只剩消息不靈的 God 穿制服(God 還被校長盯上 XD)。看來經上次寒假一鬧之後,學校嚴格了些,要登錄訪客的進出時段,警衛先生並告誡不得靠近教室 XD。談話有一段提到《危險心靈》以及社會運動(學運),今晚又看了公視播出的倒數第二集,仍覺得如同被上帝玩弄於股掌之間。「道之為物,惟恍惟惚。惚兮恍兮,其中有象﹔恍兮惚兮,其中有物。窈兮冥兮,其中有精﹔其精甚真,其中有信。」有東西在裡面,filling everywhere,behind everything。另外也討論到 infinitesimal,想到聰明講的「上帝把祕密藏在無窮維空間裡」。馴服無窮(無窮大、無窮小、乃至於最基本的無窮步驟),微積分只是第一步。這方面,數學和計算理論應該都有東西。無窮詭譎到爆炸,可是又其中有象其中有精,上帝真是絕佳的藏秘者。Let's see how far we can go ─ through the rabbit hole.

--
明天軒轅劍伍會寄到家 :P。

Anonymous Anonymous8/03/2006 3:22 pm 說:

頗讓我訝異,學長會看危險心靈XD

那部我之所以喜歡,可以說是跟我國中相似
我們國中有發起過罷免老師,到最後被學校壓下

Blogger yen38/04/2006 2:07 pm 說:

原來你也回彰中啦.XD

<< 回到頁首

2006/08/01

神祕統計數據

18266

9132

8638

5418

55339

36965

33723

21145

49746

34502

31968

18018

60357

42593

38530

21032

22121

15853

14463

7483

25860

19452

17305

8146

13592

9571

8740

4837

37816

18907

17231

11303

35134

17566

16330

7990

46736

23367

21431

14289

21216

15269

12462

7215

46629

32436

28865

16682

34271

23099

20828

12620

64546

32272

29233

14817

70813

47665

42854

26048

13770

9962

9080

4585

75057

55779

50346

23451

28229

19727

17680

9850

19630

13969

13043

6682

19940

13239

12073

7545

150862

75430

67751

33188

124368

62183

57143

27900

53943

37737

34339

18915

33783

23409

21551

11778

61006

30502

27794

14401

41674

29737

26849

14075

10152

6516

6079

4038

10762

5380

4574

1752

14712

7355

6448

1775

1260330

769574

697351

376978

用上了 irb(Interactive Ruby Shell)、Java、Mac 的「文字編輯」程式和 Xcode。

--
提示:每列數字均嚴格遞減;最後一列是上面各列的總和。

Blogger yen38/01/2006 4:44 pm 說:

真是奇怪的統計數據

Blogger yen38/01/2006 4:49 pm 說:

經過josh指點,原來是這樣子啊..hmm

<< 回到頁首

交件

The Task III 半成品整體審視完畢,可以交件啦!至此 The Task III 就算告一段落了。有些進一步統計數據,稍後再貼上。

--
整整半年呢,嘖嘖。