2008年1月31日星期四
2008年1月4日星期五
LispWorks Personal Edition now supports Mac OS X 10.5 (Leopard).
目前最新版的 Lispwork 個人版 ( 也就是免費版 )
已經支援到 Mac OS X 10.5 (Leopard) 了, 雖然我沒用 Mac,
但是不少厲害的程式設計師都是用 Mac 的, 可以考慮用用看...
而且這個個人版是 10.5.2, 比之前的 Windows 的個人板 10.5.1 還多一級說.
已經支援到 Mac OS X 10.5 (Leopard) 了, 雖然我沒用 Mac,
但是不少厲害的程式設計師都是用 Mac 的, 可以考慮用用看...
而且這個個人版是 10.5.2, 比之前的 Windows 的個人板 10.5.1 還多一級說.
2007年8月30日星期四
Common Lisp 和 Java 的橋樑(Allegro Lisp)
Allegro Lisp 提供了兩個和 Java 之間橋樑的方法, 一個是 JLinker, 這個算是使用 native call 或 socket 方式, 由 Lisp 端呼叫 Java 的函式, 不過, 由於 Lisp 是動態語言, 要呼叫 Java 的程式不免要定義一端 Java 靜態語言的型別等等, 使得在定義宣告和實際使用方式上, 我是覺得有點類似 Lisp ffi
也就是 Lisp 呼叫 C 那樣的宣告的感覺.
另一個方式是直接將 Lisp Code compile 成 JVM bytecode class,
不過這個方式, 雖然表面上是 Lisp, 但是實際上已經用的是和 Java 類似的語法.
( 這個要 Allegro Lisp 專業版以上才有支援 )
可以說是兩種方式雖然都能使用到 Java 的 Library, 但是實際上都不算太好用.
也就是 Lisp 呼叫 C 那樣的宣告的感覺.
另一個方式是直接將 Lisp Code compile 成 JVM bytecode class,
不過這個方式, 雖然表面上是 Lisp, 但是實際上已經用的是和 Java 類似的語法.
( 這個要 Allegro Lisp 專業版以上才有支援 )
可以說是兩種方式雖然都能使用到 Java 的 Library, 但是實際上都不算太好用.
2007年8月24日星期五
*macroexpand-hook*
Common Lisp 的巨集, 可以在展開時加入一個 hook,
讓你控制 Common Lisp 的展開的情形.
像是這樣
建立一個基本的函式, 讓它於巨集展開之時並顯示
hook 是一個接收三個引數的函式, 最重要的是中間的引數 form.
另外 hook 函式中必須使用 compiled 函式較為安全,
以免造成巨集重複展開的無窮廻圈.
任意建一個巨集如下 :
讓它展開, 這邊使用 let 讓它的 scope 不會擴展到全域
就可以出現以下的結果了
讓你控制 Common Lisp 的展開的情形.
像是這樣
(defun hook (expander form env)
(format t "Now expanding: ~S~%" form)
(funcall expander form env))
建立一個基本的函式, 讓它於巨集展開之時並顯示
hook 是一個接收三個引數的函式, 最重要的是中間的引數 form.
另外 hook 函式中必須使用 compiled 函式較為安全,
以免造成巨集重複展開的無窮廻圈.
任意建一個巨集如下 :
(defmacro machook (x y)
`(/ (+ ,x ,y) 2))
讓它展開, 這邊使用 let 讓它的 scope 不會擴展到全域
(let ((*macroexpand-hook* #'hook))
(macroexpand '(machook 1 2)))
就可以出現以下的結果了
Now expanding: (MACHOOK 1 2)
(/ (+ 1 2) 2)
2007年7月9日星期一
Allegro Lisp 之 OLE 物件之使用
先定義 InternetExplorer 物件
(ole:def-ole-linkage #:msx :application "InternetExplorer")
建立物件
(setq browser (make-instance 'msx:InternetExplorer))
連至 OLE Server
(ole:connect-to-server browser :inplace nil)
設定 OLE 物件屬性, 此例之 Visible 設為 true
(setf (msx:Visible browser) t)
呼叫 OLE 物件函式, 此例呼叫 Navigate2 函式
(msx:Navigate2 browser "www.franz.com")
(ole:def-ole-linkage #:msx :application "InternetExplorer")
建立物件
(setq browser (make-instance 'msx:InternetExplorer))
連至 OLE Server
(ole:connect-to-server browser :inplace nil)
設定 OLE 物件屬性, 此例之 Visible 設為 true
(setf (msx:Visible browser) t)
呼叫 OLE 物件函式, 此例呼叫 Navigate2 函式
(msx:Navigate2 browser "www.franz.com")
2007年6月23日星期六
談談 Allegro Lisp 的 socket 機制
要做到一個 robust 的 socket server,
必須能夠處理 read 及 write 的 blocking 機制,
也就是說, read 和 write 都不能 block 掉整個 thread
基本上用多執行緒也是一個方式, 只是讓 thread 停在那邊,
我覺得不是一個好的 socket 的 server 架構.
一般來說, read 時停住是比較容易被查覺的, 也比較容易處理,
如 Java 的 setSoTimeout, 當 Timeout 時會丟出 InterruptedIOException,
但是 write-timeout 的話呢? Java 最好還是用 nio 吧,
用 select 這種類似 C 的處理方式較穩 ( 雖然不太漂亮就是了 ).
不過本文主題是 Allegro Lisp, Allegro Lisp 在處理 read 的方式來說
較穩的是用 listen 先來查看是否可以 read, 再下 read 指令,
可是 write 呢? 沒有, Allegro Lisp 不像 Lispwork 有 write-timeout 的機制
不過還是可以用 system timeout 來處理, 方式如下
(setq s (socket:make-socket :remote-host "127.0.0.1" :remote-port 7035))
(dotimes (i 10000000)
(sys:with-timeout (1)
(write-sequence #(1 2 3 4 5 6 7 8 9 10) s)
(force-output s))
(format t "~a~%" i)
(sleep 0.1))
註: read 和 write 的不同點
read 是對 socket 讀資料, 如果 socket 沒資料就會 block 在那邊
write 一般就算對方不讀任何資料, 也要等到 buffer 爆 (default 約 33000 byte)
才會 block 在那邊
一般處理方式主要有:
1. 使用非同步 I/O
2. 在 read/write 前先偵測狀態, 或是使用事件式來處理
3. 使用 timeout 機制
必須能夠處理 read 及 write 的 blocking 機制,
也就是說, read 和 write 都不能 block 掉整個 thread
基本上用多執行緒也是一個方式, 只是讓 thread 停在那邊,
我覺得不是一個好的 socket 的 server 架構.
一般來說, read 時停住是比較容易被查覺的, 也比較容易處理,
如 Java 的 setSoTimeout, 當 Timeout 時會丟出 InterruptedIOException,
但是 write-timeout 的話呢? Java 最好還是用 nio 吧,
用 select 這種類似 C 的處理方式較穩 ( 雖然不太漂亮就是了 ).
不過本文主題是 Allegro Lisp, Allegro Lisp 在處理 read 的方式來說
較穩的是用 listen 先來查看是否可以 read, 再下 read 指令,
可是 write 呢? 沒有, Allegro Lisp 不像 Lispwork 有 write-timeout 的機制
不過還是可以用 system timeout 來處理, 方式如下
(setq s (socket:make-socket :remote-host "127.0.0.1" :remote-port 7035))
(dotimes (i 10000000)
(sys:with-timeout (1)
(write-sequence #(1 2 3 4 5 6 7 8 9 10) s)
(force-output s))
(format t "~a~%" i)
(sleep 0.1))
註: read 和 write 的不同點
read 是對 socket 讀資料, 如果 socket 沒資料就會 block 在那邊
write 一般就算對方不讀任何資料, 也要等到 buffer 爆 (default 約 33000 byte)
才會 block 在那邊
一般處理方式主要有:
1. 使用非同步 I/O
2. 在 read/write 前先偵測狀態, 或是使用事件式來處理
3. 使用 timeout 機制
2007年6月22日星期五
中文字碼轉換 CP950
Allegro Lisp 的方式如下
(excl:octets-to-string (excl:string-to-octets "中文"))
Lispwork 的方式如下 (目前只適用 Lispwork Windows 版, 感謝大陸網友 Binghe 提供)
(ef:decode-external-string (ef:encode-lisp-string "你好" '(win32:code-page :id 950)) '(win32:code-page :id 950))
(excl:octets-to-string (excl:string-to-octets "中文"))
Lispwork 的方式如下 (目前只適用 Lispwork Windows 版, 感謝大陸網友 Binghe 提供)
(ef:decode-external-string (ef:encode-lisp-string "你好" '(win32:code-page :id 950)) '(win32:code-page :id 950))
訂閱:
文章 (Atom)