[LSP42] CofeeScriptとTypeScriptとDart

(この記事はLISP Implementation Advent Calendar 8日目のためのエントリです。)

CoffeeScriptTypeScriptDartでLISPを作りました。
https://github.com/zick/CoffeeLisp
https://github.com/zick/TypeLisp
https://github.com/zick/DartLisp

どれもJavaScriptに変換可能でブラウザで実行できる言語です。ただし、Dartは独自のVMも持っています。

動機

今年の春、訳あって42個のプログラミング言語でLISP処理系を実装することになりました。これはその11〜13つ目です。
CoffeeScript、TypeScript、Dartという言語を選んだのはJavaScriptの派生(?)言語ということで非常に簡単そうだったからです。正直これらJavaScript系言語は簡単すぎるので敬遠していたのですが、42個中10個の言語で実装するだけで既に7週間程度を費やしていたため、これはもう少しスピードアップしようと思い、久しぶりに一日で3つの言語でLISPを実装しました。

CoffeeScriptの思い出


PythonとJavaScriptを混ぜたような感じです。インデントでブロックを表し、タイプ数が少なくてすむような文法です。例によってテーブル(JavaScript系の言語なので恐らくオブジェクト?)を使ってLISPのデータ構造を表しました。

makeCons = (a, d) ->
  { tag: 'cons', car: a, cdr: d }

TypeScriptの思い出

CoffeeScriptが独自の文法なのに対し、TypeScriptはJavaScriptのスーパーセットとなっています。名前が表す通り、変数や関数に型をつけることができます。型は optional なのですが、型をつけなければ完全にJavaScriptになってしまうため、頑張って型をつけました。

// tag は必須、後のデータはあってもなくてもいい
interface LObj {
  tag: string;
  str?: string;
  num?: number;
  car?: LObj;
  cdr?: LObj;
  fn?: (args: LObj) => LObj;
  args?: LObj;
  body?: LObj;
  env?: LObj;
}

function makeCons(a: LObj, d: LObj) {
  return { tag: 'cons', car: a, cdr: d };
}

ひたすらに色んな所に LObj と書くだけの簡単なお仕事でした。実質的に型付けの恩恵を受けれない上に、やたらとタイプ数が増えるだけの悲しい思いをしました。CoffeeScriptの後だったので、 function と書くだけでも面倒だったのに。あとコンパイル時間が長いのもいただけない。

Dartの思い出

DartはCoffeeScriptと同様に独自の文法を持っています。ブロックは中括弧{}で表し、セミコロンも必要なため、CoffeeScriptと比べるとタイプ数は多くなりますが、それでもイマドキの言語らしく、少ないタイプ数で色々できます。例によってテーブル(Dartの言葉だとmap)を使ってLISPのデータ構造を表現しました。

makeCons(a, d) => {
  'tag': 'cons',
  'car': a,
  'cdr': d
};

が、完成品を走らせてみるとCoffeeScriptとTypeScriptと比べびっくりするくらい遅い。ちょっと遅いというレベルではなく圧倒的に遅い。「なんでこんなに遅いの?」と疑問を書いたらDartの中の人から「クラスを使うんだ!」というメッセージとともにパッチが送られてきました。

class Cons {
  var car;
  var cdr;
  Cons(this.car, this.cdr);
}

makeCons(a, d) => new Cons(a, d);

こんどはDartが圧倒的に速いという結果に。でも中の人にアドバイスを貰ったのはちょっと反則気味な気も。

小学生並みの感想

みんなちがって、みんないい、わけでもない。

3 Responses to “[LSP42] CofeeScriptとTypeScriptとDart”

  1. […] CoffeeScriptで書いたLISPを、LiveScriptとして動かしてみたら、途中まで動いてエラーを吐いて止まりました。エラーメッセジを見て修正、というのを3回ほどしたら完全に動いてしまいました […]

  2. […] 対数グラフであることに注意してください。 トップはCoffeScriptの0.002秒。続いてOCamlの0.007秒。そして3位はなんとOberon-2の0.01秒です。 最下位はEの33.311秒、そしてCeylonの18.358秒、Scratchの6.2 […]

  3. […] Lisp in TypeScript. It is the pioneering TypeLisp [github.com] of 416 lines described in ” [LSP42] CofeeScriptとTypeScriptとDart ” (“[LSP42] CoffeeScript to TypeScript to Dart”, (Lisp in) CoffeeScript, […]

Leave a Reply