五月 29, 2013
» [雜談] 程式中的命名風格

很久以前一直在規劃要弄個雜談區,方向大概就是放一些「看起來雜亂無章,不曉得能做什麼的嘴砲文」… 其實就是把一些放在D槽多年的資料移到雲端備份XD 但既然要丟上雲端,還是會盡量讓內容看起來有條理一點。作為系列的第一篇,先來個時事文吧。


前幾天在 BBS 上看到命名風格的討論,由於持續了幾天,就稍微看了一下大家在聊些什麼。那一串的原點是有人提到對專案中出現「型別前綴」這種參數命名原則不太滿意,結果很多人就爆炸了XD

工作或專案上的 coding rule 通常沒有什麼對錯可言,就是一組大家都能接受的規則而已。在團隊成員對於程式碼的表達有一致的認知,而不是各自表述時,才有機會繼續談後面的合作。而「命名風格」雖然帶有不少藝術與美感(順眼)等主觀成份,也不是因此就沒有討論的空間。

編寫程式不完全是讓電腦系統可以運作那麼單純,也是程式設計師們傳達自己想法的管道。程式的編寫跟寫作一樣,雖然不必使用到華麗的詞藻,但我相信一份敘事簡明的程式,閱讀起來也是賞心悅目。作為個人能力的養成,還是值得花一點時間研究… 至於在團隊中使用,以及成員間的溝通協調,就真的是政治問題或人品問題啦~

通常在決定依循哪一種風格時都有很多考量,可能是客戶的要求、團隊的傳統、被什麼書籍文章洗腦、或是開發平台與程式語言的影響。不過在實際的開發中,我的經驗是命名只要不是太誇張的縮寫或使用冷僻的英文單字,對可讀性的影響微乎其微。曾經遇過比較誇張例子是用德文來命名變數,這對於完全不懂德文的我還真的是「不夠直覺」的命名。除了那次經驗外,即使接觸到好幾種不同風格也不會真的造成什麼困擾。

那為什麼還要寫這篇文章呢?雖然這種風格觀點是很容易被戰到爆的萬年戰文,而且我也討厭寫個程式還要有一堆規約來限制自己,但最近也常常需要向別人說明為什麼程式會寫成某種樣子,就趁這個機會整理一下,順便也檢視一下自己的習慣。其實程式寫久了通常會慢慢有自己的習慣,例如我私底下愛用的縮寫風格已經蠻固定了,就算現在看到多年前的變數命名,還是可以直覺理解用途。會需要特別留意命名方式主要還是為了和別人溝通,以及維護性與一致性吧。

順帶一提,整理這篇文章其實花了好幾天時間,因為一直以來都是覺得有問題就自動調整一下,完全沒特別選擇要用什麼風格,只好把手邊的程式都抓出來整理一下XD


一般提到「型別前綴」的命名風格通常會直接聯想到「(系統)匈牙利命名法」(Systems Hungarian Notation),對於以前接受過微軟平台技術洗禮的人多半不陌生。到了現在的 .Net Framework Naming convention 則改為建議 DO NOT use 了。我個人並不討厭加上綴字,命名時適當地加上綴字其實是有助於理解的。匈牙利命名法這種風格,最早也曾經嘗試使用過一陣子,但隨著 C 以外的語言越用越多,尤其是在可以大量創造型別的語言中(例如 C++ 和 Python),型別要怎麼加上去就會是個大問題;再加上後來覺得這樣的命名其實也曝露了實作細節,遇到要改型別時很麻煩,就漸漸地不再使用了。真的需要在命名中說明型別時,也會盡量以抽象型別為主,避免直接使用基礎型別。

除了團隊和專案的規範外,我私底下慣用的命名風格應該還算單純,沒什麼麻煩的規定。大部份情況都是很隨性地命名,整理一下大概就是幾個規則是比較固定會使用的:

命名

原則上只要沒有特別限制,使用全小寫、hyphen 分隔的命名方式,不支援的時候則改用 camel case。在可能的範圍內盡量用不影響可讀性或比較通用的縮寫,以字少的優先。主要是在使用不同語言時可能會有一些差異。舉例來說,在符號使用限制少的 forth 或 scheme / lisp 中可以用全小寫、hyphen 或斜線符號區隔的命名風格:

(define module-do-something ...)

(defun module/do-something ...)

而在 C 中只能用底線(underscore)分隔 namespace / module name 與 tag name:

RetType Module_Method(ArgType ...);

遇到需要標明存取控制範圍的時候,例如 private,在 C 中是在前面或後面加底線,在 Emacs lisp 這種沒有模組概念的語言可能改成在 module name 後面寫成 --,Python 則是在前面加上底線… 大概也是依語言而異。

型別

可以的話盡量定義抽象型別來使用:例如在 C 裡透過 typedef 定義新型別,通常會加上 _t 作為後綴。新的 C++11 也可以定義 type alias。命名時盡量以大寫字母開頭,以前在 Io 中接觸到這種風格,覺得還不錯就繼續用了。

變數

全部小寫,有必要時使用 lower camel case。全域變數會加前綴,大概會是 g_ 之類的,不過通常很少出現全域變數所以不常用。

遇到代表容器的變數,通常以英文的複數型式命名,例如 users。有需要的話可以加上輔助說明用的前綴,例如表達數量時用 numBooks

需要特別提醒操作方式或用途的時候,可能會加上一點修飾,例如一個暫時使用的變數可能會加上 tmp 前綴;另外就是在 C/C++ 中被 wild pointer 戳死的機會太多了,這時也會特別在前面加上 p 提醒自己。

常數

包括列舉(enum)用的常數,通常全部以大寫命名。因為沒辦法 camel case 所以單字之間可能會使用 hyphen 或底線分隔。不過在 scheme 或 lisp 中多半還是小寫。

函式

通常是動詞開頭的型式,例如 do-create-send-。如果是判斷用的函式則看各語言風格,一般是 is 開頭的型式,這也是從 Io 來的風格,但在 forth 和 scheme 中則是在最後加上 ? 後綴:

(if (buffer-empty? ...)

寫 lisp 時則改用 -p

(if (buffer-empty-p ...)

其他還有像轉換資料用的函式命名,依語言的不同可能會用 >->-to- 等分隔。

談這種東西很容易混到其他撰寫風格的討論,命名的部份大概就是這樣吧。各語言的細節太多了,一時也講不完,原則上我會盡量先參考語言慣例,這樣在搭配標準函式庫使用時才不會變成混合風格。至於很多人建議的底線,因為輸入實在很麻煩,對可讀性好像也沒有什麼決定性的幫助… 自從我改用 emacs 寫程式後就盡量少用了,反正編輯可以靠 subword,閱讀時真的不行就開 glasses-mode 吧 :-p

不過說到命名,在規則受限的語言中還真的很麻煩,我覺得與其用底線,還不如用 hyphen(可以少按一個 shift),但在 C 連 - 都不准用。在 forth 中只要不是空白字元都可以用,命名時的表達力就豐富多了,適時使用 ->>>? 等符號對可讀性還是有些幫助的。單就這一點來看,haskell 很不錯,可以用符號設計很多可愛的運算子XD

這樣整理下來,我的適應力應該還算不錯吧,大概都是語言慣例就用了XD 但實際上在寫的時候,除了團隊要求的情況外也不是很嚴格地要求自己遵守啦,反正寫久變成習慣的,不必太要求就會成形;真的需要違反原則時,大概也不會出現太誇張的命名。硬是要規定套用某些規定反而失去發揮的空間,我想一般寫程式的人並不是單純的打字員,應該都不會喜歡的吧。


Filed under: Programming, Talk

五月 2, 2013
» Auth-source in Emacs

前幾天將 Emacs 一口氣更新到 24.3 以後,發現有一堆東西都不太一樣了,一執行就回報一堆錯誤。畢竟現在已經有很多工作都在上面進行,工具有問題的話很麻煩,只好花點時間調整。

首先要找出有問題的套件,暫時移出路徑待修,結果一整理下來發現有一大堆根本不曉得為什麼存在的東西會報錯,把 mercurial log 叫出來一看才知道上次整修的時間已經是 2009 了。存在這麼多年卻完全沒印象的東西叫做垃圾,乾脆整個目錄都翻出來整理。(不過我要強調這只是倒垃圾,還不到 dot emacs bankruptcy 的程度XD)

後來在更新 g-client 設定時,發現在新版裡已經改用 auth-source 來取得認證所需的資訊。玩了一下發現這東西還真是不錯,可以把一些認證用的密碼資訊統一管理,並透過 api 來取得。大概瞭解運作方式後,馬上動手整合到跟認證有關的套件中。

auth-source 目前支援兩種用來取得認證資訊的 backend,分別是傳統的 .netrc 和 freedesktop 提出的 Secret Service API.netrc 雖然比較簡單,但對於有 un*x-like 環境使用經驗的人會比較熟悉,再加上 auth-source 支援 GPG 加密過的 .netrc,因此目標就是把敏感資訊都移到 .netrc 裡面管理。另一方面也是因為我沒有 Gnome 或 KDE 環境,沒辦法實驗 Secret Service API。

首先要告訴 auth-source 資料庫的位置,如果沒有特殊需求的話,預設會先找 ~/.authinfo,格式等同於 ~/.netrc。雖然這個檔案一般會將權限設為 600,但裡面存放的是明碼,總覺得不太保險。有使用 GPG 的話,可以將這個檔案加密使用,auth-source 可以處理加密後的檔案,預設檔名會是 ~/.authinfo.gpg。如果想改變存放位置,可以透過 auth-sources 指定路徑:

基本的 .netrc 內容格式如下:

machine <host> login <user> password <pass>

可以看到能儲存的資訊有 host、user、password 三種,而 auth-source 引入新的 key:port,可以用來儲存額外資訊,也可以當作搜尋時的 key 來使用。 使用方式並不難,只要透過 auth-source-search 這支函式,並在 spec 參數指定好用來搜尋的 key 就可以得到結果。例如我想取得某個站的認證密碼:

傳回來的資訊是一個 plist,可以透過 plist-get 取得需要的資訊。其中 secret 欄位的值有可能是一個用來取得真正密碼的函式,因此需要特別處理。除此之外,由於上面的例子中指定找不到就建立一組新資訊,在認證資訊不存在時,可以選擇是否儲存目前設定,一般會需要搭配 auth-source-creation-defaultsauth-source-creation-prompts 以提示使用者輸入不足的資訊:

同時,在第一次建立時也可以從 plist 取得儲存用的程序,直接執行就可以了。

執行這個函式會詢問儲存位置,也可以趁這個時候修改儲存內容。

完成這些工作,取得密碼後就可以丟給真正執行認證的函式處理了。


Filed under: emacs, Note

十月 11, 2012
» 2012 Sep‧東京 Day 6

2012.9.19

總算(寫)到了最後一天啦!整理遊記跟照片真的是很累的事,雖然每天回到飯店都會做一些記錄,但也只有前兩天比較完整,最後幾天的內容幾乎派不上用場。每天下班後只能空出一點時間整理,日子一拖下去很多當時的情境會忘光光;再加上我都在迷路,根本不曉得跑到哪裡,自由行程那兩天的路線有一大半不在計畫內,事後看著照片要查也很難找XD

雖然沒有打算刻意整理,但因為房間內的東西幾乎沒動到,把東西整理完大概就是房間的原狀了。昨晚睡前就先把所有行李都塞好,反正今天應該不會再買東西了… 吧。

吃完最後一天的早餐,就準備 checkout,然後在附近耗掉早上的時間。其實以東京來說,反正交通那麼方便,就算只有半天也可以去其他地方玩一下再回來。不過來了上野那麼多天,一直都沒好好看一下這個城市,所以最後一天就不打算到處亂跑啦。出門的時候正下著毛毛雨,想了一下決定先去買好回機場的車票,再去一趟上野公園,反正還有很多地方沒看到。


買完票以後從不忍池口出去,沿著上坡的路一直走就可以走到不忍池和弁天堂。後來才知道這裡供奉的弁才天是音樂女神和財神,如果早知道的話,應該會想辦法在行程裡排個了法寺吧XD 通過參道時雨勢突然變大,只好跑到屋簷下躲雨,順便休息一下。

在弁天堂的後面亂跑,發現一個劍豪的紀念碑。後來查了一下櫛淵虚冲軒 (くしぶちきょちゅうけん),原來是神道一心流兵法的創始人,本名叫櫛淵彌兵衛宣根,虚冲軒則是他的號。除了劍豪的碑以外,不忍池周圍還有很多奇怪的碑或塚。例如鳥塚,是為了感謝養活人類的雞而立的慰靈塚 (日語中的「鳥」是雞的意思)。附近還有菜刀塚、琴弦塚、和扇塚、魚塚等等,甚至還有為了感謝鱉而立的碑。



由於記憶卡已經滿了,再加上下雨實在有點麻煩,這一天幾乎沒拍到什麼照片。

不曉得是不是因為下雨的關係,來這裡的人很少,只看到幾位像是觀光客的人 (而且還講中文XD)。離開弁天堂以後繼續往上走,如果可以的話是想走到東照宮,途中經過看起來像動物園的地方,但走了半天看不到盡頭,加上雨一直變大,結果中途就折返了XD 回車站的途中參觀了一下花園稲荷神社,原來這裡也跟彰義隊有點關係。稲荷神掌管的是農產品,大概是因為跟民生相關,供奉稲荷神的神社非常多。

回到車站後還有一點時間,想了一下就跑去逛ヨドバシカメラ了。在台灣看不到這麼帥氣的綜合電器商場大樓,趁著一早沒什麼人,直接殺到頂樓慢慢逛下來。本來想說帶個日本配列的鍵盤回去,但挑來挑去沒什麼滿意的 (而且又貴…)。最大的收獲大概就是玩了一下 3DS 和 iPad,見識了裸視 3D 和傳說中流暢的 iPad 操作。除了電器用品,這裡玩具也不少,結果又轉了一顆海洋堂的轉蛋XD 回台灣後打開一看,拿到一個不認識的角色「楪いのり」(連名字都不曉得怎麼輸入XD),但做的相當不錯。


逛完以後又是煩惱午餐的時候了。由於這一趟來完全沒吃到拉麵,很快地就決定去武藏吃つけ麵了。第一次吃這種麵,觀察了一下其他人的動作才開始吃,連吃完可以加熱湯也是問旁邊上班族才知道XD 不過這沾麵用的濃湯真的非常鹹,要不是狂灌冰水實在受不了。下次有機會改吃一蘭好了XD

吃完以後就回飯店拿行李,準備搭車回機場了。當初研究了好久,刻意選上野的原因就是因為回機場太方便了。從京成上野駅搭京成特急回機場,雖然不是最快的,但絕對不會搭錯車XD 而且票價應該是最便宜的吧。六天的旅行就這樣結束啦。在出發前做了很多天鍵盤旅行,但實際走一趟又是完全不同的體驗和感受。這趟除了預定的活動外,也體驗一下日本的現代化、日本的便利,以及和台灣相似又充滿驚奇的異國生活,同時也是自學日語的成果驗收XD

回到台灣以後又是另一個挑戰的開始,要整理上千張照片,遊記,還有戰利品們…


Filed under: Note

十月 10, 2012
» 2012 Sep‧東京 Day 5 – 2

2012.9.18

結束 Gundam Cafe 朝聖後,離出發還有一點時間,打算先去逛一下 Book off。根據記憶,Book off 應該是往南走就可以找到,所以就穿過車站,往另外一邊出口前進。

路上看到一間 18 歲以下不得進入的店,所以只在外面拍了一下照,回來一查才發現是蠻有名的成人商品店「大人のデパート m’s」 (又是大樓)。秋葉原的 Book off 號稱是最大的,不過感覺沒有吉祥寺的好逛,稍微逛了一下就回車站準備搭車了。

下一個目的地是期待已久的日テレ大時計,所以得先到新橋駅。一出站就看到木村拓哉的 GATSBY 廣告看板XD 他的髮蠟廣告實在是印象深刻,那首廣告歌曾經可以在官網下載到 (原曲是 The Stylistics 唱的 Can’t Give You Anything (But My Love))。現在又變成奇怪的オサレ星人了XD



不曉得是不是因為剛才的嘲笑褻瀆了木村神,決定了接下來的悲慘命運。這個出口並不是預期的出口,結果我還很高興地邊拍邊走。一出車站就可以看到一個老火車頭 C11-292,還看到疑似電視節目的取材。自己覺得一切都很順利,只要找到車站旁的大樓,等到兩點就可以了… 結果在附近繞了老半天,也看到很多大樓,就是沒看到看起來像電視台的。再走下去連荷槍警衛都出現了,這時候才開始緊張起來,都不曉得跑到什麼恐怖的地方了XD

雖然我沿著鐵路走應該是不會迷路,但我忘了地球是圓的,走了老半天竟然看到銀座的標示和有楽町駅!最可怕的是我完全不曉得這兩個地方是哪裡,距離新橋駅到底多遠,只覺得一直走一直走,走好久還走不到汐留。回來一查地圖才發現完全走錯方向,選了反方向難怪找不到XD 兩點一到,我就放棄趕路了,但還是得想辦法找到回去的路,這時才決定回頭。雖然多繞了一個小時,但一路上有很多有趣的店,一個人走走看看,其實不會無聊,所以才會走了半天才發現走錯方向XD 就算回來後看著照片,用 Google Street View 對照半天,還是找了好久才找到當初迷路的路線。



好不容易找到日テレ大樓,但看起來實在太複雜,而且一時沒找到明確的入口,只好隨便找個樓梯爬上去。上去以後發現奇怪的畫面,幾個人趴在地上玩類似人體○蚣的遊戲,看起來實在太噁心,以致於又開始懷疑走錯路了XD (警告:千萬別去找馬賽克起來的東西,會噁心到想吐)

繞了一圈後大鐘就出現在眼前了,真是得來全不費工夫啊 (只是得先迷路一個小時XD)。到了以後才發現根本記錯時間,原本以為都是偶數整點開始,結果下一場表演的時間是三點… 也就是還有半小時可以休息,不用等到四點真是太好了!大鐘真的很有迫力,上面有很多機器人住民(?),就算不動也很可愛。



可以的話請務必切換 HD 畫質

在等待時完全沒人,只有我自己在大鐘的前面走來走去,還跑進大樓裡吹一下冷氣才出來。等到動作前十分鐘左右,人群慢慢出現,還好我已經佔好觀賞角度最棒的位子了。大鐘的表演只有不到五分鐘,出發前也先在 Youtube 上看了其他人的錄影,但實際在現場看的時候,伴隨著很有 Ghibli 動畫風格的音樂還是相當感動啊。結束的時候發生一個小插曲,有個女孩拿著某 h 牌手機要我幫她拍照,但我從來沒用過手機拍照,搞半天還是不會操作,還學了一下才順利拍到照片,實在是有點遜XD (明明就手機設計太不符合我的直覺XD)

雖然迷了一下路,但跑這一趟還是很值得,而且也錄到影片了,回家後就可以慢慢看,看到爽了。美中不足的是沒帶腳架,所以原始影片實在是晃得很厲害。後來發現 Youtube 有自動修正,試用了一下果然相當強大!想挑戰極限的請看原始版吧XD

這裡有一點要特別記錄一下,雖說網頁上是寫下午三點開始,但不曉得是時間不準還是怎樣,竟然五十五分就開始動作了,要看的話最好提早十分鐘到。順帶一提,要進大樓時的電動旋轉門很有趣,可以玩玩看XD



看完大鐘後開始想接下來的行程XD 記得在網路上查到東京有購物街,然後天空樹那邊好像也有;另外台場也有 RX-78-2 在等著,能去的地方還不少。不過想了幾秒後決定去東京駅了,雖然我對逛商店街沒什麼興趣,但那邊好像有 LEGO 專賣店!雖然我從沒喝克○奶粉後就沒再拿到任何 LEGO 套件了 (LEGO 實在不便宜),但我對於這類高自由度的玩具一直很有愛,還是逛一下專賣店比較吸引我。


東京駅應該是這次遇到的迷宮中排第二的吧,在站內繞了好久,還問了服務台才找到一番街的入口。進去後又耍笨不看地圖,想說就幾排店面而已怎麼會找不到… 結果真的找不到XD 不過迷路也有迷路的樂趣啦,一家一家店逛過去也挺好玩的,可以看到很多神奇,台灣看不到的店。


在車站裡逛了幾圈,順利取得新的戰利品後,又開始煩惱下一個目的地的事XD 原本查了不少地方,例如神保町的古書街、或是御茶ノ水的樂器街,都是我很想去朝聖的地方 (可惜古書祭還沒到)。雖然原本有打算去買個オカリナ回來,不過這幾天跑了好幾趟書店想找一些書,但一直找不到我想買的書,所以也考慮趁這個機會跑一趟淳久堂。昨天在吉祥寺附近好像有看到一家分店,但那時滿腦子都是 Book off,買了一堆書後就沒力氣再跑另一家書店了。但回來以後實在有點後悔,晚上又跑去其他書店也買不到… 看時間還早就決定去逛書店啦。


說到淳久堂,雖說在台灣也常常在那邊訂書,但聽過好幾次日本的本店是一整棟大樓後,就一直想去朝聖一次 (現在聽到大樓已經嚇不倒我了XD)。到了池袋後,聽說這個車站也是可怕的迷宮,果然一出改札口又迷路了XD 我在裡面問了路人,穿制服的,還有賣涼水的,跑來跑去才找到東口。出來以後又問了賣零食的,才確定沿大馬路一直走就會到 (可是在出口這邊完全看不到,不曉得要走多久XD)

不過只有一直線也不太可能再迷路了 (沒那麼路癡吧XD),基本上走過去就知道了,一到路口就看到掛著淳久堂招牌的大樓。其實我還蠻喜歡這家書店的招牌配色,店員的制服也是這個配色,感覺就很有書店的味道。台北的分店也是一樣的配色,每次去台北只要時間充裕就會過去看看。

一進去大樓後當然又瘋了,雖然腳已經因為迷路走到快斷了,但一進來後還是從地下一樓開始往上逛,看到一堆書都想搬回家,所以在理智還沒崩潰前趕快找到想買的書,離開這棟大樓XD



回到上野後差不多六點,又要開始煩惱晚餐。走了一整天實在是餓得要死,中午的親子丼好像完全都消化掉了XD 在車站外面逛了兩圈,這邊還有一大堆沒吃過的東西,連吃個晚餐都得做出困難的選擇。來日本那麼多天還沒吃到拉麵,也沒吃到和牛,剛好都是這附近吃得到的。

最後到アメ横附近的一家鰻魚飯,光看到廣告看板上的色澤就受不了了,管他是不是名店,先進去再說XD 雖然沒有研究過是什麼店,不過這鰻魚飯已經很好吃了 (再加上肚子餓XD),雖然只有一塊鰻魚,但應該再配個一碗飯沒問題!

吃飽以後又跑去附近的玩具店了,因為離飯店很近,所以是這一趟唯一去兩次的點。在門口看到一個比較貴的化物語轉蛋機,雖然 400 實在有點貴,但還是決定在這裡獻出第一次轉蛋經驗。最後轉到的是戰場原大人!不過我覺得這戰場原大人好像有點邪神化的傾向XD

今晚是最後一晚睡席夢絲名床啦,在睡覺前得先整理好行李,確認還有多少空間可以塞東西XD

然後,祈禱明天不會睡過頭,錯過回家的班機吧XD


Filed under: Japan, Travel

» 2012 Sep‧東京 Day 5 – 1

2012.9.18


準備出發去台灣啦~不對,是要回台灣XD 在車站看到兩本台灣旅遊指南,正好研究一下外國人到台灣都跑哪些景點。內容懶的拍了,大概就是日月潭、九份 (廣告內還強調有日本動畫電影的場景XD),或是日籍建築師 (森山松之助井手薫等) 設計的建築巡禮。吃的部份大概就鼎○豐、士林夜市和担仔麵。也可以搭高鐵 (在日本叫做台湾新幹線) 到台南逛古蹟,或到高雄逛號稱台灣塞納河的愛河… 這是廣告說的,不過前幾年去過一次,跟小時候的印象的確差很多,變得比較漂亮了。

今天是最後一天自由日啦,除了跑一趟汐留外沒什麼一定要完成的計劃,大概就是到處跑來跑去吧 (完全就是毫無計畫的旅行XD)。



因為在動物園附近才取名為貓熊橋嗎?


早上一如往常睡過頭,起床時已經快八點了,不過在台灣還是七點而已,平常根本不會那麼早起吧XD 原本的規劃是往南邊沿路玩,想了一下大概就是秋葉原,東京,汐留這幾個點。由於一般的店可能十點左右才開門,所以吃完早餐後上網查了一下,決定先到上野附近走一走。

走到上野公園那一帶,看到很大的烏鴉了,近看還蠻有迫力的。雖然是非假日的火曜,但一路上還是很多人。一到公園馬上就明白了,原來是美術館的圖坦卡門展啊,還沒看到美術館就已經可以看到排隊的人龍,真的是非常受歡迎的展覽。不過公園很大,不看展也有很多地方可以逛。


觀察了一下排隊人龍後,看到旁邊有一個清水観音堂的牌子,雖然沒有事前研究這些景點,但看起來可以進去逛逛。根據網頁的說明,這裡供奉「子育觀音」,可以來求子,或祈求安產之類的。九月底會有「人形供養」的法會,似乎是還願用的。


附近還有西郷隆盛像和彰義隊の墓,分別代表幕末上野戰爭時的新舊政府勢力。雖然這兩個地點都有詳細的文字說明,但對幕末史不熟,也沒事前研究景點的狀態下,看了半天對於事件發生時的勢力分布還是沒能搞得清楚 (明明就是日文太差…)。根據後來查到的資料,在彰義隊等舊勢力瓦解之後的幾年內,日本就進入明治政府的時代了,江戶也從此改名為東京,應該是一場很重要的戰役吧。比較有趣的是查到這時參戰的關鍵裝備,其實是不忍池有佐賀藩的兩門アームストロング砲,讓新政府軍取得勝利。雖然是從某動畫知道這個名字,但原來真的跟這群人有關係XD



逛了一圈後發現時間差不多,離開公園時發現對面的ヤマシロヤ已經開門了,本來打算明天才去的,但看到眼前就是店門口,還是忍不住進去了,原本應該去坐車的計畫馬上修改成逛玩具店XD 這間玩具店其實是一整棟大樓都在賣玩具,從地下一樓到五樓 (不是 PTT 那個五樓!),每一層樓都是不同主題,種類之多讓人目不暇給。

下一個目的地是秋葉原。說到這個地方,雖然知道是電器和 ACG 文化的集中地,但對於現在流行的萌系文化除了覺得可愛外並沒有特別的喜好,所以對這個地方一直沒有什麼認識。除了去見識一下之外,真要說想去的地方大概就是 Gundam Cafe 了。



不過在這之前還有更重要的任務,就是去找一下機器人零件店 Robot Shop テクノロジア。在車上研究一下地圖後,發現這是很重要的中繼點,因為可以順道去吃好吃的午餐。由於只要沿著鐵路走就會找到,雖然忘了帶地址,但只要記得這件事還是可以很容易找到。到了以後發現是個小到不行的店 (日本除了連鎖商場外,幾乎都是小店嘛),不過裡面的零件倒是不少,很容易可以買到各種機器人能用的零件,但價格都不便宜,所以逛了半天還是空手出來XD 看時間差不多,就去尋找午餐的地點了。

今天的午餐就是親子丼啦,目標當然是秋葉原的鳥つね自然洞。雖然昨天已經吃過一次,但沒吃到名店實在不甘心。所以特別跑一趟秋葉原,就是一定要吃到傳說中的親子丼。這家店隱藏在巷弄間,但因為沒帶地圖所以完全不曉得在哪,只知道在附近;想抓個路人來問也很難,不曉得是不是因為離電器街有點距離,附近的路人實在有夠少。



根據事前查到的情報,這家店的午餐是十一點半開始,這在之前會有很多上班族來排隊,但在附近繞了半天,走來走去就是沒看到排隊的人龍。最後只好每條巷子都看看,總算在附近的一條巷子裡找到了。

結果等到開門時間也還是沒看到半個人,我就自己敲門進去了。如果沒有先調查過,我肯定會認為這是不好吃的店吧XD 這個地方的午餐有限定 20 份的特上親子丼,看到「特上」就夠讓人衝動了,更別說是「限定」啦!馬上就點了特上親子丼。味道跟昨天吃的根本是不同等級,其他的請自己看照片吧,總之就是看到照片後會想再跑一趟的美味。


吃飽以後在附近逛了一下,再到電器街周邊繞了幾圈,完全沒看到半隻女僕啊!不是聽說會有女僕在路上發傳單嗎,還是都跑去吃午餐了?再繞了一下沒看到,因為後面還有地方要跑,就決定先到 Gundam Cafe 去了。

地點很好找,一出車站就看得到。進去前先亂拍了一下門口的 RX-78-2,但雙馬尾店員帶我進去時,因為沒聽清楚在說什麼,結果被發卡… 不是,是被發了英文菜單了XD 這恥辱就算了,問題是英文菜單很難懂啊,還好桌上有一份日文的,順利點了咖啡和冰淇淋。吃到一半發現隔壁大樓跑出一大堆女僕,連旁邊的日本人都說真壯觀,但東西吃到一半也不好出去啊XD 這個點實在是很不順利啊,沒有一件開心的事XD 不過咖啡還不錯就是了。

(待續)


Filed under: Japan, Travel

十月 6, 2012
» 2012 Sep‧東京 Day 4 – 2

2012.9.17



吧台座的好處就是可以很清楚看到裡面的工作情形。我被帶到最靠牆的位子,還分配了一個位子讓我放包包,算是有一點私人空間吧。我面前剛好是煮咖啡的地方,畢竟是個有管制攝影的地方,就問了一下店內能不能拍照。面前的店員大哥說拍桌上的東西就好,周圍盡量不要拍,我就很開心地亂拍桌上的所有東西,結果一得意忘形就拍到天花板去,果然被制止了XD

桌上的裝飾燈很漂亮,燈罩上還有龍貓的圖案,應該是特製的吧… 既然放在桌上,我就不客氣啦!光那盞燈就拍了好幾張!但桌面的範圍就那一點大,後來已經拍到沒什麼好拍的,只好到處東張西望。店裡大部份都是一家子來的客人,到處充滿小孩子的笑聲,但還不到很吵的程度。在這樣的地方,我可以稍微放寬標準。我喜歡安靜的地方,在日本的這幾天中,只有在居酒屋或這類家庭導向的餐館有人交談,其他地方吃飯時都相當安靜,這讓我覺得很安心。亂想一陣後咖啡就送上來了,原來就是在我面前煮的那杯啊~

我點的東西不多,而且也只有一個人,店員大哥不曉得是不是看我很無聊,就試著找我搭話聊我的相機和新的 RX-1,還有一些來美術館的閒聊。不過我本來就不太擅長跟陌生人聊天,只能一邊品嘗美食,一邊有一句沒一句聊。根據幾次找路人問路的經驗,對方講的大概都能聽懂,但只要多講個幾句就會露餡XD 但坐吧台座真的很有趣,至少有實際的經驗後比較有努力的方向了。



滿足了胃以後,回到館內從一樓開始重新逛起。首先就是去排電影,一個小時內有三個放映時段,最好提早十分鐘去排隊才有座位。館內的氣氛很棒,到處都是歡笑聲,不曉得是不是因為這樣,館員大姐姐們的臉上也一直掛著微笑。其實美術館不大,但一進入館內,心就變回大孩子了,比那些被抱進來的小鬼還亢奮XD 每一層樓、每一間展覽室應該都繞了好幾次吧,每一項展示品都恨不得拆下來帶回家,大概逛了四個多小時才走得出去。



出來以後是井の頭恩賜公園,這公園實在大到不行,在美術館已經走了好幾個小時,所以光看到地圖就沒力了,只能挑一條路線走回去。走出公園後因為四週都很漂亮,就隨便找了個方向亂走,想要邊走邊找車站。不過走了一小段路後,完全不曉得車站還有多遠,剛好這時看到一個公車站牌,好像幾分鐘就會有一班車,猶豫了一下就挑了一班車上去了XD 這班車不用投錢了,可以直接用 suica 嗶嗶。由於沒研究過公車路線,也不曉得會把我載到哪,結果大概十分鐘左右就到達吉祥寺駅了XD

其實今天的預定行程已經結束,剩下的時間都是用來迷路的,結果到了吉祥寺駅後想起一件事,馬上又有新計畫了。在車站附近的商店街有不少好吃的東西,最多台灣人提到的就是さとう的メンチカツ (炸牛肉丸) 了,這時其實不太餓,但總覺得應該還是得去朝聖一下,沒想到商店街的規模太大,繞了一下路才找到XD



到了店門口以後才發現,其實也不用刻意找,門口很多人排隊的地方就是了… 未排先猜隊伍裡有一半講中文的XD 不過看到一堆人在排隊,我反而不想排了,只是留個照片就離開牛肉丸,繼續執行下一個新計畫。

新的計畫是這樣的,在車站前面看到 Book off 的廣告,雖然已經預定明天去秋葉原店,但既然眼前已經一間,先逛逛探個路也好。沒想到在商店街繞來繞去還是找不到。廣告只說在ヨドバシカメラ旁邊,問題是我連吉祥寺店在哪裡都不知道XD 大概在商店街逛了半小時才找到,原來在不在商店街裡XD

一進了 Book off 後又瘋了,書怎麼那麼多!價格又那麼便宜!從一樓逛到四樓,在裡面逛了一小時後覺得再逛下去應該會拿不動,只好趕快結帳離開這個地方XD 還好文庫版不重,雖然買了十幾本小說還是很輕,重量其實都在畫冊和設定集上XD 買了一堆書,其實總價才台幣 1500 而已,這裡實在是寶庫啊!但是買了那麼多小說,以我看日文書的速度不曉得要看幾年才看得完XD



車站內的廁所,衛生紙補給箱和沖水感應器蠻有趣的


帶著戰利品走回車站,因為不是中央快速的停靠站,只好坐慢車到下一站中野。中野的商店街也是很有名的旅遊點,而且號稱是宅男聖地,當然要去見識一下宅男長什麼樣子XD 其實我本來沒有打算走購物團路線的,不曉得為啥一直跑到容易花錢的地方XD

走進商店街後,直衝二樓和三樓果然看到很多動漫商品,也有不少二手漫畫。不曉得是不是因為下午的關係,昏暗的光線讓我覺得不太舒服,逛了幾家玩具店後,什麼都沒買就出來了。我比較有興趣的是プラモ (塑膠模型),但買了很難帶回家,就算帶回來也未必有時間做,想一想就買不太下去了XD 這裡本來應該要有很多照片的,但因為手裡提著東西很難拍,回來後一整理才發現只拍了幾張… 反正也沒有什麼非拍不可的畫面。雖然離開商店街時還不到六點,但已經是又餓又累的狀態,決定隨便在附近找家店吃晚餐了。

這次的目標是親子丼。在出發前已經調查果有很多家好吃的親子丼,結果到現在什麼都沒吃到實在很不甘心,所以就算是隨便進去的店也要點一次來吃XD 最後找了家麵店 (好像是什麼賣蕎麥麵的連鎖店),不過這麵店做的親子丼還是比在台灣吃過的好吃一萬倍啊!




實在吃了不少肉,到超市買了半價西瓜,果汁,和有果肉的果凍

吃到親子丼以後大滿足,在附近又逛了一下才準備回上野。回程一樣亂搭車,結果跑到秋葉原駅剛好可以轉車回去。但今天實在是走太久了,一回到房間就把戰利品之一的「休足時間」拿出來貼,聽說是到日本必買的東西之一。邊看著電視邊休息,沒想到電視上正播著跟初音有關的節目,初音在日本已經超脫軟體,成為真正的藝人了嗎XD 看著看著,總覺得這休足時間還真神,貼上還不到一晚腳已經不痠了,看著時間還早馬上決定到上野駅的超市買點心回來。

雖然日本的店家都七八點就在關門了,但也有少數開到很晚的店。十點多走到上野駅時,超市裡還是有不少人在逛著,但大部份看起來像是買土產的旅客。超市裡的東西還不少,也有看到半價便當,但太晚去了所以沒辦法見識一下傳說中的便當爭奪戰XD 這次的目標是水果,所以只隨便逛一逛,找了一些跟水果有關的點心就回去了。



戰利品晚點名… 基本上那幾袋裡面都是書,規模跟真正的採購團相比很虛XD

這趟迷路期末考之旅已經完成一半了,但今天實在挺累的,晚上邊整理戰利品,一邊檢討今天用錯的文法XD 希望明天講錯的次數要更少一點!


Filed under: Japan, Travel

» 2012 Sep‧東京 Day 4 – 1

由於這些遊記都是當天晚上記錄的,寫到 Day4 才想到發表時應該要記錄一下實際的日期才對,否則內文都用「今天」「昨天」來表示時間,以後看文章可能會混淆記憶。萬一以後忘記日期,就用相對 PyCon Japan 2012 的日期來查好了XD

2012.9.17

從今天開始沒有人跟我講中文啦,走錯路沒人可以商量,也沒有上網手段可以查地圖,手中只有一份車站拿的簡易地圖,完全是一個人的大冒險。

東京在台灣人喜歡的旅遊地點中,應該是排前三名吧。隨便上網搜尋一下就是一堆遊記和食記,對於沒去過的人來說,有這些文章和照片可以安心不少,但缺點就是情報量實在太大,對於一個完全不認識日本的人來說,很難判斷哪些是重要資訊。我看到最後根本整理不起來,索性就不看了XD 後來決定的策略是挑幾個我想要去的點,然後其他時間就在附近邊吃邊玩。這樣做的優點是相當自由,完全沒有行軍壓力,但缺點就是很難估預算XD

由於我很喜歡 Studio Ghibli 的作品,最早想到的地點當然只能是江戸東京たてもの園ジブリ美術館,一個是神隱少女取景的地方,另一個是不用再解釋的聖地。要命的是這兩個點在同方向,但休館日剛好錯開XD 由於一開始還想著排一天到築地市場,考量到禮拜一剛好休市,改禮拜二去的話行程會跟建物園打架,只好忍痛放棄建物園。(結果最後根本沒去築地XD)

本來以為連休館日都考慮到了,這樣安排大概沒辦法再改… 沒想到禮拜一是敬老の日,剛好是祝日 (算是國定假日吧),所以建物園隔天才休館,禮拜一去根本沒問題啊XD 總之在情報不足、日文不好再加上自作聰明的情況下,漏掉一個想去的景點了XD 自己安排果然很容易出錯,就當作學一次經驗吧。


總之最後決定行程就是去美術館,其他時間看著辦。根據山手線的路線圖,比較簡單的移動方式就是先到神田駅,再轉搭中央線到吉祥寺駅。不曉得是不是前一天太晚睡,等我醒來時已經快九點啦!而想第一批進去的話得在十點前開始排隊,事前查過從上野過去差不多要一個小時,還沒算進迷路的時間XD

到了神田後,因為時間越來越少,看到有一輛車進站時趕緊問路人有沒有辦法到吉祥寺,沒想到路人也不曉得XD 不過時間急迫,看到車子進站只好跟著大家一起衝上車,反正車上都會顯示停靠站。上車才知道原來這班車是只停大站的中央快速,雖然不停小站可以快一點,但也因此不會停吉祥寺,只能在下一站的三鷹下車XD 事前沒有作功課的結果,我也不曉得三鷹站到底離多遠,光看手上的簡易地圖的確是吉祥寺駅比較近啊~只好把搭快車省下來的時間拿來迷路了XD



到三鷹站以後比預定早了十分鐘下車,但不曉得走到美術館要多久,原本想悠閒地沿風の散歩道走過去的計畫當然也泡湯啦。正當我在路口當機不曉得往哪個方向走時,瞥見車站南口左邊有一堆人在排隊,好奇過去看一下才知道原來是傳說中的龍貓接駁車!不過這次本來打算用走的,完全沒研究公車要怎麼搭,很怕一上車就被載到奇怪地方去了XD 搭車的地方有便宜的來回票 (往復乗車券) 的販賣機,但我實在不想一直坐車,問了一下旁邊的乘務員,確定單程可以在車上投錢後,眼見時間所剩不多也只好硬著頭皮排隊了。

幾分鐘後公車過來了,大家都拿起相機狂拍,我當然也要跟風啦,光是那輛公車就拍了好幾張XD 日本的公車跟印象中台灣的公車不太一樣,地板蠻低的,不曉得是不是為了讓行動不便的人上下車才設計成這樣。上車後投了錢以後可以找零,不熟的話司機也會引導,在大城市搭公車實在很方便。


其實沿途的景色是很漂亮的,我喜歡這種一片綠意的地方,但這場得趕時間實在沒辦法慢慢欣賞啊XD 從車站過去大概是十分鐘的車程,剛好可以在十點前到達美術館門口。美術館的入場時間是有場次管制的,但聽說台灣買的票隨便哪一個場次都可以進去;今天的計畫是先趕最早的十點那一場,然後抓緊時間去餐廳排隊吃午餐 (聽說人會非常多,要提早排隊)。雖然從一起床就一直偏離計畫,不但睡過頭還亂搭車,幸好最後的結果還不壞😀



到達的時候門口已經很多人了,意外的是排在我前後的都是台灣人XD 排隊的時候工作人員會先來查票,在台灣買的票好像不太一樣,所以工作人員一開始先用英文確認,但發現我可以用日文後改用日文交談。不過看到我在吃早餐還提醒一下館內不能吃東西,因為一路上都在趕車,只好趁排隊時趕快把早餐吃完XD

首先要在門口領電影票,一個人一張票可以看一次館內的短片;領票時好像沒看我的護照,我走過去後就直接給我票了,而且給我票的小姐會講中文喔。入館後其實還得經過一道長長的樓梯,所以站在門口其實也拍不到什麼,只可惜沒拍到漂亮的換票小姐。



這裡的攻略是這樣的。如果有機會十點入場,建議先去排電影,大概 20 分鐘會結束。因為電影通常會有很多人排,開場時是最好排的,而且電影有放映時間,看完就可以悠閒地逛其他地方。而餐廳是十一點開始營業,所以看完後差不多時間可以去餐廳附近逛一逛,就近準備搶位排隊。不過我一進去根本就瘋了,誰還會記得這些小事XD 一下去就先衝右邊的展區,然後又跑去紀念品區先探路。接著又看了插畫展,然後邊看一堆小鬼玩那隻貓巴士邊流口水。等到我想起要排隊時已經迷路… 不,應該是說走不出去的感覺XD

館內餐廳的名字叫「麦わらぼうし」,意思大概是草帽之類的東西。等我找到餐廳後,發現已經有一堆人在排隊了XD 餐廳內空間很大但位子不多,大概是為了不讓客人覺得很擁擠。但也因此需要更早去排隊搶桌子XD 因為我只有一個人,所以可以被安排在吧台座 (カウンター席),順利進入先發名單。

(待續)


Filed under: Japan, Travel

十月 1, 2012
» 2012 Sep‧東京 Day 3 – 2

聽完 Keynote 後大滿足。接下來的時間基本上都待在 NVDA 場。這一場有不少視障者參與,連導盲犬都進來了,在技術導向的活動中可以聽到這樣的分享,實在是出乎我意料。聽完 Michael Curran 介紹開發 NVDA 的歷程,知道有人一直努力用技術的力量改善人類的生活,心裡是很感動的。到了最後問答時間,果然有人問他當初是怎麼學程式開發的XD 沒記錯的話他說是在大學裡學的,但為了開發 NVDA 好像沒有完成學業,就一直持續到現在了。

接著是來自台灣跟日本的 NVDA 社群分享。雖說是社群,但好像人數非常少,在中日語系這一塊還有很多努力的空間。這次跑一趟可以接觸到以往不曾留意過的領域,也是很大收獲之一,看看以後有沒有機會幫上忙囉。



聽完 NVDA 在台灣和日本的發展情況後,我馬上趕場到分享 DSL 教室。一直覺得日本應該很多覺醒之人,覺得 Python 不能只有這樣,所以等這場已經等好久了,很想聽聽在 Python 到底還有什麼新把戲可以玩。

Some lang are not good at internal DSL
All languages have same power about external DSL

一開場就提到 Python 不適合用來做 internal DSL😄 不過我早就放棄幹這件事了,所以看到以後也沒感覺到什麼衝擊就是,只覺得理所當然是這樣。接下來先介紹了利用 with 來達到 wrap code block 的方法,主要是為了在 code block 的前後加上額外的程式碼。說到這個,Python 的語法幾乎沒有提供封裝的空間,一般得自己另外想辦法,但這樣的 Python 卻出現一個可以透過 import module 就改變語法的功能,因此個人認為 with 語法在 Python 應該算是一個逆天的存在 (至少未內建 with 的版本中成立),因為它剛好是官方開的後門。

接下來是以 benchmark 的需求為例,說明使用 dummy generator 模擬 with 的做法。根據講者的經驗,這種方法比起 with 多一些彈性,畢竟 with 已經把控制流程做死了,沒辦法自己調整,而透過 generator 中的 for 等結構還有機會自己改變內部執行的控制流程。除此之外還介紹了用 Decorator 設計 DSL 的方法。這也是我常用的方法,畢竟這也是難得 Python 會主動提供的奇怪語法。

雖然是很期待也聽得很滿足的一場,但不出意料沒聽到什麼新招。有空的話會再試著用 generator 玩玩吧,除非還有高人指點逆天之法,不過應該不會放太多心思在上面了。


閉幕式的時候很幸運又抽到衣服了!結果這次帶來的衣服多到穿不完XD

這幾天的體驗下來,這次 PyCon Japan 分享內容的難度平均來看大概就中等吧,雖然入門分享偏多但主題的種類比較多樣;Web 相關的題目也不少,但不會讓人有多到泛濫的感覺,跟台灣的研討會很不一樣。活動的花樣還蠻多的,除了 Welcome Party 和團體自介外 (聽說有但沒參加到),這兩天有 Open space (類似 BoF),還辦了線上程式比賽。雖然食物太少有點美中不足,後來有發現飲料可以喝到飽小小彌補一下XD



結束兩天的活動後,接下來的時間都是自由行程。根據出發前的調查,九月到東京幾乎沒有什麼祭典活動了,比較接近的大概就是淺草燈籠會。從網路上的情報得知這個活動不會很熱鬧,大概就是去走走,看一下燈籠和夜景這樣。



雖然七點半就出發了,但我們到那邊時竟然已經快九點了。淺草寺供奉的是觀音,不曉得為什麼到了晚上還是很多人。不過晚上店家都關著門沒什麼好逛的,所以一行人直接就殺到裡面的燈籠會的會場。今年的燈籠會主題是「陽(のぼる)」,如果我沒誤會網頁上的說明,意思是希望透過這次的活動點亮人心。不過當天不是點燈式,所以沒看到什麼特別的活動。

這裡還看得到一座五重塔,這時我想到的是被兩津整座幹走的那個五重塔,後來才知道原來日本的五重塔不只一座。夜間的淺草寺相當漂亮,再加上燈籠會的加持,非常值得走一趟。不曉得是不是我們只停留在最外面,雖然看到燈籠了,但數量並不多。一行人在這裡拍了一些照片後,由於抵擋不了饑餓,決定先去外面覓食。


在淺草寺逛了半小時,最後還是決定找一家有生魚片的店解決晚餐,這時找到的店家是すしざんまい。由於這次東京行的目標完全沒有生魚片,所以沒有特別調查生魚片的情報,不曉得這家店怎麼樣。這家的賣點好像是マグロ (鮪),當天點了中とろ和上穴子 (鰻),吃了以後覺得還不錯。另外就是我喜歡的蛋料理:茶碗蒸和玉子燒,玉子燒跟預期一樣偏甜,但超好吃!茶碗蒸的料相當豐富,基本上我都很努力地吃,幾乎沒拍到照片XD 我還點了一碗生魚片蓋飯,魚的部份還不錯,不過我對冷冷的飯比較無愛,而且也已經飽了,實在沒辦法吃完。我一個人就吃了三千多日幣,是這次花最多錢的一餐XD



滿足了胃以後,由於時間也晚了,大夥到了地鐵站以後就鳥獸散了。等大家都走光後才發現,這是我第一次搭地鐵啊XD 不過這時膽子很大,所以看了下可以搭到銀座線,印象中好像可以回上野吧,就直接跑進月台等車了。這時剛好看到一輛車離開,有點緊張會搭錯方向,就隨便抓了一位長得很像松本秀樹的路人 (寵物當家節目中,帶著雅夫、大介到處跑的藝人),想問問到上野的話有沒有走錯月台。結果松本兄 (直接改名了XD) 直接說要帶我搭車,要我跟著他就好。這時實在很感動啊,但結果發現我直覺選的月台根本沒錯呀XD 但搭車時有個伴還不錯,就跟著走了。

在等車的時候聊了一下,聽到我是台灣來的時候挺高興的,說前幾年也來過台灣,還分享了去過的地方… 沒意外就是台北、九份跟鼎○豐XD 不過還是得解釋一下我不是留學生,所以對地鐵路線完全不熟XD 對方也很體諒我這個外國人,雖然可以進行簡單的對話,但發現我理解錯的時候會主動再解釋一下。從淺草到上野非常近,搭銀座線不到十分鐘就能到上野站。由於松本兄要到上野站轉車,所以剛好可以帶我回來,離開前還詳細指點了回旅館的路。雖然我已經快變上野站達人了 (自稱),但還是承他的情,畢竟有個當地人領路還是安心多了,非常感謝他對外國旅人的協助。


回到上野後,馬上要進行另一個實驗。在出發前已經預先訂了一直很想買的東西送到 Lawson,早上看到信箱出現到貨通知後就一直等不及去取貨。結果一直到十一點多才取貨。旅館的附近就有三家 Lawson,我挑了距離最近的,進去找了台叫 Loppi 的機器印出提貨券,馬上就能拿到東西,感覺比台灣的超商取貨方便多了。不過因為留在日本的時間不長,萬一延遲送貨就GG了,所以這個實驗其實有點冒險… 還好兩天就送到了。

那張 CD 是我一直很想買的,應該算是岡崎律子的遺作,這次總算是出手了。其實玩遊戲的時候就已經把所有歌都聽到很熟了,岡崎自己唱的版本也在其他地方都聽很多次了,但沒收藏到 CD 想聽的時候很不方便,幸好過了那麼多年還買得到這張 2005 年發行的 CD。

明天開始就是一個人的大冒險了。


Filed under: Japan, PyCon, python, Travel

» 2012 Sep‧東京 Day 3 – 1

以現在的整理速度推測,應該會寫到十月XD

這兩天整理了一下照片跟收據 (領收書),發現上面的資訊還蠻有趣的。費用細項當然有,其他除了日期時間外,竟然還有責任者或担当者之類的資訊,實在蠻有趣的。除了照片以外,收據上的資訊也對恢復記憶有幫助。雖然我每天都會做一些活動記錄,但記錄的細節隨著一天天過去變得越來越少,有必要另外想辦法幫忙記憶XD 再加上相機不是隨時開著拍,很多遺失的片斷都是靠收據回想起來的 (東西買太多?)。



爬上這個階梯時腦中突然浮現《上を向いて歩こう》這首歌的旋律

回到大冒險之 PyCon Japan 二日目。

雖然昨天晚上喝了一晚啤酒,回來後又邊看中川翔子唱歌邊睡著 (印象中看到三點XD),但好像沒什麼影響一樣,今天竟然起了個大早。

雖說起得蠻早,但也已經七點了,今天打算好好在樓下吃早餐,目標多喝一點果汁。得意忘形的結果就是鬧了一個笑話,原來吃完要自己把餐盤送回去,我一直到隔天早上才發現櫃台旁邊有寫XD



今天第一場的時間從十點開始,因此預定的行程很單純,就是十點要出現在會場。(自以為)已經攻克山手線的我當然沒在怕,看時間還有一個小時就很隨性地決定先去上野駅附近逛一下。假日早晨的車站很寧靜,裡面的店家還沒開,搭車的人也很少。在裡面發現儲值用的機器後,馬上又存了一點錢到 suica 裡,總算又安心下來了。

大一點的車站好像都會跟百貨商場アトレ結合在一起,上野駅也是這樣的車站。不過因為時間不多,還得留半個小時搭車到學校,所以只是在一樓逛一下而已。這時還早,所以大部份專櫃和店家都沒開,只好到 JR 遊客中心晃晃,看一下觀光資料。一般大一點車站都有不少觀光情報可以免費索取,逛車站時意外發現有台灣的觀光情報,覺得很有趣就拿了兩種回來。後來翻開一看,裡面根本每個行程都是九份和鼎○豐嘛!難怪每次都聽到日本人來台觀光必去這幾個點,根本就來自旅遊指南XD



這陣子上野的美術館剛好有圖坦卡門特展,所以整個上野駅到處貼滿廣告和裝飾,周邊也有人在廣告宣傳。我自己是蠻喜歡這類埃及的文化展,以前還曾經有朋友到埃及玩,帶了紙莎草做的書籤送我。之前在台灣的展覽沒去,這次的停留時間太短也排不進去,實在很可惜XD

上野駅內的結構有點怪,不曉得是不是因為沿著山坡建造的關係,往月台移動途中有很多階梯。另外就是站內很多樑柱和高低不平的天花板,感覺像廢棄工廠改裝的一樣。車站內還可以看到秋葉原女僕咖啡廳的廣告,據某位大大的說法,這家是創始店。但那時我看著這廣告看板,腦中想起的是出發前不曉得在哪個 blog 看到的分享:那些寫著中文的店通常會比較貴XD



禮拜天的電車還是有很多人搭乘。在前往大井町駅的途中,雖然我不是坐在博愛座,但我還是把座位讓給一位後來上站、帶著兩個小孩的媽媽。我站起來請她坐的時候,她好像嚇了一跳,該不會在日本隨便讓位是很奇怪的行為吧?但她還是跟我道了謝,讓兩個小孩坐著。這次在日本常常搭車,也有好幾次讓位的經驗,倒不是刻意要搞什麼國民外交,只是單純看到有帶著小孩子的人站著就會不自覺讓出位子。禮拜一是敬老節,日本的國定假日之一。電視和餐廳都看得到相關的活動宣傳,不過這次看到的老人不多,大概要往鄉下跑比較容易看到。

第二次轉搭りんかい線已經熟門熟路,直接就衝到月台等車。

到學校時剛好十點,只好直衝 351a 聽 PyPy。這場講的是 JIT 的部份,但是我前面有一小部份沒聽到,結果很晚才進入狀況XD 到了 yyc 登場的時候,人數少了一大半XD 不曉得是我不是我失神沒聽清楚,努力聽完還是沒聽到解釋 High Performance 的部份。不過就算聽到大概也是鴨子聽雷,就沒那麼在意了XD 不過可喜可賀的是,我總算搞懂怎麼在 WindowsXP 設定抓不到 SSID 的無線網路了。一連上線才發現擋了一堆 port,沒辦法 ssh 回家XD 這下學到以後出門前要先把 port 改到 80😄



比起網路和偏微分方程,這時我更在意的是午餐。聽了兩場耗腦力的 session,實在是餓到不行啦。好不容易撐到午餐時間就直接到餐廳用餐了… 沒想到出現在眼前的還是三明治orz 還好有四種口味,選了個跟昨天不同的口味吃吃看,還是可以接受啦。

吃飽喝足後就是重頭戲 Open Space 啦,感覺起來是類似 BoF 這類活動。為了補足昨天沒聽到 Blender 的遺憾,特地挑了一場 Blender 相關的,沒想到只有兩三隻小貓,而且只能在大教室的後面小塊空間進行XD 雖然都聽得懂在講什麼,但時間關係只講了些 Blender 的基本操作,實在也沒啥好討論的。接著趕 Arduino 場。但跑到目的地後發現教室裡有不少人在休息,卻完全沒有 Arduino 相關討論的感覺。坐了一下覺得很無聊,就跟 kanru 一起去找其他人了。



這次比較出我意料之外的是,hychen 自從接受 FLOLAC 的洗禮後,好像某個開關被打開一樣,這兩天一直找我分享 programming language 的東西。而且從言行來看,這人根本已經病入膏肓,滿腦子邏輯了XD 不過看到有人開始朝著「正道」(?)前進,還是覺得不錯啦,希望台灣可以有多一點人可以聊,不然有問題都不曉得要問誰XD 除此之外就是一直找 kanru 幫他調整 Emacs 的設定,但 Emacs 這種東西實在不適合東抄西抄。我比較建議從預設環境開始調整,自己覺得不好用就改設定,最後才能調校出適合自己編輯習慣的環境啊。

結束 Open space 的時段後,去聽第二天的 Keynote

這場還蠻有趣的,例子裡面一堆廃怯少女。拿 import __future__ 還有學姐當哏超好笑,我對這部作品其實完全不熟,只是看到有用典就覺得很有趣,比較好奇的是在場的人好像都聽得懂的樣子XD 然後把 Zen of Python 一條一條拿出來討論。還提到 unicode 在 Python 的問題:

Who in the world trusts your code sample if len(u”\U0001F40D”) varies?

我自己試了一下,手上三個版本的 Python 跑出來的結果也是不一致的XD

もう何も怖くない (● ω ●)

(待續)


Filed under: Japan, PyCon, python, Travel

九月 26, 2012
» 2012 Sep‧東京 Day 2 – 2

中場休息在外面聊天的時候,遇到也是來自台灣的 NVDA 開發者,來這裡分享台灣的發展情況。NVDA 是一套自由的螢幕閱讀軟體 (screen reader),這類軟體可以讓視障者也可以順利操作電腦。出發前曾經稍微瞭解一下這套軟體,讓我想起幾年前 NHK 曾經播過一齣跟熱血盲人教師有關的戲,叫做チャレンジド (Challenged)。戲裡介紹了不少視障者的生活情況及訓練的過程,也有操作盲用電腦的鏡頭。看過那齣連續劇後才對盲用電腦系統有一點基本的瞭解。前陣子剛好有看了一點輸入法的東西,也許可以趁這個機會瞭解一下 NVDA 跟輸入法的整合。



在吃飯前還有一場,因為 hychen 的主題聽好幾次了,所以大家拋棄他跑去聽了「關於 Python 程式設計教育的考察」。這時 Room 230 已經開了空調,突然對人類文明的進步充滿感激啊~這一場的講者是學校助教,先對學校做了些宣傳後才開始介紹基本的 Python 概念。雖然接觸 Python 快十年,但不熟的地方還是很多啊,例如在 Python 中所有的物件都是 immutable!我到現在才知道XD 示範的例子很簡單:

以前在 irc 上曾經有聊過從 id 取回 object reference 的方法,但現在知道運算後 id 會變,想把 id 當作 hash function 的話在大部份情況可能會有問題。






在報到處領到衣服後就是吃飯時間啦,往學校餐廳移動的路上,看到很多有趣的海報😛 很多都是有漂亮女生,或是用漫畫方式表現的海報。這時候就很有來到日本的感覺了😛

午餐發放餐盒,有幾種口味的三明治和飲料可以選。雖然吃了不會餓,但總覺得有點空虛啊。食物的部份果然還是 OSDC.tw 大勝!PyConTW 也好太多了 (可惜不太夠吃XD)。說到食物,之前有人說過研討會三寶是 食物網路正妹 (來源請求XD),今天一整天都沒辦法搞定網路實在讓人很不爽,雖說我沒有網路也不是問題,但難得一次帶電腦參加活動卻沒網路,怎麼想都很不爽啊!另外正妹的部份也是台灣大勝!就這三點來看,這次 PyConJP 實在不及格呀XD





下午的議程因為跑錯地方,忘了去聽 Blender 場XD 除此之外沒什麼特別想聽的,所以直接泡在英語場了,結果意外有趣,內容比較偏整合應用,抓一些資料來做圖表之類。其中比較感興趣的東西還是 ZeroMQ 的部份,用的人似乎不少。最後的 Lightning Talk 也蠻有趣的,竟然找了一個小鑼 (沒打錯字XD) 來提醒講者時間!不過沒把準備時間算在裡面,時間一到也不會拔線關麥克風,讓整個活動的緊張感下降不少,這部份還是台灣版比較有趣。不過報名 Lightning Talk 的人很多,其中外國人也不少,這真的挺意外的,印象中 PyConTW 好像都是台灣人?

這次到 PyCon Japan 看到蠻有趣的是有許多合併舉辦的主題研討 (併設イベント),前面提到的 NVDA 就是其中之一。除此之外比較有趣的就是 Sphinx,竟然有人拿它來做 DSL 啊,真是意外的玩法!雖然我以前也用其他套件做過類似的事,但當初看到 Sphinx 只單純想到文件產生器,完全忘記背後是 Python 的話就可以隨我改造成特裝引擎了。

另一個我覺得還不錯的地方是針對每一個 session 都標註聽眾程度要求,雖然不見得準確,但至少是個參考的依據 (可以避免走到標為 Beginner 的教室這樣XD)。整體來說,議程的內容算是蠻均衡的,雖然算一算單一主題的數量可能還是 Web 開發相關的題目佔多數,但不會像台灣的活動一樣明顯偏向 Web 開發。連 NVDA 和 Sphinx 這樣的工具應用都安排了半天時間,內容的多樣性比起台灣場豐富很多。





作為今天活動結尾的就是晚上的 Party 啦。餐廳的確蠻近的,雖然差點經歷迷路(?)事件,但總算迷途知返,跟著其他人群走終於順利到達會場。Party 會場沒有想像中的大,食物雖然還可以,量也追加了,但種類實在太少只好一邊聽某人抱怨不像 mosky 得到那麼多粉絲,一邊拼命喝啤酒XD

喝到一半時主辦單位還舉辦了抽獎活動,用 random.randint 選出幸運號碼。雖然很想說這抽獎實在沒看頭 (大輸 PyConTW 那條蛇XD),但我畢竟抽到一個電腦包了(後來拆封一看,比較像是手提防震包),還是很感謝主辦單位的用心啦~



整個 Party 進行了差不多三個小時吧,大家才開始鳥獸散。這時已經將近十點,日本方面的工作人員也很熱心指點該怎麼搭車回旅館。不過這時我的膽子已經大很多,搭車這種小事根本嚇不倒我,直接就回答我自己可以回去XD 不過因為不少人都要搭りんかい線回去,這一路上有好幾位工作人員同行。

路上小聊了幾句,鈴木さん好像以為我曾經在日本留學過,好像每個被我搭訕的日本人一聽到我第一次來都擺出誇張的表情XD 不過今天一整天待在都是日本人的場子,很明顯感覺到聽力還是不太行啊,會話只要多講幾句就會露餡了;英文就更不用說了,有一半以上是鴨子聽雷XD 不過至少有受到一點刺激會比較有動力繼續練習下去,總算沒白來一趟。明年還有機會來的話要更進步,而且要多搭訕日本人XD




到了大井町駅後只剩我自己搭京浜東北線的車回上野。這兩天已經在東京搭了好幾趟車,雖然車站可以看到提醒不要「かけこみ乗車」的標語,但還是看到兩次!明明幾分鐘就一班車,而且也不是終電,不曉得為啥要這樣性命相搏?XD 這時已經是晚上十點了,搭車的人還是很多。這些人可能大多是獨自搭車吧,所以很少看到有人在交談。我在車上很無聊只好東看看西看看,很明顯可以觀察到每個人一上車不是低頭操作手機、遊戲機,就是看書 (我猜多半是小說)。這裡是個充滿低頭族的城市。

回到上野後再次拜訪了附近的超商。買了飲料和零食,沒想到一時大意把 suica 餘額都用光了!我一直沒留意附近哪裡有儲值機,想到明天不能嗶嗶進站就有點失落,只好把氣都出在零食上XD 飲料蠻好喝的,似乎是幾個月前才推出的小 7 原創新商品,所以特別拍張照留念。在日本的期間總共買了兩瓶同樣的飲料,另一種メロン口味的也買了,但極不推薦XD 零食就不怎樣了,說實話日本的超商零食實在太遜了,可能重點擺在其他商品吧,例如便當就比台灣的種類多不少。

今天看電視看到很晚,雖然明天十點才開始,但因為沒有嗶嗶,還是希望別睡過頭啊。

結果開著電視邊看中川翔子唱歌邊睡覺。


Filed under: Japan, PyCon, python, Travel

» 2012 Sep‧東京 Day 2 – 1

在日本的這幾天住的是「ホテル サードニクス 上野」這家商務旅館,比較有名的大概是床吧,不過我實在累到來不及體會床的差異就睡著了。早餐在一樓的餐廳,雖然只有四種可以選,但飲料可以隨便喝到飽。可惜因為太晚起床只能帶到會場去吃,飲料也只能帶一杯,不過就早餐來說這樣就夠了,留在東京的這幾天,要妥善分配每一分胃的空間才行。



今天是 PyConJP 的第一天,幾乎一整天都會待在會場,所以交通方式很簡單,只要到會場就可以了。從旅館到會場大概需要 30 分左右,提早約 10 分鐘出門可以悠閒地從アメ横漫步到車站。早上八點多的アメ横沒什麼人,也沒有酒氣沖天的居酒屋和上班族,就跟一般的住宅區巷道沒什麼兩樣。跟熱鬧的夜間上野比起來完全是不同氣氛,這就是所謂的反差萌嗎?XD





在旅館周邊可以看到三間小 7,一間全家,兩間 Sunkus,三間 Lawson (日本很大的連鎖超商),算是相當方便的區域。小 7 內的東西跟台灣看到的差不多,但熱食的種類比較多。為了實驗超商取貨,我在台灣就先訂了東西,送到旅館附近的 Lawson。不過今天出門前檢查了一下信箱,只收到出貨通知,還沒到店。

走到熟悉的御徒町駅,這次要挑戰傳說中的轉車 (乗り換え)。先搭 JR 京浜東北線到大井町駅,再轉搭りんかい線品川シーサイド駅,這是離會場最近的車站,出站後走個幾步就可以看到學校。





聽說轉車還有分要不要出站,好在這次轉車好像不需要出站,不然沒帶地圖就糟糕了。雖然大井町駅不大,但要到りんかい線的搭乘處還是走了一段路,跟著指標繞來繞去都不曉得跑到地下幾樓了。順利到品川後,爬了不少樓梯總算回到地面。東京的複雜交通網,讓很多車站只能往地下挖,聽說大江戶線還有到地下七層的,還好這次不用去挑戰。

出了車站後竟然看到 OK 超商了。不過時間已經逼近預定開始的時間,我可不想因為逛超商而錯過 Keynote,只好一邊觀察周邊的大樓一邊尋找目的地,有機會再回來逛。





不曉得是不是因為週末的關係,這附近的車子不多,偶爾出現的車子也開得很慢。在周邊氣氛的感染下,我很自然地就放慢腳步 (明明開場時間已經到了),悠閒地往學校前近。沿途有工作人員和路標,實在是沒有迷路的機會,不到五分鐘就已經抵達報到處了。

報到的同時發現 thinker 好像也是剛進來。不過因為我認人能力很差,又只在影片上見過,猶豫了一下還是上前打招呼了,還好沒認錯人XD 找狗牌的時候花了點時間,工作人員已經事先照字母排好,應該沒什麼問題才對,沒想到報了 L 開頭竟然找不到。感覺報到處的工作人員感覺蠻緊張的,很努力在幫我找,後來雖然用本名找到,但名字被切掉了XD






報到後得到 AIIT 提供的袋子和一堆資料,打開看一下赫然發現疑似 ACG 物的東西… 日本微軟 GJ!這幾年的微軟在宣傳方式的變化挺多的,從窓辺ななみクラウディア,連台灣也出現藍澤光了,這個世界果然是朝著宅(?)的方向發展啊!

袋子裡還有一些貼紙之類的小東西。其實我以前一直不曉得那貼紙要用在哪,後來才發現很多人貼在筆電上,kanru 甚至還貼在行李箱上,好像蠻實用的,等我有自己的行李箱再考慮看看。有趣的是袋子裡還放了學校的宣傳資料,看來很缺學生 :P





不曉得是不是因為節電的關係,室內沒開空調,一整個悶啊。看到好多日本人已經拿起扇子,看來都有散熱對策了,只剩呆呆的台灣人在悶鴨子。在坐著就會流汗的教室裡等了半天才看到其他台灣戰友,看來都有迷到路 :D 不過活動開始的時間延了大概半小時,所以大丈夫だ、問題ない!最後都有趕上開場的 Keynote (日文好像叫「基調講演」)。

這次的 Keynote 講者是 Armin Ronacher,應該算是 Python 圈的名人吧,我雖然記不住他的名字,但他的專案倒是玩過好幾個,例如 PygmentsJinja、和 Flask 等等。當時只覺得專案用了 Jinja (神社) 這麼和風的名字,喜歡神祕東方文化的外國人還真不少… 沒想到根本是個阿宅!






結束開場的 Keynote 後,一群人跑到外面聊天。這次的 PyConJP 有贊助商徵才專區,使用 Python 開發產品的公司和團隊還真不少。走廊上的公布欄也貼了不少求人廣告,不過 gumi 的廣告是不是貼錯地方了?根本就像什麼遊戲海報嘛!旁邊還可以看到一台 O’Reilly Japan 的轉蛋機,聽 lwhsu 說很多活動都看得到XD

轉蛋機後面是 O’Reilly 的書籍展售區,全部都是日文書就是了。

(待續)


Filed under: Japan, PyCon, python, Travel

九月 23, 2012
» 2012 Sep‧東京 Day 1 – 2


經過一個半小時的路程,總算抵達終點的京成上野駅。上野其實離會場有點距離,當初會選擇住上野只是單純聽過著名的上野動物園,完全不曉得上野在哪。選個名字比較有聽過的地方,在車站附近的話交通也方便,就這樣定下來了。結果根本沒去動物園,只在大到不行的上野公園晃一晃而已。


到了京成上野站後,先到遊客中心搜括一堆地圖和景點情報,順便熟悉一下車站附近的路。結果往著名的アメ横移動時已經是下午四點啦。這個時間人非常多,為了感受一下氣氛,我決定不走大馬路,直接穿過アメ横的小路到旅館。這裡因為是著名的消費景點,店家多,人也非常非常多,但我拖著行李在外面玩了三個小時已經有點累了,完全沒有心情逛街,只想趕快找到旅館休息。邊迷路邊在人群中穿梭,最後幸運從一個蠻近的路口穿出來,剛好可以看到接下來幾天要住的地方。


從車站到旅館,走過這一段路才慢慢意識到,原來要靠左邊走阿,難怪一直撞人XD 但其他人也很體諒地閃開,大概看我拖著行李一副快走不動的樣子吧。但有可能心裡想著:又是個死觀光客吧XD 過去的台灣不管在語言或生活習慣上都受到日本的影響,但到了日本雖然可以感受到親切感,還是有不少文化和生活習慣上的差異可以很直接感受到。在這樣一個熟悉又陌生的地方,看著周圍熙熙攘攘的行人,想起在阿部寬在電影中說的「扁臉族」,不由得輕笑起來,調整心情開始享受接下來幾天的異國生活。


雖然才剛到日本,但這一天的晚上已經預定有日本主辦單位方面為我們 (應該說是外國參加者) 辦的 Welcome Party,地點在品川附近。由於時間還早,研究了一下在車站拿到的地圖後,決定再次穿過アメ横,到御徒町駅搭車。


上野的馬路上幾乎都是公車和汽車,幾乎看不到機車。除此之外就是自行車和行人了,路口大概都看得到專門給自行車或行人使用的號誌。有趣的是自行車跟行人共用紅磚道,也有專用的停車場。在日本騎自行車的人不少,甚至還遇到有人邊玩手機邊騎,看到行人也可以如常閃避,實在太厲害了。台灣雖然沒有專用號誌,但有些地方鋪了自行車專用道,只是常常看到上面停滿汽車,自行車一樣跟行人爭道,相當可惜。

到了車站,真是慶幸有先買好 suica,只要在閘門嗶嗶一下就可以進去了,不必到車站還在算車資買票,也不會忘了取票 (回程就遇到了,還好有人提醒XD)。到這裡我才知道為什麼很多人推薦住在山手線附近,因為搭車實在太方便了。雖然東京有可怕的地鐵網,但山手線的鐵軌在天上,不要離太遠的話抬起頭就會看到,找到後沿著走就會到車站;地鐵的入口常常隱藏在建築物間,路不熟的話實在沒那麼容易找。


因為是個小車站所以很容易就找到月台,沒兩分鐘車就來了。這裡可以搭到山手線和京浜東北線的車,Welcome Party 的會場得先到浜松町駅,不管搭哪一條線都到得了,所以隨便看到有車就上也不用怕,也不用管什麼內圈外圈,只要方向對就沒問題。為了確保不會跑錯方向,至少要先記住幾個大站的方向,例如東京、上野、品川和渋谷等地方的相對位置。雖然 JR 上的網頁已經提供了足夠的資訊,但出門在外沒網路,也沒印出來的情況下,如何掌握最少情報就不會迷路也是很重要的。

後來發現這些車站的樣子,在 Youtube 上很容易找到影片,真的很擔心的話也可以先研究看看。我因為匆忙出門,根本沒想到要先研究一下路線,事後也證明沒那麼難,只要在看得到鐵軌的範圍亂跑,要迷路還真不容易。但這些話對於還沒體驗過的人來說應該還是聽不進去吧 (我當初也是這樣XD),總之還是只能說,去了就知道搭車沒那麼難。

雖然順利解決了搭車問題,沒想到接下來又遇到大問題。到了車站後,根據之前的情報會有穿黃衣的工作人員在車站帶路,沒想到提早半小時到還是看不到人。我因為沒帶餐廳地圖只好憑著記憶在車站到處問人,連超商員工都被我抓來問了,還是沒半個人知道餐廳位置 (其實不能怪他們,因為我忘了店名,只記得是雞肉料理的店,能找到也太神了)。最後已經想放棄,正打算隨便吃個拉麵回去時,竟然在車站內撿到跟我一樣被丟下的 hychen 和 kanru XD 三個人在外面繞了很久還是找不到,最後只好在路邊找了家居酒屋先解決晚餐。回來一查才發現一度走到很近的地方了,再往前走個一分鐘應該就到了,沒想到一直鬼打牆,在反方向繞半天 (誰叫那邊剛好有另一家雞肉料理的店,名字不同所以走到一半就折回來了XD)。


第一次去居酒屋也是新奇的體驗。在電車上看到一本正經的上班族,進了居酒屋後跟發瘋一樣,一整個吵。因為點了很多花時間的燒烤料理,所以除了聊天以外都在偷聽隔壁桌的上班族抱怨工作,沒想到可以聽得懂一大部份,所以邊吃邊聽還蠻有趣的。在居酒屋待到十一點多,最後回到上野已經快十二點了。回到飯店第一件事就是打開電視,好久沒看的 BS 放送,真懷念啊~


Filed under: Japan, Note, Travel

» 2012 Sep‧東京 Day 1 – 1

我想這系列很有機會演變成充滿內心戲且冗長的遊記。

這次會決定跑一趟東京,其實自己也很意外。這幾年已經跟社群活動太接近了,有點不太習慣,但有時候就是會一衝動做出奇怪的決定。現在回想起來,整個決策並沒有太多猶豫。決定要去以後就開始安排工作進度,拿到假單以後才開始訂旅館和機票。以前這些事情都是交給公司或旅行社處理的,第一次全部自己來其實有點興奮,但也很怕一個環節出錯就出不去了XD 雖然研究了許多網路上的心得,大概把該做的事都整理出來了,不過有朋友的幫忙讓整個進度更順利,很快就處理好住宿和交通問題。

一直到這時候才到 Connpass 系統報名,家人還確認了好幾次,問我是不是真的打算去一趟。沒想到晚了半個月報名的序號竟然讓我抽中兩份獎品,這是後話了。

總之,決定到 PyConJP 看看了,再加上兩天背包迷路之旅。


認識我的人中應該有不少人知道我學過一點日文,也許會存在我很熟悉日本這種錯誤印象,事實是我對日本完全不熟,也從沒想過要去日本。對我來說,日文就像英文一樣只是個方便的工具,讓我可以看懂日文的技術 Blog 和台灣還沒出版譯本的小說。因此到日本這件事對我來說實在是個不小的挑戰,畢竟我連東京的位置也只有個模糊的概念,更別說要安排兩天的自由行程了。除了兩個非去不可的點以外,其他的時間一直到飛機起飛都還是空白的,有點大冒險的感覺。

雖說到日本已經相當簡單了,出發前還是忍不住擔心老半天,會不會因為天候因素停飛?會不會因為某些原因無法出境之類的?以前就算上日籍老師的課,也都是懂不少中文的日本人,這下真的要面對完全不懂中文的日本人了,說得出口的日文到底能不能派上用場還不曉得… 我可不想跟日本人用英語交談。雖然看到很多人完全不懂日語也是玩得很開心,但我想既然都去一趟了,總要確認一下之前學的東西是不是有用,就當作真正的期末考口試吧。

總之出發前的幾天腦中一片混亂,先前查了幾天的資料在出發前通通忘光光,地圖來不及印,到出發前一天連交通手段都還沒查清楚。最後只好自暴自棄,到目的地後再見機行事吧!但總不能回不來吧,所以只確認了回機場的方法就出門了。


因為我只有一個人,實在很怕回程當天睡過頭錯過飛機,所以絕對不能搭太早的飛機XD 研究了好幾天,很幸運地訂到早去晚回的機票,所以一大早就得出門。

一早的機場就有很多旅遊團待命,找到報到的櫃台後就早早拿到登機證,等著登機時間。這時遇到 hychen 和 kanru 也來了,不過因為我逛了一下玩具店,比較晚一點到。那個樂高店實在很致命,但應該沒有人出門前又增加行李的吧XD 三個人在候機的時間幾乎都在聊 emacs 的操作心得 (好像有點宅XD)

搭機的過程沒什麼特別的所以沒有照片。真要說的話就是空服員一下跟我說英文,一下說日文,搞得我有點混亂XD 機上看了宇宙兄弟和一點點羅馬浴場 (テルマエ・ロマエ),兩部都是極度推薦的電影。ANA 的飛機餐很普通,但全部吃完還是可以有一點飽足感。

三個多小時的飛行很快就結束,之前聽說了十分鐘通關的神話,所以我也挑戰了一下。可能因為人不多吧,其實還蠻容易達成的,重點還是在先填好入境用的資料。這時候還不到一點半,邊等其他人邊逛機場,不過這時首先要解決的是搭車問題。這次住的地方在上野,我只記得要搭什麼特急的,但資料沒準備齊全也想不起來,最後只好鼓起勇氣開口問啦。從賣票的大姐姐問到義工(?)媽媽,連穿警衛制服和推車的也都抓來問了,最後總算順利被引導到京成特急的售票口 (其實沒有很難走啦,只是想多適應一下日文環境)。


匆匆買了一千日幣的車票後又問到賣 suica 的地方 (根本沒看到什麼みどりの窓口阿XD),最後是在紅色窗口買到的。問了一下哪些地方可以儲值,賣票的大哥哥說到處都可以,只要有機器就可以儲值 (這不是廢話嗎XD)。整備完成找到月台後已經兩點了,這時對面剛好停著還沒出發的 N’EX,看到帥氣的 N’EX 的車廂有點後悔選擇京成特急XD

到日本旅遊的台灣人實在很多,從機場到月台間,聽到的都是中文比較多。而機場內其實也到處都是中文指標,就算不懂日文也沒那麼容易迷路。到月台時已經一堆講中文的人在等車了 (從口音推測是台灣人)。



車子到了以後看到傳說中的相親座了。除了車內廣告都是日文,乘客全都帶著大包小包的行李以外,跟在台灣搭車沒什麼差別。比較特殊的是博愛座附近貼著提醒手機要關機的標示。

由於是電車,途中有很多人上車,從女學生到老奶奶都有。車上很少人會交談,途中的當地人上車後不是低頭玩著手機就是睡覺補眠。後來有兩位老奶奶上車後一直在聊天,原本以為老人說的話會比較難懂,但後來才發現這種說話速度反而容易聽懂。一個半小時的車程很無聊,不是看著窗外的景色就是到處拍拍拍。

搭電車其實蠻有趣的,雖然每一站都停實在很花時間,但可以看到當地人,也可以慢慢欣賞沿途景觀。比起搭觀光巴士直達旅館的規畫,我的冒險可是從下飛機後就開始了。途中看到許多坡道和正在辦活動的河堤,因為是很多動漫畫會出現的場景,看到後開始有來到日本的感覺了 (河堤跑太快來不及拍XD)。


(待續)


Filed under: Japan, Note, Travel

十月 30, 2011
» Extending Gforth with the Code Word

很久沒發文了,但一直都有記錄筆記的習慣,原本也是打算整理好發表的,但常常寫到一半就去做其他事了,所以積了不少未完成的稿XD 這次出清一篇筆記,來談談 forth 中的 code word。

一般對於 forth 系統的擴展有兩種方式,最方便的當然是定義新的 colon word,另一種則是實作比較低階的 code word。

code word 代表的是低階實作,也就是直接跟底層平台對話。以 lisp-based forth 為例,其實就是把 lisp vm 當作(虛擬)硬體平台,因此 code word 作用大概就是產生一堆 lisp form,而 x86 native forth 當然就是產生 x86 machine code 了。

簡單地說,code word 需要負責兩件事:

  • 產生 native code
  • 讓 forth 可以順利執行這些 native code

產生 native code 的工作通常會由一個 target assembler 負責。這也是為什麼一個完整的 forth system 多半會提供自己的 assembler。雖然 forth 已經是可擴展的設計,但在需要直接操作宿主平台時,可能會需要寫成 code word 比較方便。

比較麻煩的是第二點,讓 forth 可以順利執行的關鍵在於不能干擾系統運作。forth 本身雖然是 stack vm,但還是有幾個基本的暫存器,一般在 x86 上會對應到實際的暫存器。依照實作模型的不同,可能會需要佔用 2 至 5 個不等。在 code word 中必須妥善管理這幾個暫存器,不是單純 pushapopa 就可以解決的。最常見的狀況,就是維護 SP 的值 (forth 中的 SP 暫存器,非 x86 的),確保參數可以正常傳遞,不會發生 underflow;以分支指令來說可能需要修改 IP 的值,只要改錯暫存器就會發生災難。因此第一步就是找出這幾個暫存器的對應關係。

在一般的 forth 系統中,通常會提供一個叫做 see 的 disassembler,可以透過它來猜出系統的規劃。Gforth 套件提供了好幾種實作,由於接下來的實驗在不同實作中會有不同結果,為了方便解說只使用 gforth-fast。在 Gforth 中,第一個建議觀察的是什麼事都不會做的 noop

see noop
Code noop
( $804B1BF )  add     esi , # 4  \ $83 $C6 $4
( $804B1C2 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804B1C5 )  mov     eax , ebx  \ $89 $D8
( $804B1C7 )  jmp     804B03C  \ $E9 $70 $FE $FF $FF
end-code

從這邊可以猜到不做事的時候,系統大概會使用 eaxebxesi,然後跳到某個位址繼續執行。因此觀察其他 word 的時候就可以先去除這幾個動作,找出真正關鍵的操作。接下來建議的是 dupdrop。這兩個 word 是基本的堆疊操作,可以直接找出 SP 在哪,甚至可以看出是否有加入 TOS (Top Of Stack) 的快取設計,也就是將 TOS 放在特定的暫存器以減少一次記憶體操作。

see drop
Code drop
( $804C836 )  add     edi , # 4  \ $83 $C7 $4
( $804C839 )  add     esi , # 4  \ $83 $C6 $4
( $804C83C )  mov     ebp , dword ptr [edi]  \ $8B $2F
( $804C83E )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804C841 )  mov     eax , ebx  \ $89 $D8
( $804C843 )  jmp     804B03C  \ $E9 $F4 $E7 $FF $FF
end-code

drop 的內容可以看到除了 noop 以外,還操作了 edi,沒有意外的話 SP 就是它了。同時也知道堆疊往低位址成長 (因為 drop 相當於做了一次 stack pop)。作為佐證可以再觀察一下 dup,應該會看到減少 edi 內容值的運算:

see dup
Code dup
( $804C85D )  sub     edi , # 4  \ $83 $EF $4
( $804C860 )  add     esi , # 4  \ $83 $C6 $4
( $804C863 )  mov     dword ptr 4 [edi] , ebp  \ $89 $6F $4
( $804C866 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804C869 )  mov     eax , ebx  \ $89 $D8
( $804C86B )  jmp     804B03C  \ $E9 $CC $E7 $FF $FF
end-code

看起來的確有移動 edi 內容的操作。另外還看到奇怪的動作,把 edp 的內容搬進 stack top – 1 的位置,並不是移動到 stack top,推測 可能有 TOS 的設計。

要證實這一點,可以再看一下 swap+ 這幾個會影響 TOS 的 word。

see +
Code +
( $804B918 )  add     ebp , dword ptr 4 [edi]  \ $3 $6F $4
( $804B91B )  add     esi , # 4  \ $83 $C6 $4
( $804B91E )  add     edi , # 4  \ $83 $C7 $4
( $804B921 )  mov     ebx , dword ptr FC [esi]  \ $8B $5E $FC
( $804B924 )  mov     eax , ebx  \ $89 $D8
( $804B926 )  jmp     804B03C  \ $E9 $11 $F7 $FF $FF
end-code

看來的確是把運算後的結果 (TOS) 直接放到 ebp 了,而不是放在記憶體中。拿到 SPTOS 後就可以試著增加一個 code word 看看了。首先用最簡單的 dup 操作來驗證前面的猜測,實作一個有相同操作的 _dup

code _dup
    bp di ) mov
    4 # di sub
    next
end-code

3 _dup .s

可以看到堆疊中的確出現兩個 3 了。不過看起來自己實作的 _dup 好像比原版的 dup 還要精簡一點。另外也可以寫個 _+ 看看:

code _+
    4 # di add
    di ) bp add
    next
end-code

2 3 _+ .s

結果也正確無誤,留下一個 5。到這邊已經可以做很多事了。不過偶爾可能會需要 RP,所以從 >r 找到 RP 放在記憶體的某處。查找的過程不再列出,同樣複製一個相同的 _>r 來驗證看看:

code _>r
    4 # $3c sp d) sub
    3c sp d) bx mov
    bp bx ) mov

    4 # di add
    di ) bp mov
    next
end-code

為了維護 return stack, >rr> 通常要平衡使用才不會破壞系統運作,所以我將自己實作的 _>r 搭配系統的 r> 一起使用,測試過可以正常執行。

除了這幾個重要的暫存器外,還有一個 IP,可以透過觀察 branch 找到,這裡就不再贅述了。不過還有一件重要的事需要特別提出來討論。在整理這篇筆記的過程中,我發現一個嚴重的問題:以前實驗的結果,在 0.7.0 版的 gforth-fast 可以正常運作,但換成 0.7.9 版卻無法動作,後來試了一下 0.6.2 也同用無法執行。查了文件才知道原因在於 c compiler 版本。由於不同版本的編譯器執行 register allocation 結果可能不同,會產生出完全不一樣的 forth vm,這點是特別要注意的。前面列出來的結果是在 gcc 4.4.4 建立出來的 gforth-fast 0.7.9 的環境重新實驗的。如果使用到的暫存器剛好都是自由的 (不被系統使用),換系統時就不需要再調整程式了。

雖然聽起來有點糟,但對我來說也不算什麼大問題就是了。畢竟 forth 在各系統間的相容性本來就不能期待,會想使用 code word 的人大概對正在使用的系統也有一定的掌握能力了,這樣程度的相容性問題應該都有能力處理。


會翻出這篇筆記,主要是看到有人做了一個 benchmark,gforth-fast 需要的時間是其他 forth 的好幾倍,想試試把幾個關鍵處改寫成 code word,看有沒有機會加速。最後實驗的結果是… 不行!

囧rz

非但沒變快,反而更慢了XD 也許 Gforth 在切換成 code word 可執行環境時做了很多事,因此效能不如全部都使用 colon word;也許是 instruction miss 等原因造成的吧。這個一時興起的實驗提醒了我在選系統時要記得同時測試一下 code word 的使用,暫時還是先把 Gforth 的 assembler 當作 cross assembler 使用吧。


Filed under: forth, Note

十月 26, 2011
» TestPost

不好意思,之前發現 emacs 沒辦法發出文章了,這篇文章單純測試用 測完沒問題就刪掉 <!–more–> 測試程式碼 <pre class="src"> <span style="color: #00cdcd;">init</span>: <span style="color: #00cd00;">xor</span> ax, ax <span style="color: #00cd00;">mov</span> ds, ax <span style="color: #00cd00;">mov</span> es, ax </pre> <p>測試<a target="_blank" href="http://www.google.com/">超連結</a>是否正常</p> <ol> <li>item 1</li> <li>item 2 <ul> <li>qwer <ul> <li>abcde</li> </ul></li> <li>tyui</li> </ul></li> <li>item 3 <ul> <li>mjkl</li> <li>eoru</li> </ul></li> <li>item 4</li> </ol>

四月 21, 2011
» VOCABULARY in Forth

最近找了一些 Forth 的舊文章來看,也看了一些舊程式碼。在這些資料中發現很多以前沒學會的東西,正好趁這機會補習一下。這次要介紹的是 Forth 裡的 VOCABULARY

如果對 Forth 有一點瞭解,或者看過我以前翻譯的 PForth 教學,應該會知道 Forth 中的每一個執行單位叫做 word。相對於其他程式語言來說,就像是函式那樣的東西。Vocabulary 的意思是「詞彙」,簡單的說就是 word 的集合。更進一步,大概就像是 Library 的設計。

以上是我一直以來對 Vocabulary 的理解。以前我還在念書時,想找個程式語言來學,卻糊裡糊塗入了 Forth 坑。但當時 Forth 並不是主流,不但買不到書,也找不到人教,很多東西就這樣斷章取義,隨意理解了。等到實際要用時才知道問題大條,趕緊花了點時間玩一下,原來誤會了那麼久的東西,其實是那麼簡單又強大的設計。

其實 Vocabulary 除了 Library 的功能之外,更重要的功能其實是 Namespace 的控制。

Forth 的核心設計有幾個重要的基礎元件,其中的 Dictionary 用來存放資料與新定義的 word。Vocabluary 可以將 Dictionary 中的 word 分組,並影響後續使用的搜尋順序。用比較現代一點的說法,其實就是 Namespace 與 Scope 機制。以下會簡單介紹一下 Forth 的 Vocabulary 設計與運作方式,參考資料來源是 GForth 附的程式碼與實驗結果。

在 Forth 系統誕生之時會提供一個最基礎的 Namespace,在這個 Namespace 裡就只有最基本的 Namespace 定義與管理工具,連基本的堆疊運算辦不到。以 GForth 為例,這個最基本的 Namespace 叫做 Root,只提供了 5 個 word:

order set-order forth-wordlist Forth words

其中比較重要的是 ORDERFORTH 這兩個 word。 ORDER 的作用是列出目前作用中的 Namespace,以及目前的定義空間; FORTH 是一個 Vocabulary,裡面定義了撰寫 Forth 程式會使用到的 word。先來看看 ORDER 的結果,在 GForth 中輸入 ORDER 會印出:

Forth Forth Root     Forth

這串訊息要分成三部份來看:

  1. 最左邊的 Forth:代表目前作用中,搜尋順序最高的 Vocabulary。依照以前的術語,這個位置代表 CONTEXT Vocabulary
  2. 最右邊的 Forth:代表目前的定義空間,所有新定義的 word 將會加入 Forth 這個 Vocabulary 中。依照以前的術語,叫做 CURRENT Vocabulary
  3. 中間的部份:一個 Vocabulary 清單,代表目前的搜尋順序。當系統在 Context Vocabulary 中找不到要執行的 word 時,就會依照這邊的順序一個一個找下去

以這個顯示結果來說,在 C++ 看到的可能是:

using namespace Root;
namespace Forth
{
  ...
}

這三個部份都是可以隨意改變的。在 Forth 中,每個 Vocabulary 其實也是一個可執行的 word,執行後的動作就是更新 Context Vocabulary。Forth 允許兩個同名的 word 定義在同一個 Vocabulary 或不同 Vocabulary。定義在同一個 Vocabulary 時,只會搜尋到最後定義的 word;而定義在不同 Vocabulary 時,就是靠 Context 決定會找到哪一個。

舉個簡單的例子來說明。假設我有 A 和 B 兩個 Vocabulary,其中 A 定義了兩個 foo:

: foo ( -- )
  ." in a" cr
  ;

: foo ( -- )
  ." in a (2)" cr
  ;

B 也定義了一個同名的 foo

: foo ( -- )
  ." in b" cr
  ;

假設我想執行 A 裡面的 foo,必須先切換 Context 到 A:

\ Set Context
A  ok

\ Exec foo
foo in a (2)
 ok

可以看到真正執行的是最後定義的 foo。若想執行 B 裡面的 foo,同樣也要先切換 B:

B  ok
foo in b
 ok

除了切換 Context 外,其他兩個部份也可以隨意設定。但在介紹方法之前得先引入幾個小工具。Forth 對於整個 Vocabulary 的管理提供了幾個小工具。比較重要的有 VOCABULARYONLYALSODEFINITIONS

VOCABULARY 可以建立新的 Vocabulary。以剛剛的例子來說,建立 A 與 B 的方法是:

vocabulary A  ok
vocabulary B  ok

ONLY 的意思是只搜尋 Root 這個 Vocabulary。在 GForth 中可以看到 ORDER 的結果是:

only  ok
order Root Root     Forth  ok

可以看到去除左右兩個 Vocabulary 後,中間的搜尋清單只剩下 Root。

ALSO 的意思是說,將目前的 Context Vocabulary 加入搜尋清單。加入以後,不管 Context 怎麼變動,都可以不受影響。以前面的例子繼續實驗。我把 A 加入搜尋清單後,再改變 Context,看看是否可以找到定義在 A 的 foo:

only forth also \ reset search list
A also          \ add A to search list
forth           \ set Context

\ current environment
order Forth a Forth Root     Forth

\ exec foo
foo in a (2)
 ok

看來的確可以自由配置搜尋清單。

最後一個是 DEFINITIONS,用來決定新定義的 word 該屬於哪一個 Vocabulary,執行後會把 Context Vocabulary 設定到 Current Vocabulary。以前面的例子來說,我想在 A 裡面定義一個 foo,可以這樣做

A definitions
: foo ( -- )
  ." in a" cr
  ;

Forth 的 namespace 設計很簡單,卻威力強大。只加了這幾個工具就可以產生一些好玩的應用。舉例來說,為了 debug 方便,我會在 word 定義中加上一些 log 訊息。有時候跑一次程式後再檢查 log 會比進入 debugger 有效率得多。例如:

: foo ( -- )
  \ ." >> enter foo" cr
  ." exec foo" cr
  \ ." << exit foo" cr
  ;

比較麻煩的是加了 log 就得移除,需要一直修改程式。利用 Forth 的特性,我可以在不同的 Vocabulary 設計一組外掛用的 wrapper word,專門用來顯示一些 log 訊息:

vocabulary tool
tool also definitions
: foo ( -- )
  ." exec foo" cr
  ;

vocabulary tool-debug
tool-debug definitions
: foo ( -- )
  ." >> enter foo" cr
  foo
  ." << exit foo" cr
  ;

可以看到我在 debug 用的也是同名的 foo,但因為定義在不同 Vocabulary,所以不會互相干擾。在一般情況下我可以正常地執行 foo:

only forth also definitions tool  ok
foo exec foo
 ok

需要追蹤執行流程時,就將新工具外掛進來

tool-debug  ok
foo >> enter foo
exec foo
<< exit foo
 ok

不需要 log 的話可隨時換回正常版的 foo。

雖然很容易就做到這樣有趣的效果,但其實這只是簡單的示範而已, 並不具太大的實用價值。要達到比較實用的程度,可能得搭配 Forth 的 DEFER word 機制,將 log 輸出功能設計成一個可抽換的 policy word,並在執行前決定要設置成哪一個 policy1。運作起來類似 late binding 的效果。

Forth 這麼古老2的東西 (其實不比 Lisp / Fortran 晚多少喔),竟然連 Namespace 管理機制都設計進去了,以現代程式語言的角度來看還真是一點都不退流行阿!而且 Forth 流行的時代,其實主要做一些硬體控制的工作,有複雜到需要加入 Namespace 機制嗎3?在那個高階語言都還不太流行的年代,天曉得這些前輩高人們怎麼想到的?


1. 應該很多人猜得到這是從哪本書借來的點子

2. 想瞭解 Forth 的誕生,可以參考 Forth – The Early Years (中譯) 這篇文章

3. 事實上就是有這個需要,希望以後有機會能介紹到這部份


Filed under: forth

十月 31, 2009
» Test Yourself

超過半年沒新文章了XD

每次看著空虛的 blog 就想把一些庫存丟出來充充版面,但有些內容過了該發表的時間點就沒什麼動力寫完,只好繼續讓 blog 就這樣晾著。沒寫文章的這陣子,程式也沒多寫,大概都把時間耗在 plurk 和 irc 上了 (也撥了一些時間看看土曜劇和晨間劇啦)。倒是最近遇到一個想用 forth 寫輸入法的狂熱份子,又喚醒我心中的 forth 魂了。

forth 毫無疑問是我最喜愛的程式語言,但本 blog 的 forth 分類卻只有屈指可數的兩篇文章。實在是因為我除了把 forth 當作頭腦體操外,根本很少使用 forth 來寫正式的程式 (而且功力也差…)。話雖如此,閒暇時仍舊會在 google 上搜尋相關資料,思考著怎麼利用在 forth 中的體會,幫助其他開發工作。但大多數時間還是抱著好玩的心態來看 forth,偶爾想到就會找出來玩一下。

這次嘗試了 reva 這套 forth engine,雖然提供了很多方便的函式庫,但卻不相容於 ANS 標準,所以一開始吃了不少苦頭。花了一點時間看了實作,再把以前在 pforth 上寫的練習程式移植到 reva 後,慢慢搞清楚 reva 與 ans 之間的差異了 (有些 word 的確方便多了)。

另外就是玩一下 ffi 的部份。第一個練習就是來個 vte,根據 caleb 提供的範例程式改寫一下 (去掉 turnkey 的部份):

" libvte.so" lib libvte

0 func: vte_terminal_new
8 func: vte_terminal_fork_command

needs ui/gtk2
~gtk2

: =exit callback gtk_main_quit ;
: main ( -- ) init
    GTK_WINDOW_TOPLEVEL gtk_window_new dup dup
    vte_terminal_new
    dup 0 0 0 0 0 0 0 vte_terminal_fork_command drop
    2dup _add
    z" child-exited" ['] =exit _connect drop
    z" delete-event" ['] =exit _connect drop
    gtk_widget_show_all gtk_main ;
main bye

直接翻譯自原本的 c 程式,除了變數都透過 stack 來操作外,看起來實在沒什麼不同。事實上也不過是把 forth 當作 libvte.so 的外殼,透過交談式界面來操作,相當方便。執行結果如圖:


有了 ffi 後,原本在 c 世界的資源都可以拿來利用了,而且寫起來也有趣多了。即使不特別用 forth 風格來撰寫,當作 c 來寫也不是太困難的事,實作邏輯很相近 (就像很多人拿 c++ 來寫 c 一樣…)。


話說回來,forth 提供的語法其實比 c 豐富很多,應該要被歸類在比 c 還高階的語言才對阿!思考到這裡,想起以前嘗試過用 forth 實作 Higher-order Function,就是企圖在 forth 中使用高階的工具。

其實剛接觸 forth 時一直都是當作比較方便的組合語言來學。看了 Joel 的文章後,覺得在其他語言也應該享受到 HOF 的方便,再加上那時也學了一陣子程式設計,正好試試看是不是比 Joel 大一時還厲害 (笑)。不過 Python 或 Perl 這幾個常用的語言早就內建類似的工具了,最後就找了 c 和 forth 來玩。c 的版本很多人玩過,我就不再多說了,還是聊聊 forth 吧。

有嘗試過用 functional 風格寫 c 的人應該會知道這兩種不同程式風格不是那麼容易結合,一方面是 lisp 的設計讓這些高階運算很容易達成;而以凡事以 list 為運算對象的概念,也跟 c 不太一樣。但在 forth 裡卻很容易跨越這層隔闔,雖然 list 物件得另外實作出來,但偷懶一點還是可以用 stack 來模擬的。只要把前置式語法改為後置式語法,也許很多在 functional 世界發展成熟的設計手法就可以直接搬到 forth 使用了。

以 Currying 來說,在 forth 裡再自然不過了。c 的實作可以參考 jservthinker 的魔法,而 forth 呢,其實在標準的 word 中就有不少是帶有 currying 風,如 0<0=1+2/ 以及 cell+cells。大概因為太自然了,即使 forth 圈沒有刻意使用 currying 來稱呼 (就我所知是沒有),幾乎是平常就在做的事。以 Wikipedia 上舉的例子來說明:

Take the function f(x,y) = y / x.
To evaluate f(2,3), first, replace x with 2.
Since the result is a new function in y, this function g(y) can be defined as
g(y) = f(2,y) = y / 2.
Next, replacing the y argument with 3,
provides the result, g(3) = f(2,3) = 3 / 2. 

在 forth 中可以寫成:

: f ( y x -- n ) / ;
: g ( y -- n ) 2 f ;

3 2 f . cr
3 g . cr

透過 forth compiler 直接將參數 (也就是 2) 編譯到 forth dictionary 中,往後使用 g 時就會自動將 2 傳給 f。可以看到在 forth 裡使用 currying 有多麼自然。

那麼其他的 HOF 呢?回到 Test Yourself 這篇文章,文中第一題出現的 accumulate,可以在 SICP 的 2.2 節看到,事實上就是 fold-right。在 python 中有個很像的工具,叫做 recude (但 reduce 應該是 fold-left),摺疊的方向是不同的。要自己實作一個來用也不難,根據這裡提供的 Haskell 程式:

foldr f z []     = z
foldr f z (x:xs) = f x (foldr f z xs)

可以知道 foldr 的實作關鍵在於從 list 的右邊開始摺疊,以遞迴的想法來說就是先呼叫到底,直到遇到終止條件 (empty list) 再開始回頭計算。釐清這個想法後就可以翻譯成 forth 程式,但為了方便,先定義一些方便的小工具:

hex EFABCD constant nil
: car ( addr -- n ) @ ;
: cdr ( addr -- addr' ) 1 cells + ;
: null? ( addr -- t ) @ nil = ;

因為偷懶不想實作 list object,這邊先用陣列來模擬,在最後塞一個 nil 作為辨識用。 carcdrnull? 的定義可以參考 lisp,而且也可以看到這裡的 cdr 用到了上面提到的 currying。有了這些工具後就可以輕鬆地翻譯 accumulate 了:

: foldr ( addr init xt -- n )
    rot dup null? if 2drop        ( null list, left init on the TOS and return )
        else over >r              ( store f )
                dup car >r        ( store x )
                cdr -rot recurse  ( exec "foldr f z xs" )
            r> r> execute         ( exec "f x n" )
        then ;

: accumulate foldr ;

這裡參考了 haskell 使用的符號,在每一行後面加上註解,可以對照著 wikipedia 給的範例程式和 accumulate 的 scheme 程式看,對於初次接觸 forth 程式的人應該會有幫助。但要注意的是,這裡只是示範性質的實作,畢竟 forth 的內涵跟 c 一樣是個 stack,遞迴深度過深還是會發生 stack overflow 的。

有了 accumulate 後,原題的平方和就可以很輕鬆地 組裝 出來了:

: square ( n -- n' ) dup * ;
: addsq ( a b -- n ) square + ;
: sum-of-square ( list -- n ) 0 ['] addsq accumulate ;

這裡又可以看到 currying 啦!接著只要丟一個 list 就可以了

create list 1 , 2 , 3 , 4 , 5 , nil ,

list sum-of-square . cr

執行完應該可以看到螢幕上出現答案 55。

以上使用的應該可以在任何一個相容 ANS 標準的 forth engine 執行,我自己用的是 pForthficl。裡面用到的一些基本字用法可以參考以前翻譯的教學

建構出基本工具後就可以來寫 SICP 上的作業了。這個題目希望用 accumulate 實作出 sum 和 product,對於學習過函數式程式語言的人應該都不陌生。用 forth 寫起來會像這樣:

: sum     ( list -- n ) 0 ['] + accumulate ;
: product ( list -- n ) 1 ['] * accumulate ;

把剛剛產生的資料餵進去看看:

list sum     . cr
list product . cr

可以看到螢幕上出現 15 和 120。這裡的 product 其實就是 factorial,但一般會設計成接受一個整數參數,而不是一個 list。不過只要稍微包裝一下 product 就可以產生出 factorial 了:

: scratch ( -- addr ) pad 4 cells + ;
: seq ( n -- addr ) scratch swap 1+ 1 do
    i over ! cell+ loop nil swap ! scratch ;
: fact ( n -- n' ) seq product ;

5 fact . cr

到目前為止除了 foldr 比較長一點,其他都是短短的程式。在 forth 的世界中,一般就是這樣透過基本字來組合來建構出複雜的程式,所以也有人說 forth 就像程式語言中的樂高積木一樣。但要設計出好用、好組裝的積木,就需要經驗了。太大的積木不好用,而且複雜不容易維護,所以重新拆解成更小單元;抽出來的積木不好重複利用,則需要重新分析所有程式的演算法核心性質。仔細一想,這不就是 refactoring 的概念嘛!但對於使用 forth 的人來說,不需要別人推廣也不用特別學習,很自然地就在做這件事,好像古老的技術思維又和現代連結上了,而且一點也不會過時。

進一步思考下去,fold 的出現其實也是在對演算法進行分解後,得到的通用工具。其他還有 map、filter 和 zip 等小工具,就像前面提過的,這些成熟的演算也可以回饋到 forth 程式來使用。其實從以前就覺得 forth 有許多資料和程式實作技巧並不是很透明,也不像主流語言這樣持續發展且容易取得;一方面關注的人也不多就是。雖然對於推廣 forth 不太有興趣,不過從現在的技術中找出連結,引入可用的工具,對於 forth 應該會有全新的認識…吧,我想。


Posted in forth

二月 11, 2009
» Line wrap in Emacs

在大部份的編輯器中,對付太長的文字列通常用的是自動換行 (line wrap),就我目前所知,在 Emacs 中有以下幾種不同方式可以選擇:

Line wrap

預設行為即是一般常見的 line wrap。在這種環境下的文字內容並不會被更動,僅在顯示時將超出視窗邊界的部份顯示在下一行,同時在換行處加上一個記號 (如箭頭標示處):


在切割視窗時情況不同:


可以設定一下得到相同行為:

(setq truncate-partial-width-windows nil)


Truncation

打開 truncate line 以後,超出視窗邊界的部份不顯示,同時會在邊界處顯示一個特殊符號作為識別 (與 line wrap 時用的符號不同)。一般適合在寫程式的時候使用

M-x toggle-truncate-lines


也可以寫到 .emacs

(setq default-truncate-lines t)

為了方便可以設個快速鍵:

(global-set-key [f11] 'toggle-truncate-lines)

Filling text

fill 是破壞性操作,會根據 fill-column 的值強制在特定位置插入換行字元。手動操作時只需要按下 M-q 即可,或是乾脆啟用 auto fill:

M-x auto-fill-mode


fill-column

換行寬度可以自行修改,因為設定 fill-column 要求一個數值當作參數,:

C-u 60 M-x set-fill-column

C-u 60 C-x f

fill-prefix

fill-prefix 的內容會自動加到被修改的文字列前面,預設為 nil (代表換行後前面不加任何字)。假設 fill-prefix"… ",則換行後會在該列最前面加上 "… "

設定這個參數可以用 set-fill-prefixC-x .,要注意的是這個動作會將游標所在位置前的同列文字設為 fill-prefix,若在斷行處操作,則整列文字都會被採用。因此我建議透過 eval 方式設定:

M-: (setq fill-prefix "... ")

或乾脆寫進 .emacs


fill prefix 對於整理程式碼註解很有幫助,但對於一般文字也許會造成困擾。要取消 fill-prefix 只需要找個空行再設定一次即可 (minibuf 會顯示 "fill-prefix cancelled")

Long line mode

相較於 fill mode,long line mode 則是溫和的非破壞性操作,只是在顯示上調整成 fill mode 的效果 (soft newline),並不會真的插入換行 (hard newline):

M-x longlines-mode


但顯示與實際內容畢竟有差別,可以將真正的換行處以特殊符號表示以資識別:

M-x longlines-show-hard-newlines


在處理長文字列的顯示上,Emacs 提供了豐富的設定以應付各種需求。就我個人來說,對於一般的文章我習慣用 line wrap 型式顯式;而在編輯程式碼的時候,這種方式反而會破壞縮排的視覺效果,這時改用 truncation 就很適合了。至於 long line mode,我到現在還沒用過。當然,一般編輯程式碼的時候很少會出現超長的程式碼 (也許寫 gtk 程式時例外XD),閱讀上非常不便。非不得已的時候,我會想辦法在 80 columns 內先斷行 (以前留下來的習慣@@),非超出視窗不可的部份,就交給強大的編輯器來處理吧!

Reference


Posted in emacs, Note

二月 5, 2009
» 透過 Outline mode 編輯 Muse 文稿內容

前陣子在使用 muse 撰寫筆記的時候,總覺得要找標題不太方便,似乎也沒辦法透過 speedbar 顯示大綱,玩了半天就想到了 outline mode 這個好東西,剛好語法是一樣的,只要簡單配置一下就可以帶來很大的方便。測試了一下後加了一些設定:

(add-hook 'muse-mode-hook
	'(lambda ()
	   (outline-minor-mode t)))

(define-key muse-mode-map (kbd "<f5>")  'outline-up-heading)
(define-key muse-mode-map (kbd "<f6>")  'outline-backward-same-level)
(define-key muse-mode-map (kbd "<f7>")  'outline-forward-same-level)
(define-key muse-mode-map (kbd "<f8>")  'outline-next-heading)
(define-key muse-mode-map (kbd "<f12>") 'outline-toggle-children)
(define-key muse-mode-map (kbd "C-<f12>") 'outline-mark-subtree)

(define-key muse-mode-map (kbd "C-<f5>") 'outline-promote)
(define-key muse-mode-map (kbd "C-<f6>") 'outline-move-subtree-up)
(define-key muse-mode-map (kbd "C-<f7>") 'outline-move-subtree-down)
(define-key muse-mode-map (kbd "C-<f8>") 'outline-demote)

在進入 muse mode 的同時也啟用 outline minor mode,並設定一些快速鍵以便快速在各個標題之間定位。事後在調整內容次序時,還可以整個 subtree 一起調整,不必再笨笨地用 copy & paste 修改了。


Posted in emacs, Note

十月 19, 2008
» Blogging with Emacs

玩了幾個晚上,總算可以順利從 emacs 裡將文章送到 Blog 了。 自從開始用 emacs 後就一直改用 muse 在寫筆記和報告,設定好以後可以透過 LaTeX 轉換成 PDF 檔,相當方便。用習慣後也曾興起透過 muse 寫 Blog 的念頭,找了很多資料,也知道有很多人實作成功,但說真的要拿來用還是有點問題,主要還是 elisp 不熟,而且大部份的實作竟然都是直接在 emacs 裡寫 html 後送出去 (還有人推薦用 nxml);就算直接在後台寫也有方便的 wysiwyg editor,但 emacs 還有 muse 這個好東西,何必那麼苦命呢。

biggo.com.tw

A Django site.