読者です 読者をやめる 読者になる 読者になる

レガシーコード生産ガイド

私に教えられることなら

ジャバスクリプトでLisp開発記録

JavaScript lisp

10/22から作り始めてて、見返し用に開発記録を書いておくことにした。

動作サンプル

なまえは、環境がNirnLeafで、言語がNirnLisp。

自作のS式→JavaScriptトランスレータjasj書いてるので、altJSでと言ったほうがいいかもしれない。ごく薄いトランスレータなのでaltJS感は(自分には)ないけど。

動機

  • ブラウザでうごく、内部が完璧にわかってる、自分好みのLispが欲しい
  • とにかく自分に合ったプログラムの触り方をしたい
  • mispliがかっこいい
  • 今年の始めにLisp作ったときの復習がしたい

現時点の仕様

Clojureを参考というか真似している。

  • シンボル
  • 数値
  • 文字列
  • キーワード :foo
  • JavaScript配列 [1 2 3]
  • JavaScriptオブジェクト {:foo 1 :bar 2}
  • true, nil

trueは単にシンボルtrue自身を束縛している。tではない。nilnil

キーワード、配列、オブジェクトは関数としても使える。

([1 2 3] 0) => 1 (:bar {:foo 1 :bar 2}) => 2 ({:foo 1 :bar 2} :bar) => 2

まだimmutableなデータではないのであんまり嬉しくはない。

変数の定義と変更

  • 定義 (def x 1)
  • 変更 (set! x 2)

再defや定義してないもののset!はエラーになる。(変えるかも)

関数と定義

Clojureみたいに、引数は()でのリストではなく[]での配列にする必要がある。

  • 生成 (fn [x] x)
  • 定義 (defn id [x] x)

あと&で可変長引数。

> (defn list' [& xs] xs)
(fn [& xs] xs)
> (list' 1 2 3)
(1 2 3)

マクロ

(fn->mac f)で、引数を評価せずに関数fに渡すマクロオブジェクトが作られる。

それをdefで束縛すれば普通のマクロみたいに、またdefmacで定義可能。

また、バッククォートと、Clojureみたいに~~@によるアンクォートもある。ちゃんと動くかは自信ない。。

例えばwhenなら

> (defmac when [t & body] `(if ~t ((fn [] ~@body)) nil))
(fn->mac (fn [t & body] `(if ~t ((fn [] ~@body)) nil)))
> (when 1 2 3)
3
> (when nil 2 3)
nil

JavaScriptメソッド

先頭が.のシンボルはJavaScriptメソッド用に処理される。ようするにClojureのまねです。

> (.floor Math 1.5)
1
> (.getElementById document "repl-view")
#<JavaScriptObject [object HTMLDivElement]>

まだJavaScriptオブジェクトにそのままアクセスする方法がない(mapは違う構造)ので、それができてからまともに使える、かな。

現時点の組み込み特殊形式、関数、変数

組み込みのマクロとしてdefn defmacがある。

特殊形式

def set! fn if quote backquote
  • quote、backquoteは'、```でも使える
  • backquote内部ではunquoteunquote-spliceを、それぞれ~~@で使える。

関数

+ - * / mod
= != > < >= <=
list cons first rest
fn->mac apply map

あ、evalandor忘れてた……

変数

nil true Math RegExp document

サンプル

mapの定義

(defn map [f xs] 
  (if xs 
      (cons (f (car xs)) (map f (cdr xs))) 
      nil))

クロージャなどの使用

> (defn adder [n] (fn [x] (+ x n)))
(fn [n] (fn [x] (+ x n)))
> (def inc (adder 1))
(fn [x] (+ x n))
> (map inc '(1 2 3))
(2 3 4)

今後挑戦してみたい

  • Lisp自身でREPL書く
  • ヘルプ/ドキュメント充実
  • immutable data structure
  • 引数の数によるディスパッチ

感想など

動機のとこに書いたように、今年の始めに作ってたんだけど、本やサイトを参照しつつヒイヒイ言いながら作って、自分の頭で理解できたのか不安だった。が、案外イメージで覚えていて、結局何も見ずに作ることができた。良かった。

最近、特に燃え尽きプログラマと動的開発について - 標高+1mSmalltalkの人たちが書いた文書に影響されて、動的な環境とか非ファイルベース、非テキストベースのプログラミングへの強い志向が生まれている。

「いつかそういう環境を作れたらな」と思っていたけど、仕事が予想以上に忙しくなり、かつ普通に体力勝負していたのでは到底掴め無さそうなチャンスが転がっているのを目の当たりにして、とにかく情熱に突き動かされるまま書いてみることにした。

その環境の一番根っこの部分に何を持ってくるかでいろいろ選択肢があるわけだけど、今回は全てが式、のLispを書いてみた。ここからしばらく手入れモードに移行して、次は全てがオブジェクト、な環境も書き始めたい。

広告を非表示にする