A beginer's journey to SBCL's closure.

I've written a blog article about the layout of closures in SBCL. Not so sure about the correctness of the content.

Related comments are always welcome!!


on Lisp being the string representation of AST

Lisp uses the string representation of AST as its syntax.

The good thing derived from this is: you have the whole AST available for massage, to transform it to whatever form. That's exactly what a control statement does.

But in languages like C, you cannot easily have the AST ready for the exact corresponding code you're writing now, which means it's hard, though not impossible , to transform or operate the AST using the code you are writing now. One might argue he does not need new control statement, but the ability to add new control statement matters for expressiveness and ease of generating DSLs.

My thinking about Lisp's Macros

Macro is just let over lambda with prameterable bindings or body. Both being parameterable makes a macro-writing macro template: once given one, a macro is generated which expects another part. Again, this is just lamda with two parameters, two variables.

Macro and lambda differ in that the evaluation system treats them differently: macro has access to raw lambda list, unevaluated.

Macro is just lambda that has the chance given by the evaluation system to manipulate the raw lambda list and writes out new lists to replace itself. The unique and unified syntax of lisp renders the difficulty of writing them to be near to zero.


remove the ".exe" suffix of commands in bash on Cygwin when completing

Because I think the extra ".exe" takes too much space when multiple pipelines are used in a one-liner task.

Basically it's a small change to the file lib/readline/complete.c in bash's source code.

Find the definition of the function "make_quoted_replacement" and change the line

replacement = match;


if(strstr(match, ".exe") != NULL) {
replacement = (char *) xmalloc(strlen(match) - 4 + 1);
memset(replacement, 0, strlen(match) - 4 + 1);
strncpy(replacement, match, strlen(match) -4);
} else {
replacement = match;

Then recompile it to deploy.


change the case sensitivity of pathname completion in bash

I don't like bash being case-sensitive when cd to different directories because when there are upper-case letters in directory names usually either the capslock or the shift key has to be pressed which slows speed of switching paths. Thus in all my boxes where bash exists(linux machines, cygwin on windows boxes & my macbook running Snow Leopard) I have set up the ~/.inputrc file to contain this line to turn off the case-sensitivity:

set completion-ignore-case on

But there were cases that I'm using somebody else's bash shell instead of my own, which does not disable that case-sensitivity and would cause inconvenience for me(yes, to some extent). And today an idea occurred to me that bash may very likely support some kind of volatile switching this feature on and off. So I tried `man bash` and found a rather ugly solution:

1. create a tmp file, let's say "/tmp/inputrc" and type that line above in it.
2. in this bash shell, set the $iNPUTRC env variable by type in the command `export INPUTRC=/tmp/inputrc`
3. also in this bash shell, press the keybinding C-x C-r(which runs the readline command "re-read-init-file") to load the setting just typed in.

and now this bash shell is enabled with case-insensitivy.

It's rather a tedious and ugly solution.

PS: I tried to run this command

set completion-ignore-case on

in the bash shell as described in this cyberciti page. But it proved no effect at all.


first try on cl-cont's continuation

(defun pn (n)
(cond ((eq 0 n) (format t "~A "'DONE))
(t (cl-cont:call/cc (lambda (k)
(funcall k (pn (- n 1)))
(format t "~A " n)))))))


fix the M-. behavior in iTerm under Snow Leopard

I found that one of my favorite keyboard shortcuts refused to work, after my MB has been upgraded to the Snow Leopard. That striking keybinding is "M-.", which used to bring the last argument of the most recently committed bash command to the cursor's very position on bash's input line(thanks to libreadline, which provides this feature and other which are similar to those keybinding in Emacs[God's editor, yes]), now will introduce a "≥" symbol instead in iTerm.

iTerm is more user-friendly than the Terminal.app which is originally contained in Leopard and Snow Leopard. For example I can use Command+1, Command+2 to switch to different tabs in iTerm(and I know that GNU Screen can sometimes make the tabs useless and unnecessary, but consider that what if I'm connected to several remote hosts via ssh?), which may not be possible(or at least not easy to do so) in Terminal.app. And that's why I feel that life sucks when forced to use the Terminal.

I had thought that it's because the iTerm is too old to work with SL, because that version was released in April, 2009 and it indeed worked smoothly in Leopard. So I decided to wait for a newer version of iTerm. And today when the newer version comes. I can't help to upgrade it, with full expectation that it will solve that problem(M-. does not work as it did). But, I was made disappointed because, it DOES NOT work like that!

OK. Maybe I have to turn to some other dirty way. I first tried to use the mapping function in iTerm to deceive bash that whenever the M-. is pressed it should be taken as the right keycode to bring up the last argument of the last bash command. but I failed because, the "xev" program reported the same keycodes in both iTerm and Terminal(remember that M-. works as _I_ expected in Terminal).

Then, I remembered that I had once made some customized keybindings in bash via the ~/.inputrc file under Linux, which controls mappings between keyboard inputs and what bash see. With even no expectation that it will work, I put this line:

"≥": yank-last-arg
into my ~/.inputrc.

After iTerm's relaunch, M-. succeeds to just emit the last argument... which I have longed for about 4 weeks.


[Small Pieces In Emacs] Copy the name or path of the current buffer's file, if any.

(defun zs-copy-current-file-name-to-system-clipboard (&optional full-path-p)
"copy, if the current buffer accesses a file, the name or file path(given a
prefix argument) to the system clipboard(if under X) and append to the killing
(interactive "P")
(if (buffer-file-name)
(if full-path-p
;; (x-select-text (buffer-file-name))
(kill-new (buffer-file-name))
;; (x-select-text (file-name-nondirectory (buffer-file-name)))
(kill-new (file-name-nondirectory (buffer-file-name)))


Strange svn behavior when specifying username

It seems that the --username option is totally ignored by svn when you later try to update or commit (or any operations that have to be performed interactively with the svn server) if the svn+ssh protocol was used to check out the code initially _AND_ at that same time you did not specify a username directly in the svn+ssh url(which is often later provided when the server asks for it). According to this mailing list thread this problem only happens to the svn+sshl combination.

Then, how this problem be by-passed? It's easy with the help of svn's "switch --relocate" facility. Let's say the original svn+ssh url is "svn+ssh://svn.example.com/path/to/repos"(which you can find in each .svn directory's entries file), then the username can be add to the url after you've changed the current directory to the local svn copy's root directory by:

svn switch --relocate svn+ssh://svn.example.com/path/to/repos svn+ssh://username@svn.example.com/path/to/repos .

That's a simple one-liner command. Do remember to replace the "username" with your real username used and don't forget the final dot "." which means the current directory.