トップ 最新 追記

Route 477



2012-12-05

[lisp][javascript] JavaScriptにコンパイルされるCommonLisp風言語、JSLispが面白そう

Lisp Advent Calendar 2012 5日目の記事です。

JavaScript Weeklyから来たメールを眺めていたら、こんなJSデモを見つけた。

作者は https://github.com/6502 の人らしい。見てみると、「JSLisp」というリポジトリが。 またyet anotherなLisp in JSかと思ったが、READMEを見ているとけっこう面白そうな記述が:

  • Lisp風言語からJavaScriptにコンパイルする
  • CLライクなlisp-2 (ていうか、マクロと関数を同名にできるから厳密にはlisp-3だよと書いてある)
  • ネイティブ型はJSの型を使う、listはarray (car/cdrはない)
  • defmacro, back quote
  • optional引数、keyword引数
  • defmethod, defobject

githubのNetworkを見ると、去年の夏からやっていることが分かる。

http://www.jslisp.org/ が公式サイトのようだ。permalinkがない :-( ので個別にリンクが貼れないが、以下のように凝った機能がいろいろあるみたいだ。

  • Example : ルービックキューブとかチェスとか六角マップ上の最短距離探索とかあって格好いい
  • Reader : リーダマクロがあるらしい
  • Static checks : 使われていない変数などのコンパイル時検査
  • Generic funcitons : 関数の挙動を条件別に定義できる
  • Treeshaker : 使われていない(=main関数から辿れない)関数を除去してコンパイルする

まだあまりドキュメントが無く、残念ながらgit masterのコードは手元でうまく動かせなかったが、なかなか気になる処理系だ。


2012-12-06

[rumcoke] RumCokeという言語を作っています

altjs Advent Calendar 6日目の記事です。

「altjs」とは、JavaScriptにコンパイルされる or JavaScriptで実装された言語(処理系)のこと。 僕自身もBiwaSchemeというaltjs処理系を作っていますが、 秋のILC参加中に「もしCoffeeScriptがS式ベースだったら...?」というアイデアを思いついて、RumCokeというLisp風のaltjs言語を作り始めました。

Hello Worldです。

(define util (require "util"))(util.puts "Hello, world!")

あと、処理系自身がRumCokeで書かれているので、いまのところそれが一番大きな例です。 このプログラムが、このように変換されます。

RumCokeの特徴

  • JSの薄いラッパー言語である

CoffeeScriptやTypeScriptのように、なるべくJSに近いsemanticsを意識しています。

  • Scheme風の構文

JSはLisp-1なんで、Schemeが合うかなと思いました。

  • Lispだけどリストがない

S式がArrayベースだったらどうなるんだろう?という実験のつもりでしたが、昨日のJSLispがもうやってましたね…。

  • 構文木レベルのマクロ

SibilantJSのように文字列レベルのマクロだったり、 LispyScriptのように任意のコードが書けないものと違って、 ちゃんと「構文木を構文木に変換するもの」としてマクロが書けます。*1

  • self-hosting

GHCやCoffeeScriptのように、その言語自身で自分の処理系を書くというのをやってみたかったのでした。 手順としては、

  1. まず素のJSで処理系を書く (このとき、なるべく使用するJSの構文要素を減らすことが望ましい)
  2. 簡単なRumCokeプログラムをJSに変換できるようにする
  3. 現在の処理系の1行目を生成するようなRumCokeプログラムを書く
  4. それをJSに変換できるように処理系を拡張する
  5. 現在の処理系の2行目を生成するようなRumCokeプログラムを書く
  6. それをJSに変換できるように処理系を拡張する
  7. ...
  8. 現在の処理系の最後の行を生成するようなRumCokeプログラムを書く
  9. それをJSに変換できるように処理系を拡張する
  10. さあ、手元には現在の処理系を生成するようなRumCokeプログラムがあるぞ。それを現在の処理系でJSに変換するぞ。
  11. 生成されたJSは、現在の処理系と全く同じであるはずだ。おめでとう、君はself-hostingに成功した。
  12. 古い処理系はもう要らないので捨てる。ここからは、RumCoke版の処理系だけをメンテすればいい。

という感じになります。Quineみたいでややこしいけど非常に面白かった。 以降は、処理系に新しい機能を追加する→その機能を使って処理系をリファクタリングする、みたいなループになります。

実装状況

quasiquoteを足そうとしたところで止まっています。そのうち暇を見つけて再開する予定です。

JS言語の作成に関してはいろいろ新たなノウハウを得たので、今月中にまた何か書くかもしれません。

*1 と言って、define-macroを用意してないのでユーザレベルではまだ書けないですが


2012-12-09

[esolang] 今年見つけたEsoteric Language関係の記事

Esolang Advent Calendar 2012 9日目の記事です。

昨年同様、今年ブクマしたesolang関係の記事を見返してみようと思います。

以下はesolangs.orgから。(ざっと眺めただけなので、インパクト重視です…)

  • BlackCoffin.gif gif画像でプログラミング。Coffinは「棺」で、命令がグレースケール…。喪中ですね。それ以外のピクセルは無視されるため、絵の主線部分にプログラムを埋め込むといった使い方も。
  • Ellipsis 「…」の一文字だけで構成されるプログラミング言語。実際にはファイル中に書かれている「…」の個数Nを8進数にして各桁をBrainf**kの文字に変換するため、文字が「…」である必然性は特にない。
  • F**k (github) これはひどいw
  • huh? これも別の方向でひどい
  • Light Pattern 写真の列を入力とする言語。シャッタースピード、絞り、色味(RGB)の差分で命令が決まり、写真の内容は自由。デモを見るとなかなかサイケデリックで面白い

次点。

  • Mobius 出力が音声(500/600/700Hzのbeep)。
  • Monkeys 猿を操ってプログラミングするらしい。
  • Objective LOLCODE I can haz cheezburger的な。
  • Semicolon (github) Whitespaceベースですが、reversed semicolonという文字があることに驚いた。
  • UniCode Unicodeの矢印記号を使った言語。このアイデアは二次元言語にした方向が面白そう

2012-12-10

[ruby][mac] MacRubyでアプリ作ってみた

ニコニコのコメントファイルを表示するだけのアプリを作った。

Retina MBP (13inch) に乗り換えてから、にこぷれの動画再生がカクカクすることがあって困っている。 仕方ないのでflvはVLCで再生して、コメントは別の方法で読むことにしたというわけ。

コメントは単純なXMLなので、Nokogiriで適当にパースすればテキストに変換できる。

# coding: utf-8
require 'nokogiri'

xml = Nokogiri::XML(ARGF.read)

start_time = if (thread = xml.at("thread"))
               Time.at(thread[:server_time].to_i)
             else
               first_chat = xml.at("chat")
               raise "chat not found" unless first_chat
               Time.at(first_chat[:date].to_i)
             end

xml.search("chat").each do |chat|
  bsp = false
  number = chat[:no]
  date = Time.at(chat[:date].to_i)
  time = date - start_time
  min = time / 60
  sec = time % 60

  text = chat.text
  if text =~ %r{\A/press show .* (.*?) @ (.*)}
    bsp = true
    text = "<#{$2}> #{$1}"
  end

  printf "%02d:%02d %s%s\n", min, sec, (bsp ? "" : " "), text
end

これをlvで見るのでもいいのだが、なんとなく単独のウィンドウで表示したくなって、MacRubyを使ってみることにした。

MacRubyについては、以下を上から順にやればだいたい雰囲気がわかる。

ファイルの読み込みAPIなどはRubyがそのまま使えるため、そんなに新しいことを覚えなくていいのがありがたい。 Nokogiriなどgemも使えるようだが、XCode上で使ってみたらなぜかNokogiri::XML("")がCレベルのエラーになったので、とりあえず正規表現に逃げてしまった。

今までだったらSinatra+ブラウザとかで実装してたと思うけど、ものによってはMacRuby使ったほうが簡単そう。

[javascript] Ember.jsで遊んでみた

Ember.jsはいわゆるJavaScript MVCフレームワークの一つ。 Ember.jsはその中でもわりとヘビーウェイト・高機能なやつで、モデル間やモデル・ビュー間でデータの依存関係を指定して、片方が変化したら従属する方に勝手に変更が反映されるような機構が備わっている。

という話を聞いて最初に思いついたのが、太陽・地球・月が回転するというデモ。月の位置は地球の位置に依存していて、地球が動いたら月も自動的に移動する、というやつ。 で出来たのがこちら。

img

リポジトリにはファイルがたくさんあるが、ほとんどはstarter kitに入っているもので、編集したのは app.jsindex.htmlだけ。

描画はRaphaelJSを使っている。こういう小さいものを作る時にとても便利なライブラリだ。

ページのホスティングはgithub pagesを使っている。 今回のようにgithub pagesがメインのときは、「git push origin master」せずに「git push origin gh-pages」だけすることで、gh-pagesブランチのみにすると分かりやすくていい。

Ember.jsについては、Ember.js Advent Calendar 2012がとても参考になる。


2012-12-11

[ruby] bundle execが「--verbose」オプションを食ってしまう

Bundlerを1.1.4から1.2.3に上げたら、

$ bundle exec ruby a.rb --verbose

としたときに--verboseがa.rbに渡らなくなってしまった。

とりあえず

$ bundle exec "ruby a.rb --verbose"

とクオートでくくるようにして対処。