sibilant
ちょっと癖のあるnode.js上のlisp->jsトランスレータ
http://sibilantjs.info/#welcome
combinationsとか作ってみた。
(puts '(1 2 3 4)) (puts (append-map '(1 2 3 4) (lambda (x) (list x (* x x))))) (puts (combinations (list 1 2 3 4) 2))
result
sibilant -x combinations.sbl [ 1, 2, 3, 4 ] [ 1, 1, 2, 4, 3, 9, 4, 16 ] [ [ 1, 2 ] , [ 1, 3 ] , [ 1, 4 ] , [ 2, 1 ] , [ 2, 3 ] , [ 2, 4 ] , [ 3, 1 ] , [ 3, 2 ] , [ 3, 4 ] , [ 4, 1 ] , [ 4, 2 ] , [ 4, 3 ] ]
original
以下のコードを渡してjsのコードを生成している。
(defmacro import (module) (concat "var " module " = " "require" "(\"" module "\");")) (import sys) ;;; (defun erase (xs e) (select xs (lambda (x) (!= x e)))) (defun append-map (xs fn) (defvar r []) (each (x) (map xs fn) (setf r (r.concat x))) r) (defun combinations (xs n) (if (= n 1) (map xs (lambda (x) (list x))) (append-map xs (lambda (x) (map (combinations (erase xs x) (- n 1)) (lambda (y) (cons x y))))))) (defun puts (obj) (sys.puts (sys.inspect obj))) ;;; (puts '(1 2 3 4)) (puts (append-map '(1 2 3 4) (lambda (x) (list x (* x x))))) (puts (combinations (list 1 2 3 4) 2))
js
var sys = require("sys"); // var erase = (function(xs, e) { // xs:required e:required return select(xs, (function(x) { // x:required return (x !== e); })); }); var appendMap = (function(xs, fn) { // xs:required fn:required var r = [ ];; map(xs, fn).forEach((function(x) { // x:required return r = r.concat(x);; })); return r; }); var combinations = (function(xs, n) { // xs:required n:required return (function() { if ((n === 1)) { return map(xs, (function(x) { // x:required return [ x ]; })); } else { return appendMap(xs, (function(x) { // x:required return map(combinations(erase(xs, x), (n - 1)), (function(y) { // y:required return [ x ].concat(y); })); })); }; })(); }); var puts = (function(obj) { // obj:required return sys.puts(sys.inspect(obj)); }); // puts([ 1, 2, 3, 4 ]); puts(appendMap([ 1, 2, 3, 4 ], (function(x) { // x:required return [ x, (x * x) ]; }))); puts(combinations([ 1, 2, 3, 4 ], 2));