作者yauhh (喲)
看板PLT
標題Re: [問題] Self的sorting
時間Sat Mar 3 22:51:58 2012
※ 引述《mark1357945 (浮夢)》之銘言:
: 我最近在大學的程式語言課程選了Self當作自己的主題語言
: 不過似乎這個語言還滿冷門的 週遭的人很多都沒聽過
: 搜尋過也看了一些論文 但有關Self的sorting相關資料也不太多
: Smalltalk相關的卻是找到了不少
: 可是第一次接觸Prototype-based的OO語言 (之前只學了C++ 一、兩年)
: 現在還沒有把握能把Smalltalk的code直接看文法轉譯成Self的版本
: 有高手對這個語言熟悉可以推薦一些書本或參考資料適合入門
: 或是能講解一下有關實作heap sort的嗎?
上次見到這問題,花了一些時間將Self和Smalltalk學起來,終於覺得能掌握一二分,
現在來寫寫心得.
| Smalltalk |
Smalltalk這個語言很妙,從1990年之前,發明者開始設計時,就說這個語言包容了
語言,平台與環境,所以到目前的實作是包含作業系統的虛擬機器,即使檔案系統
也加以抽象包覆,最後可以說是一套pure object-oriented programming language.
然後他們比較鼓勵你,寫程式是在一個現成的虛擬平台上,把碼加上去,把Unit Test
做上去,你的程式碼加進現有的系統,結果就產生新的系統. 於是Kent Back這位
Xtrame Programming的發揚者也蠻喜愛Smalltalk這個語言平台,因為充份發揮了
XP精神.
我選擇一種特定的Smalltalk實作,稱為Pharo. 所謂排序,大概就是先定義你的資料
是 #(5 2 3 7 6 4) 像這樣的陣列,然後對這個陣列送一個訊息sort,請它排序.
呼叫程式如下:
#(5 2 3 7 6 4) sort
Smalltalk講物件導向,是說凡是都是物件. 而像上面一行程式那樣有二個物件排在
一起的時候,最前面的物件是接收者,而後面全部的物件或標籤,數字等等,全都是
訊息. 物件導向最原始的精神就是,對物件傳送訊息,這些訊息也就構成你與物件之間
的介面.
回頭來看現在Java,有哪些人寫熟了能夠意識到像以下這行究竟如何稱為物件導向:
sorter.sort(data); // data = {5, 2, 3, 7, 6, 4}
什麼是物件? 什麼是訊息? 什麼是介面? 搞不清楚,然而就算搞不清楚,很重要嗎?
或者這麼說,將一些東西歸類為Java所稱的interface之後,所獲得的只是專屬於
interface的制式語法...... 諸如此類,如此一來,反而被語法綁得死死的.
Smalltalk的排序. 像泡沫排序大概是這樣子寫:
| list n maybeSwap | "宣告區域變數"
list := #(5 2 3 7 6 4).
n := list size. "對list送size訊息"
maybeSwap := [ :i :j | |x y| i < j ifTrue: [ x := i. y := j ]
ifFalse: [ x := j. y := i ].
{x. y}
]. "定義 if a > b swap(a,b) 排序邏輯"
1 to: n-1 do: [ :i |
1 to: n-i do: [ :j | |p| p := maybeSwap value: (list at: j)
value: (list at: j+1).
list replaceFrom: j to j with: p
startingAt: 1.
list replaceFrom: j+1 to j+1 with: p
startingAt: 2
]
]. "根據排序邏輯修改list內容"
list "list為傳回值"
以上這段程式碼看起來是程序式的,不過在Pharo,除了只有在稱為workspace的
類似記事本的區域可以寫寫這種腳本之外,沒有別的地方讓你存放一個腳本.
環境中有一大堆Smalltalk的物件類別,你只能找到適合的類別,把程式寫成方法塞進去.
以前面所提到,原本的呼叫程式來說,
#(5 2 3 7 6 4) sort
因為#(5 2 3 7 6 4)屬於Array類別,所以自己弄個Array>>sort方法,把程式貼進去即可.
(Pharo手冊說,提到什麼類別擁有什麼方法,是用 Object>>Method 語法來標記.
不過 >> 這不是Smalltalk的語法,而是Pharo自己的標記法,使文件說明時比較方便.)
| Self |
Self這倒蠻特別的,說是prototype-based programming, 可是仔細看看,Self與
Smalltalk的關係,就像是Javascript自稱object-based相對於Java稱為object-
oriented那樣的差別,也就是說,其實是沒差的: Smalltalk本來就可以算是
prototype-based programming system.
Self跟Smalltalk的程式開發風格一樣,都比較是鼓勵你先拖拉一些GUI物件出來,
然後把程式碼加進去.
不同之處是,恰如prototype-based此稱呼之其份,Self比較少了程式語言中較基本的
物件,例如以排序這個題目來看,我一時找不到有關array的語法.
奇怪了,難道Self都不需要array嗎? 我仔細看看文件,發現Self已經提供許多
collection prototype了,包括有vector, set, dictionary, list, sequence等等.
如果要讀資料,應該是從開檔案開始,使用iterator將檔案紀錄讀進物件中.
先啟動Self,啟動方式是
/usr/bin/Self -s Clean-4.4.snap
即使用VM Self打開OS Clean-4.4.snap. 一開起來看到環境中有一個shell方塊,
就從這個物件開始. 在shell方塊的evaluation文字編輯區域輸入 set copy
然後下面有三個按鈕 "Get it", "Do it", "Close" 點 "Get it" 就會產生一個
新的匿名的set物件. 同理, vector copy 然後 "Get it" 就會出現vector物件.
如果有編譯錯誤或執行錯誤,錯誤訊息也會變成一小塊細細紅色的方塊,跳出來.
這種作法蠻可愛的.
Self 操作手冊,基本是耐心讀僅有的官方網站提供的tutorial和reference manual
就很夠了. 真的最好先熟悉Smalltalk系統操作方式,然後再練習操作Self. 語法方面,
Self和Smalltalk有一點點不同.
我在shell物件中輸入程式如下:
| v. s. i | "宣告區域變數"
s: set copy. "取一個set, set是unordered collection"
s add: 5. s add: 6. s add: 3. s add: 2. s add: 7. s add:4.
v: vector copySize: (s size) FillingWith: 0.
"取一個vector,尺寸跟set s一樣大"
"vector是ordered collection, index是0-based"
i: 0.
s do: [| :n | v at: i Put: n. i: i+1 ].
v
按 "Get it" 得到一個vector v.
然後我把v的屬性框展開來看,發現資料已經排序了.
如此看來,在Self環境中,排序的演算及操作不是很重要的問題. 難怪叫作prototype-
based,因為set是未排序資料的prototype,而vector是以排序資料的prototype.
我覺得好像是這樣子.
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 61.231.68.98
※ 編輯: yauhh 來自: 61.231.68.98 (03/03 23:09)
1F:→ yauhh:哦哦,核對一下,發現我選錯資料結構了. set資料不重複,不適合 03/04 00:37
2F:→ yauhh:一開始拿來存資料. 03/04 00:37
3F:→ yauhh:reference manual提到有PriorityQueue對heapsort很有用.. 03/04 00:38
4F:→ yauhh:以上推文所說的是Self. 03/04 00:41
5F:→ stopcrying:不太明白你說的 prototype是指那方面?是方便做原型? 03/12 01:36
7F:→ yauhh:就是像這個意思,你要用什麼東西都先從系統中找一個像的,copy 03/12 19:46
8F:→ yauhh:來用. 03/12 19:46
9F:→ stopcrying:先把 heapsort放一邊,純 sort的話有個 sortedSequence 03/13 16:19
10F:→ stopcrying:把東西塞塞塞進去就好了說... 03/13 16:19
11F:→ yauhh:所以那樣的sort線性幾乎是insertion sort,非線性大概就是 03/15 20:26
12F:→ yauhh:sort by search tree 03/15 20:27
13F:→ yauhh:或heap sort 03/15 20:27