[LSP42] FalconとEuphoria

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

FalconEuphoriaでLISPを作りました。
https://github.com/zick/FalconLisp
https://github.com/zick/EuphoriaLisp

動機

今年の春、訳あって42個のプログラミング言語でLISP処理系を実装することになりました。これはその14〜15個目です。
FalconとEuphoriaという言語は、Wikipediaを眺めているときに見つけ、簡単そうだったので選びました。今回の企画でLISPを作った言語は10を超え、過去にLISPを作った言語も合わせると既に20を超えており、正直、使う言語を探すほうがLISPを作るのよりも疲れるようになってきました。

Falconの思い出

久々のbegin/end系の言語です。相変わらず好きになれません。でもFalconには1行で書く場合に end を省略できるという素敵な文法があるのでいい感じです。例によってテーブル(Falconの言葉だとdictionary?)でLISPのデータ構造を表現しようとしたのですが、テーブルを比較すると、内容比較になってしまいます。これでは eq を作ることが出来ません。色々と試行錯誤したところ、一度クラスで包んでやればアドレス比較になるようなので、その方法で逃げました。

class L(tag, dict)
  tag_ = tag
  dict_ = dict
  function __getIndex(index)  // 演算子オーバーロードだよ、お兄ちゃん!
    return self.dict_[index]
  end
  function __setIndex(index, value)  // これもだよ!
    self.dict_[index] = value
  end
  function tag()
    return self.tag_
  end
end

function makeCons(a, d): return L('cons', ['car' => a, 'cdr' => d])

function safeCar(obj)
  if obj.tag() == 'cons': return obj['car']
  return kNil
end

努力の方向が間違っているような気もしますが気のせいです。全部クラスで作れという苦情は受け付けておりません。

Euphoriaの思い出

好きになれないとはいえ、endと書くことはある程度慣れてきました。しかし、そんな私の気持ちを打ち砕いたのがこのEuphoria。

function safeCar(object obj)
  if TagEq(obj, "cons") then
    return Car(obj)
  end if
  return kNil
end function

なんですか、この end function というやつは。関数を書くたびに function と2回もタイプするとか正気の沙汰とは思えません。そんな時間があったらどれだけの括弧が書けると思っているんですか。
お察しの通り、またテーブル(Euphoriaの言葉だとmap)でLISPのデータ構造を表現したんですが、mapの操作も冗長だったので、取り敢えず wrapper を書いて逃げました。

function L(sequence tag, object data)
  map obj = new()
  put(obj, "tag", tag)
  put(obj, "data", data)
  return obj
end function

function Tag(object obj)
  return get(obj, "tag")
end function

function TagEq(object obj, sequence str)
  return equal(Tag(obj), str)
end function

function makeCons(object a, object d)
  return L("cons", {a, d})
end function

努力の方向性(冗長性の除去のため以下略)。
あと、一部のオブジェクトは copy-on-write みたいなので注意が必要です。

function SetCar(object obj, object val)
  object data = Data(obj)
  data[1] = val
  put(obj, "data", data)
  return val
end function

うーん、冗長。マニュアルをしっかり読んだわけではないのでなにが copy-on-write なのかはよく分かりません。

小学生並みの感想

タイプ数が少なくてすむ言語は正義だと思いました。

Leave a Reply