Hatena::Groupcadr

わだばLisperになる このページをアンテナに追加 RSSフィード

2004 | 12 |
2005 | 01 | 02 | 07 | 10 | 11 |
2006 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 11 |

2008-02-24

LISP引きこもり生活 (1)

| 05:09 | LISP引きこもり生活 (1) - わだばLisperになる を含むブックマーク はてなブックマーク - LISP引きこもり生活 (1) - わだばLisperになる

私は実生活では、生きることに疲れ、貯金を食い潰しつつ、ひきこもり生活をしているわけなのですが、一歩進んで、コンピュータ環境的にはLISPに引きこもることにしてみました。なんとなく、面白そうなので。

具体的にどういうことかというと、理想としての最終引きこもり形態としては、Lispマシン上から一歩も外に出ないような生活となります。

しかし、そんなことは現実問題として無理なので、この理想にどうにか近付きつつ、現状の快適さもできるだけ損なわない、というのを目標にしようかと思います。

色々段階はあるかと思いますが、始めてみないことには分からないので、とりあえずLISP系のアプリケーションで代替できそうなものは徐々に置き換えて行くことにします。

まず、最初に何から置き換えようかと考えたのですが、やはり、ログインシェルかなと思います。

Lispマシン上で日常作業はどのように行われていたのかは、知る由もないのですが、なんとなくの私の見当では、UNIXのように、インタラクティブにシェルを操作するのではなくて、エディタのバッファ上から、色々な操作を行っていたのではないかなと想像しています。

実際Lispマシンのエミュレータを使ってみても、エディタ上のLispの式を評価することによってOSを操作できるので、エディタ上で大概のことは操作できてしまいます。

なんというか、Emacsの*scratch*バッファで、OSを全部操作するような感じで。

恐らく、シェルのインタラクティブ性というものは、端末からログインして作業する、ということを前提に発展してきたのだと思いますが、Lispマシンはその辺の考え方も違っていそうです。この辺は現状でも生き残っているSmallTalkはどうなっているのか興味があるところですね。

それで、エディタからなんでも操作するのを実現する方法なのですが、SLIMEを使っていて、非常にこれに近いものを感じるので、何でもSLIMEごしに作業することにしてみました。

そしてそれと同時に、便利なZshの使用を停止し、SLIMEから操作した方が楽な状況に強制的に追い込むことにしようということで、ログインシェルをSCSHとGaucheに変更。Zshよ、8年間ありがとう…。

そのうち、initをCLの処理系に置き換えられればと思いますが、さすがに無理かな(笑)

とりあえず、ログインシェルは置き換えたので、SLIMEから操作するということは、どういうことになるのか、適当に何か作って試してみることに。

第1弾として、wgetもどきを作ってみました。

この位なら、まだ手の届くところかなとは思いますが、システム管理とかどうするんだろう…(´▽`*)…。

;; 使用例
(wget "http://prdownloads.sourceforge.net/scsh/scsh-0.6.7.tar.gz" "/var/tmp/")
;=>
; http://prdownloads.sourceforge.net/scsh/scsh-0.6.7.tar.gz ==> /var/tmp/scsh-0.6.7.tar.gz
; ....................................................................................................102400
; ....................................................................................................204800
; ...

;; 定義
(defpackage :home 
  (:use :cl)
  (:export :wget))

(in-package :home)

(defun wget (uri &optional (dir "./"))
  (let* ((file-name (aref (nth-value 1 (ppcre:scan-to-strings ".*/([^/]*)$" uri)) 0))
	 (out-file (concatenate 'string dir file-name)))
    (format t "~A ==> ~A~%" uri out-file)
    (with-open-file (out out-file
			 :direction :output 
			 :if-exists :supersede
			 :element-type 'unsigned-byte)
      (with-open-stream (str (drakma:http-request uri :want-stream 'T))
	(do ((s (read-byte str nil -1) (read-byte str nil -1))
	     (cnt 0 (1+ cnt)))
	    ((= -1 s) (format t "end ~A.~%" cnt))
	  (write-byte s out)
	  (when (and (zerop (rem cnt 1024)) (not (zerop cnt)))
	    (princ ".")
	    (when (zerop (rem cnt (* 100 1024)))
	      (format t "~A~%" cnt))))))))

たまにするならこんな拡張

| 01:03 | たまにするならこんな拡張 - わだばLisperになる を含むブックマーク はてなブックマーク - たまにするならこんな拡張 - わだばLisperになる

Arcのafn(On Lispでのalambda)は、使い捨て感覚の関数に付ける名前を考えなくても良いので、個人的に気に入って使っているのですが、引数の取り方がlambdaと一緒のため本体部分が長くなると読み辛くなるかなあと思います。

そこで、形式をlambdaからletにしたものはどうかなと思い、そんなのを作ってみることにしました。要するに名前付きletのアナフォリック版ということですね。

それで名前をどうするか考えたんですが、Arcでletは1引数なので、そうなるとwithになるかと思い、awithにしてみました。

全体的には割とすっきり書けて良い感じにも思えるのですが、引数部分がなんとなくごちゃごちゃしてる気もします。

また、ドットで連結するのに馴れると(+ 1 foo)のようなものも1+.cntのように書きたくなってくるので、 古式ゆかしいadd1という名前の復活も試してみることにしました。

(mac awith (binds . body)
  (let b (pair binds)
    `((afn ,(map car b)
	,@body)
      ,@(map cadr b))))

(set add1 [+ _ 1])
(set sub1 [- _ 1])

;; 使用例
(def rotate (lst pos)
  (let pos (mod pos len.lst)
    (awith (lst lst acc () cnt 0)
      (if (or no.lst (is pos cnt))
          (join lst rev.acc)
	  (self cdr.lst
		(cons car.lst acc)
		add1.cnt)))))