次の関数があるとしましょう
var action = (function () {
var a = 42;
var b = 2;
function action(c) {
return a + 4 * b + c;
}
return action;
}());
// how would you parse action into it's serialized LISP / AST format?
var parsed = parse(action);
action
関数への参照を取得し、LISP 形式を出力する関数を持つことは可能ですか?(lambda (c) (plus (plus 42 (multiply 4 2)) c))
できることにいくつかの制限を加えることが許可されていaction
ます。
- 本体は単一の式のみにする必要があります
- それは純粋な関数であるべきです
- 任意の自由変数は定数です
主な質問は、さまざまな入力で呼び出すことができる関数が与えられ、そのソース コードで、自由変数を置き換える正しい値を見つけることができますか?
上記の例では、a と b が定数であることがわかっているため、いくつかの値の出力を知的にプロットしてパターンを確認し、定数が何であるかを知ることができます。
質問:
関数参照とそのソース コードを受け取り、実行時の値を自由変数に置き換えて、関数の何らかの形式の AST を生成する関数をどのように記述しますか。
AST フォーマットの例は、コードに相当する LISP です。
基本的に、関数をシリアル化および逆シリアル化し、同じように動作させたい
{ a: a, b: b }
分析関数に渡すと、問題は自明になることに注意してください。それは不正行為になります。
使用事例:
ライブラリのユーザーがこの関数を作成するために DSL を使用する必要なく、効果的に C++ に渡すことができるように、純粋な JavaScript 関数の言語に依存しない形式を生成したい
データベースドライバーがあったとしましょう
var cursor = db.table("my-table").map(function (row) {
return ["foo", row.foo]
})
実行時に関数が何であるかを判断し、それを AST 形式に変換して、効率的なクエリ ビルダーを使用して SQL またはデータベースにあるクエリ エンジンに変換できるようにする必要があります。
つまり、次のように記述する必要はありません。
var cursor = db.table("my-table").map(function (rowQueryObject) {
return db.createArray(db.StringConstant("foo"), rowQueryObject.getProperty("foo"))
})
これは、DB ライブラリがクエリ オブジェクトを使用して実行できる関数であり、詳細なメソッドを使用せずにクエリ オブジェクトの変換を構築できます。