8 ms·
Compiling Lisp to JavaScript in 350 Lines of Haskell
- brian_herman 8y agoWow this guy got scratch the programming language to compile Lisp in JS that’s impressive
- mtreis86 8y agoNo, it's written in Haskell
- cjhanks 8y agoParent wrote before elthe title was changed, not fair to down vote.
- quickthrower2 8y agoBut was the article changed?
- qbrass 8y agoIt was being downvoted before the title changed.
- userbinator 8y agoThat's something I'd actually like to see.
- jahewson 8y ago350 lines of Haskell.
- rurban 8y agohttps://common-lisp.net/project/parenscript/ https://common-lisp.net/project/parenscript/ has 350 lines of Common Lisp.
- dang 8y agoWe've added Haskell to the title above.
- joshumax 8y agoThe original title was "Compiling lisp to JavaScript in 350 lines from Scratch" -- For anyone actually interested in a lisp interpreter written in Scratch, there's https://scratch.mit.edu/projects/159487877/ https://scratch.mit.edu/projects/159487877/
- dan-robertson 8y agoConverting “lisp” to JavaScript in the sense of this article is basically trivial (but then it was done in only 350 lines of Haskell). Compiling, say, Common Lisp to JavaScript is hard. There are “easy” steps (in the sense that they can be ignored or done a stupid way at first) like dealing with numbers, namespaces, packages, (I.e. the symbol foo can name a function and a variable, amongst other things, and the symbols #:foo and #:foo are not equal). There are the “boring” steps like doing argument parsing (and harder is working out how to make it efficient) There are the hard steps like working out how to compile lexical goto and return-from, eval-when There are the very hard steps necessary for macros like having to reimplement a macroexpander (for macrolet and friends) and then realising that this is insufficient as one also needs to implement environment and such (but this can be done by a macro to slightly modify macros, assuming that this compiler is also implemented in Common Lisp). But this still is insufficient. Consider the following legal Common Lisp: (defun make-adder (number) (lambda (x) (+ x number)) (defmacro macro-+ (a b) `(funcall ,(make-adder a) ,b)) (defun foo (y) (macro-+ 3 y)) So the body of foo expands into: (funcall #<lambda ...> y) And one has no way to compile this host-system function to JavaScript and hence to expand macros one needs to be able to interpret Common Lisp and be able to convert any object into JavaScript source code (and keep in mind that the source code needs to ensure that what we’re identical in the CL are identical when the JS is compiled, and that closed-over variables are also properly dealt with in the sense that if two different functions close over the same variable in CL then they need to be compiled into JS functions that close over the same variable, or at least behave the same as the CL functions. Having to interpret does at least solve problems like having numbers behave the same way in macros as at runtime. And then there is CLOS which is a bit of a pain to bootstrap (and must be bootstrapped twice of course). To compile CL to JS one essentially needs three CL compiler (backends), one for macros in the first compile, one for compiling to JS and one for compiling and linking in the code that is compiled at runtime in the JS VM.
- shawn 8y agoThat's why it's not worth compiling CL to JS. https://github.com/sctb/lumen https://github.com/sctb/lumen Most of the cases you mention have straightforward answers. EVAL-WHEN :compile is WHEN-COMPILING, for example: (define-macro when-compiling body (eval `(do ,@body))) By the way, I lost my vouching privileges for reporting the fact that I could vouch my own comments. I never did, except once – to file the report.
- agumonkey 8y agonext reading: common lisp to pascal using a pretty printer https://www.reddit.com/r/lisp/comments/1totwx/some_useful_lisp_algorithms_part_2_pretty/ https://www.reddit.com/r/lisp/comments/1totwx/some_useful_li...
- tsuberim 8y agoCool stuff. I wrote a simple Hindley-Milner type language interpreter in Haskell inspired by Haskell a while back. Consider using Parsec as a parser combinator library.