顯示具有 lisp 標籤的文章。 顯示所有文章
顯示具有 lisp 標籤的文章。 顯示所有文章

星期四, 1月 31, 2008

Arc is released. and is it a Blub?

http://arclanguage.org/

這兩天幾乎網路上所有lisp programmers都在討論Arc,
這個著名lisp hacker, Paul Graham所發明的lisp dialect, 一度被認為是vaporware的語言,在前天release了.

Paul Graham對於lisp社群的貢獻是無庸致疑的,
但這次他所公開release的Arc則是讓不少人大失所望.
畢竟這是他從他首次宣稱Arc is a better lisp以來已經過了6-7年之後釋出的版本,
"just another lisp dialect"似乎是不少lisp programmers的一致意見,
另外此次版本不支援unicode只支援ascii也引發大波瀾.
我自己最近時間不多, 但也小試了一下, and just didn't 'get' it.
我當然理解PG的"Syntax Do Matters",
但我也不完全同意less typing是higher level programming language唯一的路,
非常希望時間能證明, 這只是我們這些 "Blub" programmers的愚昧, 而Arc is indeed a better lisp and a better programming language.

註: Blub是PG發明的字眼. 在著名的Beating the Averages一文裡用來回答一個有趣的問題: "如果lisp這麼好,為什麼都沒人用?" 而描述出一個所謂的Blub弔詭的情境:
Blub是任一種介於比lisp低階 而比machine language高階之間的一個一般強度(power)的程式語言. (比如: python,java,ruby,perl,C/C++,haskell,ML-family,erlang,php,javascript,fortran,cobol.....anything not in lisp-family)
Blub programmer則是Blub programming language的支持/使用者,
Blub programmer的想法是, Blub語言 擁有某些特性X,
他無法想像更低階語言怎麼能夠沒有特性X而能拿來認真的使用.
同一時間他則認為Blub語言已經擁有所有他所需要的特性, 覺得所有比Blub語言更高階的特性全是無用而浪費時間的.

註2: 我的標題意思是Paul Graham在文章裡說他自認為他的Arc語言已經好到可以讓他不想用CL或scheme才release了, 是否也是陷入了Blub弔詭裡?

btw: you need patches to run current Arc on latest mzscheme(352+) or you're on windows(sadly),
see http://arclanguage.org/item?id=319 and http://jfkbits.blogspot.com/2008/01/digging-into-arc-in-24-macros-or-less.html

星期六, 5月 26, 2007

[link] Evolution of a Python programmer

白菜的blog上看到的

http://dis.4chan.org/read/prog/1180084983/

我也來加一個:

Python mind but Lisp/Scheme in heart Programmer:

Y = ( lambda func:
( lambda f: func(lambda x: (f(f))(x)))
( lambda f: func(lambda x: (f(f))(x))))
F = lambda f: lambda x : x==0 and 1 or x*(f)(x-1)
T = Y(F)
print T(6)

星期日, 2月 18, 2007

[link] The Aha! point for lisp.

Aha! While writing YAQL I accidentally discovered Lisp

Greg Trasuk's Weblog:
"""
And then the AHA! moment happens. I finally "get" Lisp! It's just a string representation of the abstract syntax tree for any language! I could embed a Lisp interpreter in the query parser! I could use Lisp macros to perform optimizations on the query! There's a JJTree grammar for Python in the Jython package, I could parse Python into Lisp programs! I'm onto a Really Big Concept! Possibly the Next Big Thing, the grand unification of all scripting languages! Now I have to move back to Xemacs from Netbeans! All I need to do is increase the output by 15% and the city will be mine! If only I had More Power!
"""

話說自從lloyd大大傳授我他壓箱(真的是壓了好多層箱)
的Emacs Lisp聖書三大本,
最近寫Emacs Lisp寫出興趣來了,
發現其實Lisp很好玩,
以前雖然也沒事會裝裝武林高手,
用用lambda,map,filter...blahblah...
雖然把Code寫成一副很有"尊嚴"的樣子,
但是其實心裡總是覺得夾在Python的Code裡面就怪怪的,
多寫幾個就覺得很醜... 所以其實也只是偶而拿來減少一下loop需求而已.
但是, 果然玩了Lisp之後才知道人家是正牌的... XD

所以最近沒事都在讀讀Practical Common Lisp跟玩玩Emacs,
(不過最常幹的還是看動畫念日文跟網路亂逛), 然後看到這篇其實寫的很不錯.

他沒講到的話 我還真的不知道... 覺得這篇很有啟發性...
把任何語言的AST寫成字串形式其實就是LISP...(筆記筆記)
1958年就應該要知道的東西...
結果總是有人(就是我們這代人)在重造輪子...
算了, 反正造輪子總是比較爽... 自產自銷 XD

不過還是要說... 拜Python教的大家絕對不用氣餒...
Python+Django是無敵的...
(ㄟ lloyd大大...你又可以演吐槽角色了...)

星期六, 2月 17, 2007

lython approach 1.0 !?

繼不久前很久沒放出新版本的jython 放出了第一個2.2 beta之後,
lython突然也放出了 1.0版本,
原來是近期多了一位熱血開發者faulkner,
玩了一下發現很不賴, 可以使用CPython的Library啊!!!
排除了Not Enough Library這個問題之後,
Lisp就是非常非常吸引人的程式語言.

lython可以使用Lisp語法/Macro加上Python的Library,
而且仍然是產生.pyc ,
所以即使沒裝lython只要有CPython還是可以跑, 實在是很不錯.
希望faulkner再接再厲,
這樣的話就輪到有人寫一篇 Why lython is an acceptable LISP 的時候了. XD

lython內附的Example之一:


file-hello-world.lth
(import os)

(:= out "/tmp/lythontest")
(if (os.path.exists out)
(os.unlink out)
(print "target file does not exist"))

(:= f (open "/tmp/lythontest" "w+"))
(f.write "Hello World from Lython!\n")
(print "write you a letter in /tmp/lythontest")
(f.close)


Lython的interactive interpreter也學python學的很像:

-bash-3.00$ lython.py
Lython (experimental)
Type "(help)" if you need it.
Ly> (for x (range 10) (print x))
0
1
2
3
4
5
6
7
8
9

星期五, 2月 16, 2007

[link]Programming Language Stories

http://weblog.raganwald.com/2007/02/programming-language-stories.html

這篇好笑(難笑?!)的文章唯一跟Python有關的部份是跟使徒聖彼得對話的這段:

*****RoR閃光開始*****

Peter: “Welcome to heaven. Programming language?
聖彼得: 歡迎來到天堂. 用的程式語言?

Person #3: “Python.”
丙兄(前面Smalltalk跟Common Lisp的人都通過了): Python

Peter: “Room 54. Be very quiet as you pass Room Six.”
聖彼得: 五十四號房. 當你經過六號房時要很安靜的通過.

Person #3: “Why do you keep telling us to be quiet as we pass Room Six?”
丙兄:為甚麼你持續的跟我們說要很安靜的通過六號房?

Peter: “Because the Ruby on Rails People are in Room Six, and they think they’re the only ones here.”
聖彼得: 因為RoR那群人在六號房. 他們認為只有他們在這裡.

*****RoR 閃光完畢*****

但我覺得其實最好笑的是Scheme的部份, 好笑在哪裡?

哎呀, 其實是很難笑啦... 特別是你認真的從頭看到尾之後...

星期四, 2月 15, 2007

Bash-like Tab Completion in Emacs python-mode

Just hacked a bit, and a bash-like tab-completion in emacs python-mode is done. :)

Thanks Yuan Liu's tip and my friend lloyd's advices and tests,
also pymacs and python-mode developers,

it works quite well for tab completion using just tab key in python-mode.

1. install python-mode and pymacs

2. change /usr/share/emacs/site-lisp/python-mode/pycomplete.el to:


;;; Complete symbols at point using Pymacs.
;;; See pycomplete.py for the Python side of things and a short description
;;; of what to expect.

(require 'pymacs)
(require 'python-mode)

(pymacs-load "pycomplete")

;;check if prev character is blank-type
(defun char-before-blank ()
(save-excursion
(forward-char -1)
(looking-at "[\n\t\r]")))

(defun py-complete ()
(interactive)
(let ((pymacs-forget-mutability t))
(if (and
(and (eolp) (not (bolp))
(not (char-before-blank))))
(insert (pycomplete-pycomplete (py-symbol-near-point) (py-find-global-imports)))
(indent-for-tab-command))))

(defun py-find-global-imports ()
(save-excursion
(let (first-class-or-def imports)
(goto-char (point-min))
(setq first-class-or-def
(re-search-forward "^ *\\(def\\|class\\) " nil t))
(goto-char (point-min))
(setq imports nil)
(while (re-search-forward
"\\(import \\|from \\([A-Za-z_][A-Za-z_0-9\\.]*\\) import \\).*"
nil t)
(setq imports (append imports
(list (buffer-substring
(match-beginning 0)
(match-end 0))))))
imports)))

(define-key py-mode-map "\M-\C-i" 'py-complete)
(define-key py-mode-map "\t" 'py-complete)

(provide 'pycomplete)


3. change /usr/lib/python2.4/site-packages/pycomplete.py to:
(change your python path if different python version)

"""
Python dot expression completion using Pymacs.

This almost certainly needs work, but if you add

(require 'pycomplete)

to your .xemacs/init.el file (.emacs for GNU Emacs) and have Pymacs
installed, when you hit TAB it will try to complete the dot expression
before point. For example, given this import at the top of the file:

import time

typing "time.cl" then hitting TAB should complete "time.clock".

See pycomplete.el for the Emacs Lisp side of things.
"""
import sys
import os.path
import string
from Pymacs import lisp

sys.path.append(".")

try:
x = set
except NameError:
from sets import Set as set
else:
del x

def get_all_completions(s, imports=None):
"""Return contextual completion of s (string of >= zero chars).

If given, imports is a list of import statements to be executed first.
"""
locald = {}
if imports is not None:
for stmt in imports:
try:
exec stmt in globals(), locald
except TypeError:
raise TypeError, "invalid type: %s" % stmt
except:
continue
dots = s.split(".")
if not s or len(dots) == 1:
keys = set()
keys.update(locald.keys())
keys.update(globals().keys())
import __builtin__
keys.update(dir(__builtin__))
keys = list(keys)
keys.sort()
if s:
return [k for k in keys if k.startswith(s)]
else:
return keys

sym = None
for i in range(1, len(dots)):
s = ".".join(dots[:i])
try:
sym = eval(s, globals(), locald)
except NameError:
try:
sym = __import__(s, globals(), locald, [])
except ImportError:
return []
if sym is not None:
s = dots[-1]
return [k for k in dir(sym) if k.startswith(s)]

def pycomplete(s, imports=None):
completions = get_all_completions(s, imports)
dots = s.split(".")
result = os.path.commonprefix([k[len(dots[-1]):] for k in completions])

if result == "":
if completions:
width = lisp.window_width() - 2
colum = width / 20
white = " "

msg = ""

counter = 0
for completion in completions :
if completion.__len__() < 20 :
msg += completion + white[completion.__len__():]
counter += 1
else :
msg += completion + white[completion.__len__() - 20:]
counter += 2

if counter >= colum :
counter = 0
msg += '\n'

else:
msg = "no completions!"
lisp.message(msg)
return result

if __name__ == "__main__":
print " ->", pycomplete("")
print "sys.get ->", pycomplete("sys.get")
print "sy ->", pycomplete("sy")
print "sy (sys in context) ->", pycomplete("sy", imports=["import sys"])
print "foo. ->", pycomplete("foo.")
print "Enc (email * imported) ->",
print pycomplete("Enc", imports=["from email import *"])
print "E (email * imported) ->",
print pycomplete("E", imports=["from email import *"])

print "Enc ->", pycomplete("Enc")
print "E ->", pycomplete("E")

# Local Variables :
# pymacs-auto-reload : t
# End :


4. add this line into your .emacs
(require 'pycomplete)

That's it!

ps: you can also grab pycomplete.el and pycomplete.py here

ps2: if you install python-mode and pymacs from scratch,
don't forget add these lines in your .emacs:

(add-to-list 'load-path "/usr/share/emacs/site-lisp/python-mode")

(autoload 'python-mode "python-mode" "Python editing mode." t)
(autoload 'jython-mode "python-mode" "Python editing mode." t)
(autoload 'py-shell "python-mode" "Start an interactive Python interpreter in another window." t)
(autoload 'doctest-mode "doctest-mode" "Editing mode for Python Doctest examples." t)
(autoload 'py-complete "pycomplete" "Complete a symbol at point using Pymacs." t)

(add-to-list 'auto-mode-alist '("\\.py$" . python-mode))
(add-to-list 'auto-mode-alist '("\\.doctest$" . doctest-mode))

(add-to-list 'interpreter-mode-alist '("python" . python-mode))
(add-to-list 'interpreter-mode-alist '("jython" . jython-mode))

(add-to-list 'load-path "/usr/share/emacs/site-lisp/pymacs")

(autoload 'pymacs-load "pymacs" nil t)
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")

星期日, 2月 11, 2007

Emacs的文化衝擊

There's nothing wrong with static type systems.
You just have to realize that when you use them, you're building hardware, not software.
-- Steve Yegge


ESR曾經說, 即使妳不用lisp, 妳也該學習lisp, 因為學習lisp會讓妳成為更好的Progammer.
這幾天玩弄Emacs下來, 我不得不說, 如果妳是Programmer, 即使妳不用Emacs作為編輯器,
妳也該瞭解Emacs, 因為瞭解Emacs會讓妳瞭解什麼是好的軟體設計.

***

Emacs是一個環境, 妳不是在"用"一個Emacs, 而是你"進入"了Emacs, 妳活在Emacs的國度裡.
隨便打開一個*scratch* buffer, 輸入(message "hello") 然後 C-M-x , it's EVALUATE!!
如果以其他系統的角度來說. 你已經做好了你的第一個Emacs plugin.
改好你的.emacs , M-x eval-buffer, 新的設定已經載入了.
RESET? 不, 好的"""軟體"""系統不用reset.
Ok, I'll say, Hardware plugs, Software's spirit is: Evaluate, and it's done.

***

我喜歡Python的introspective跟豐富help, 只要能打開python的直譯器, 我幾乎很少需要書籍或線上文件.
Emacs的系統也是一樣, 我原本不能理解當vim user在強調keystroke時, Emacs User那種不屑/不在意的態度.
我現在能理解了, Emacs擁有非常高明的help系統. 忘記了keystroke, 妳還有GUI, 即使妳像我一樣不使用Emacs的GUI,
Emacs的help系統會讓妳忘了為什麼需要GUI. M-x apropos跟C-h C-h是好朋友,
妳忘了keystroke, 妳可以鍵入長指令查keystroke, 妳忘了長的指令, 妳可以用keystroke查詢,
妳什麼都忘了, 只要妳還記得 M-x apropos或C-h, 還是有辦法記起來.

而一旦defun被eval, 他就能夠立即的被啟動, 回傳的值也立刻能在mini-buffer裡看到,
所有自定義的function妳只要能記得開頭的字母, 也都隨時可以按tab兩次顯現,
喔, docstring, help, 使用etags查詢某個function還能即時探索該function在emacs的elisp code,
所有動作都不必離開Emacs, introspective至如此,夫復何求?

***


Systems should never reboot.
Great software systems are introspective.

我現在很清楚的瞭解他指的是什麼了, 如果妳不能理解, 建議你玩玩Emacs.
Emacs是Dynamic的典範, 是超越了時代的設計,
我很難想像這是一個80年代開始發展的系統.
我以往從來不在意Emacs或者Vim的所謂編輯器聖戰,
原本覺得那是意氣之爭, 但即便對某些人是意氣之爭,
但認真去瞭解Emacs還是教了我很多,
僅在數天之內, 我便開始瞭解聖戰為何而戰.
Vim可能符合了這一代人對軟體,對編輯的期望,
但那是現在, 軟體的歷史還年輕的很, 而Emacs的戰場還在未來.
是因為有了堅持跟夢想, 才會有了這個不流血的戰場.
在可見的未來, Emacs的聖戰將會繼續打下去.

星期六, 2月 10, 2007

Emacs

受到lloyd大大的影響,
基本上最近我也加入了拜lisp教之Emacs分會.

剛好Stevey的blog也寫了一篇有關Emacs的文章, 就拿來試一試吧.

果然, lisp在Emacs底下寫很有感覺啊...


(defun blog-column-length ()
"Print stats on current blog column, or blogollum, or whatever"
(interactive)
(save-excursion
(goto-char (point-min))
(let ((char-count 0))
(while (not (eobp))
(unless (looking-at "[ \t\r\n]")
(setq char-count (+ 1 char-count)))
(forward-char 1))
(message "%d chars, %d words" char-count (/ char-count 5)))))


ps:不過我這邊的ntemacs23沒有(require 'cl)
所以就把原本的incf改成了setq.

update: 剛看了這段Emacs Screencast, 非常令人讚嘆.

update2: 又學會一招
http://www.gnu.org/software/emacs/elisp/html_node/Simple-Macro.html#Simple-Macro
(defmacro incf (var)
(list 'setq var (list '1+ var)))