Arantium Maestum

プログラミング、囲碁、読書の話題

2020-05-01から1ヶ月間の記事一覧

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その13 マクロ

簡単なマクロ機構を実装していく。 背景 shift/resetが実装されたらやってみたいことの一つが@dico_lequeさんの発表「モナドをつくろう」をいろいろ試してみること。 モナドをつくろう from dico_leque www.slideshare.net スライド19に出てくるreifyがマ…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その12 文字列、入出力とDo

今まで作ってきた言語には副作用がなかったが、やはり入出力くらいはほしいよね、というわけで 式と値に文字列を追加 標準入出力からの読み取り・書き込みのための組み込み関数 副作用のある処理を順次実行して、最後の式の値をとるDo式 を言語に追加する。 …

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その11 Cond&リファクタリング

今回の変更は三点: condによる条件分岐 Val.FnとVal.RecFnを統一 式の中の自由変数を検出するget_freeをリファクタ 前回とのコード差分: Comparing v0.10...v0.11 · zehnpaard/kontlang · GitHub condによる条件分岐 すでにifによる条件分岐は実装してある…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その10 Consとリスト

今回は言語で簡単なデータ構造を扱えるようにする。具体的にはイミュータブルなconsセル(とnil値)を導入して、linked listを作れるようにする。 ついでにLisperならお馴染みのcar、cdrやリストを便利に作れる・使えるlist、applyなども定義する。 こんな感…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その9 微調整

今回は細かいところを調整しただけ。 前回との差分: Comparing v0.8...v0.9 · zehnpaard/kontlang · GitHub 調整ポイントは: レキシカル・スコープで関数作成時にクロージャに束縛する自由変数の重複を排除 Exp.Letsを評価する時、変数に束縛されるべき式…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その8 再帰

普通の関数が実装できたので、今度は再帰関数を定義できるようにする。 具体的にはこのような構文: (letrec [factorial [n] (if (= 1 n) 1 (* n (factorial (- n 1))))] (factorial 6)) あるいは: (letrec [(odd? [x] (if (= 0 x) false (even? (- x 1))))…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その7 関数(レキシカル・スコープ)

前回実装したダイナミック・スコープの関数は、実装は楽だが使うにはけっこうピーキーである。より一般的なレキシカル・スコープに直すとする。 関数の定義を評価して「関数の値」を作成する時に、関数内に出てくる自由変数を検出して、定義時の変数環境でそ…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その6 関数(ダイナミック・スコープ)

分岐や変数束縛が出来るようになったので、次は関数定義を追加したい。 機能としては: fnで無名関数を作成 letfnで関数を名前付きで作成(複数同時も可) 多引数に対応、引数の数が定義時と呼び出し時に合っていなかったらエラー 今回はダイナミック・スコ…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その5 変数とlet

前回でようやくifで分岐ができるようになった。今回はletを使って変数を定義できるようにする。 こんな感じの式が評価できるようになる: (let [x 5] (+ x 6)) (let [(x 5) (y 6)] (+ x y)) Clojureっぽく[]が構文に現れるようにしてみた。複数の変数を同時…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その4 真偽値

前回までは言語で扱える値は整数値と組み込み関数だけだった。比較とか分岐とかしたいよね、ということで今回は真偽値を追加して、ifで分岐できるようにする。 以下のようなコードが書けるようにする: (if (and (>= 3 1 1) (< 0 3) false (<= 1 2 3 3 5)) 1…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その3 トランポリン化

前回継続渡しスタイルで末尾再帰化したインタプリタにさらに手を加えてトランポリン化する話。 一般的に、トランポリン化は「末尾再帰のない言語でスタックオーバーフローを起こさずに深い再帰をシミュレートする」手法だと言える。再帰的な関数呼び出しを遅…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その2 継続渡しスタイル

前回に続いて、機能としては整数と四則演算だけのインタプリタの話。 今回は機能はそのままで、式を評価して値を返すeval関数を継続渡しスタイルに変換する。 そもそも継続渡しスタイルだと何が嬉しいのか。 インタプリタの実行手順を考えると、関数呼び出し…

めざそう言語処理系の沼 〜shift/resetへの旅 〜 その1 四則演算

shift/resetという限定継続を扱うための機構を備えた言語のインタプリタをOCamlで段階的に作っていく。長めのシリーズになりそう。 今回は整数と関連する演算が評価できるインタプリタを作成するまで。EoPLの最初の言語であるLETの二歩くらい手前。 例えば:…

OCamlとLwtでマルチクライアントなエコーサーバを実装してみる

OCamlで非同期的プログラミングをするための著名なライブラリが二つある。Jane StreetのAsyncと`Ocsigenプロジェクト発のLwtだ。 個別の機能のネーミングは多少違うが、概念的には非常に似通っているようで、協力的マルチタスクによる非同期プログラミングを…