{"action":"created","issue":{"url":"https://api.github.com/repos/tca/veneer/issues/10","labels_url":"https://api.github.com/repos/tca/veneer/issues/10/labels{/name}","comments_url":"https://api.github.com/repos/tca/veneer/issues/10/comments","events_url":"https://api.github.com/repos/tca/veneer/issues/10/events","html_url":"https://github.com/tca/veneer/pull/10","id":90604827,"number":10,"title":"quick hack init as node package","user":{"login":"bewest","id":394179,"avatar_url":"https://avatars.githubusercontent.com/u/394179?v=3","gravatar_id":"","url":"https://api.github.com/users/bewest","html_url":"https://github.com/bewest","followers_url":"https://api.github.com/users/bewest/followers","following_url":"https://api.github.com/users/bewest/following{/other_user}","gists_url":"https://api.github.com/users/bewest/gists{/gist_id}","starred_url":"https://api.github.com/users/bewest/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bewest/subscriptions","organizations_url":"https://api.github.com/users/bewest/orgs","repos_url":"https://api.github.com/users/bewest/repos","events_url":"https://api.github.com/users/bewest/events{/privacy}","received_events_url":"https://api.github.com/users/bewest/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":1,"created_at":"2015-06-24T08:18:06Z","updated_at":"2015-06-24T08:52:46Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/tca/veneer/pulls/10","html_url":"https://github.com/tca/veneer/pull/10","diff_url":"https://github.com/tca/veneer/pull/10.diff","patch_url":"https://github.com/tca/veneer/pull/10.patch"},"body":"* name unamed functions to provide readable tracebacks in errors\r\n* expose parse_program to get at AST\r\n* stub out quick hack with help on IRC from @tca:\r\n  * https://gist.github.com/tca/71745cff5783211deb1d\r\n\r\n* [ ] expose scriptable interface\r\n* [ ] expose repl\r\n* [ ] provide way to describe how to iterate through results stream\r\n"},"comment":{"url":"https://api.github.com/repos/tca/veneer/issues/comments/114792150","html_url":"https://github.com/tca/veneer/pull/10#issuecomment-114792150","issue_url":"https://api.github.com/repos/tca/veneer/issues/10","id":114792150,"user":{"login":"bewest","id":394179,"avatar_url":"https://avatars.githubusercontent.com/u/394179?v=3","gravatar_id":"","url":"https://api.github.com/users/bewest","html_url":"https://github.com/bewest","followers_url":"https://api.github.com/users/bewest/followers","following_url":"https://api.github.com/users/bewest/following{/other_user}","gists_url":"https://api.github.com/users/bewest/gists{/gist_id}","starred_url":"https://api.github.com/users/bewest/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bewest/subscriptions","organizations_url":"https://api.github.com/users/bewest/orgs","repos_url":"https://api.github.com/users/bewest/repos","events_url":"https://api.github.com/users/bewest/events{/privacy}","received_events_url":"https://api.github.com/users/bewest/received_events","type":"User","site_admin":false},"created_at":"2015-06-24T08:52:46Z","updated_at":"2015-06-24T08:52:46Z","body":"There are some nice things done in yours in terms of keeping AST very very pure, as well as the way the counter is passed around as memo internally.\r\n\r\nThere is also a nice approach over here https://github.com/cduret/mk.js/blob/master/minikanren.js#L438-L448 where javascript's prototype based inheritance might allow monkey-patching with tries or things to speed up `walk` and `lookup`.\r\n\r\nIn the meantime, the node ecosystem has a neat concept of [streams](https://github.com/dominictarr/event-stream) that might overlap nicely with browserify/web-pack and the way parsing works.  I've compared the output of three different parsers here:\r\n\r\n\r\n#### input\r\n```javascript\r\nconsole.log('myString', myString);\r\n// var val = vm.read_eval(\"(== a 2)\");\r\nvar sexpr = require('sexpression');\r\nvar exprs = require('s-expression');\r\ntry {\r\n  console.log('s-expression', JSON.stringify(exprs(myString)));\r\n  console.log('SEXPR', JSON.stringify(sexpr.parse(myString)));\r\n  console.log('SEXPR re-stringified', sexpr.stringify(sexpr.parse(myString)));\r\n  console.log('parsed 1', JSON.stringify(vm.parse_program(myString)));\r\n  console.log('re-stringified', pretty_print(vm.parse_program(myString)));\r\n  var val = vm.read_eval(myString);\r\n  for (var x = 0 ; x < 5 ; x++) { // 5 results for fun\r\n  var out = procedurep(val) ? val() : pretty_print(val);\r\n  console.log(out);\r\n  }\r\n} catch (e) {\r\n  console.error(e, val, myString);\r\n}\r\n```\r\n\r\n##### outputs\r\n\r\n```bash\r\n\r\nbewest@hither:~/src/veneer$ cat reader.js eval.js base.js  mk.js rep.js |  tee foo.js | node\r\nmyString \r\n\r\n(define (appendo x y z)\r\n (conde\r\n  ((== x '()) (== y z))\r\n  ((fresh (head xtail ytail ztail)\r\n    (== x `(,head . ,xtail))\r\n    (== z `(,head . ,ztail))\r\n    (appendo xtail y ztail)))))\r\n\r\n\r\n\r\n\r\ns-expression [\"define\",[\"appendo\",\"x\",\"y\",\"z\"],[\"conde\",[[\"==\",\"x\",[\"quote\",[]]],[\"==\",\"y\",\"z\"]],[[\"fresh\",[\"head\",\"xtail\",\"ytail\",\"ztail\"],[\"==\",\"x\",[\"quasiquote\",[[\"unquote\",\"head\"],\".\",[\"unquote\",\"xtail\"]]]],[\"==\",\"z\",[\"quasiquote\",[[\"unquote\",\"head\"],\".\",[\"unquote\",\"ztail\"]]]],[\"appendo\",\"xtail\",\"y\",\"ztail\"]]]]]\r\nSEXPR [{\"name\":\"define\"},[{\"name\":\"appendo\"},{\"name\":\"x\"},{\"name\":\"y\"},{\"name\":\"z\"}],[{\"name\":\"conde\"},[[{\"name\":\"==\"},{\"name\":\"x\"},null],[{\"name\":\"==\"},{\"name\":\"y\"},{\"name\":\"z\"}]],[[{\"name\":\"fresh\"},[{\"name\":\"head\"},{\"name\":\"xtail\"},{\"name\":\"ytail\"},{\"name\":\"ztail\"}],[{\"name\":\"==\"},{\"name\":\"x\"},{\"car\":{\"name\":\",head\"},\"cdr\":{\"name\":\",xtail\"}}],[{\"name\":\"==\"},{\"name\":\"z\"},{\"car\":{\"name\":\",head\"},\"cdr\":{\"name\":\",ztail\"}}],[{\"name\":\"appendo\"},{\"name\":\"xtail\"},{\"name\":\"y\"},{\"name\":\"ztail\"}]]]]]\r\nSEXPR re-stringified (define (appendo x y z) (conde ((== x nil) (== y z)) ((fresh (head xtail ytail ztail) (== x (\\,head . \\,xtail)) (== z (\\,head . \\,ztail)) (appendo xtail y ztail)))))\r\nparsed 1 {\"car\":{\"car\":{\"string\":\"define\"},\"cdr\":{\"car\":{\"car\":{\"string\":\"appendo\"},\"cdr\":{\"car\":{\"string\":\"x\"},\"cdr\":{\"car\":{\"string\":\"y\"},\"cdr\":{\"car\":{\"string\":\"z\"},\"cdr\":null}}}},\"cdr\":{\"car\":{\"car\":{\"string\":\"conde\"},\"cdr\":{\"car\":{\"car\":{\"car\":{\"string\":\"==\"},\"cdr\":{\"car\":{\"string\":\"x\"},\"cdr\":{\"car\":{\"car\":{\"string\":\"quote\"},\"cdr\":{\"car\":null,\"cdr\":null}},\"cdr\":null}}},\"cdr\":{\"car\":{\"car\":{\"string\":\"==\"},\"cdr\":{\"car\":{\"string\":\"y\"},\"cdr\":{\"car\":{\"string\":\"z\"},\"cdr\":null}}},\"cdr\":null}},\"cdr\":{\"car\":{\"car\":{\"car\":{\"string\":\"fresh\"},\"cdr\":{\"car\":{\"car\":{\"string\":\"head\"},\"cdr\":{\"car\":{\"string\":\"xtail\"},\"cdr\":{\"car\":{\"string\":\"ytail\"},\"cdr\":{\"car\":{\"string\":\"ztail\"},\"cdr\":null}}}},\"cdr\":{\"car\":{\"car\":{\"string\":\"==\"},\"cdr\":{\"car\":{\"string\":\"x\"},\"cdr\":{\"car\":{\"car\":{\"string\":\"quasiquote\"},\"cdr\":{\"car\":{\"car\":{\"car\":{\"string\":\"unquote\"},\"cdr\":{\"car\":{\"string\":\"head\"},\"cdr\":null}},\"cdr\":{\"car\":{\"string\":\"unquote\"},\"cdr\":{\"car\":{\"string\":\"xtail\"},\"cdr\":null}}},\"cdr\":null}},\"cdr\":null}}},\"cdr\":{\"car\":{\"car\":{\"string\":\"==\"},\"cdr\":{\"car\":{\"string\":\"z\"},\"cdr\":{\"car\":{\"car\":{\"string\":\"quasiquote\"},\"cdr\":{\"car\":{\"car\":{\"car\":{\"string\":\"unquote\"},\"cdr\":{\"car\":{\"string\":\"head\"},\"cdr\":null}},\"cdr\":{\"car\":{\"string\":\"unquote\"},\"cdr\":{\"car\":{\"string\":\"ztail\"},\"cdr\":null}}},\"cdr\":null}},\"cdr\":null}}},\"cdr\":{\"car\":{\"car\":{\"string\":\"appendo\"},\"cdr\":{\"car\":{\"string\":\"xtail\"},\"cdr\":{\"car\":{\"string\":\"y\"},\"cdr\":{\"car\":{\"string\":\"ztail\"},\"cdr\":null}}}},\"cdr\":null}}}}},\"cdr\":null},\"cdr\":null}}},\"cdr\":null}}},\"cdr\":null}\r\nre-stringified ((define (appendo x y z) (conde ((== x (quote ())) (== y z)) ((fresh (head xtail ytail ztail) (== x (quasiquote ((unquote head) unquote xtail))) (== z (quasiquote ((unquote head) unquote ztail))) (appendo xtail y ztail))))))\r\n#t\r\n#t\r\n#t\r\n#t\r\n#t\r\nbewest@hither:~/src/veneer$\r\n\r\n```\r\n\r\nSo here we have three libraries, `s-expression`, `sexpression`, and yours to contrast.  I found this really educational and interesting.\r\n\r\nIf you're interested in pointing me along the way, I think think it'd be interesting to make this idiomatic to node.js such that it can be browserified and run in the the browser and on the commandline.  Not much has to be done for browserify to support node scripts, other than using the node `require` idiom namespacing everywhere.  So long as this is done in an obvious, trivial manner, at the top everything seems to work out well.\r\n\r\nThanks for the pointers, dunno if this will go any where, just random notes from day of hacking and pointers in IRC."}}