7 ms·
LispyScript: A JavaScript With Lispy Syntax And Macros
- jhrobert 14y agoAdd "SweetExpressions" and I wonder how far from coffeescript it would get. "SweetExpressions" is probably the best method so far to get rid of excessive parentheses in lisp. See http://readable.sourceforge.net/ http://readable.sourceforge.net/
- timcameronryan 14y agoI experimented with a CoffeeScript-like Lisp in JavaScript once. It's pretty opinionated, but provides interesting syntax possibilities (infix notation, non-significant parentheses and commas for clarity, JSON-compatible syntax): https://github.com/tcr/syrup https://github.com/tcr/syrup range = fn: [i] loop: [i, r = []] if: (i == 0) r continue: (i - 1), concat: (i - 1), r print: range: 5 # [0, 1, 2, 3, 4]
- lowboy 14y agoI was just coming here to wonder at the need for those chubby little lines with their quadruple chins. Seems like if you have blocks of regular indention you should be able to trim some of the fat. I'm not a lisp guy though, so I'm sure that sentiment is naive.
- Homunculiheaded 14y agoAs someone who has done a fair bit of lisp hacking I'll never really understand the paren-hate. Yes it's weird the first few times but I have never met anyone who has coded a significant amount of lisp who sees them as anything but an asset. In lisp you're essentially hacking at the AST level, this is precisely where a huge chunk of lisp's power comes from, and parens are an incredibly natural and concise way to express this structure. I have also written a lot of Python and I can honestly say significant white space as been an issue for me far more often than parens in Lisp (and I don't find significant white space to be an issue at all).
- wes-exp 14y agoI've coded a significant amount of lisp, and I agree the parentheses are completely an asset.
- rtfeldman 14y agoSadly, the vast majority of coders never make it to "a significant amount of Lisp". Most who do tend to be very positive about Lisp, so it's not that the language veterans give it a bad word-of-mouth reputation. Quite the opposite. There is clearly an "approachability problem" to Lisp, and it seems worth trying to solve. (If nothing else, the more popular a language gets, the more opportunities you will have to get paid to write in it for a living.) Parens come up every single time the word Lisp is mentioned in "mixed company"--that is, both Lispers and non-Lispers. It's not just the most common complaint about the language, but the dominant complaint. (Thought experiment: What's the #2 complaint newbies make about Lisp? And how much longer did it take you to answer that question than #1?) Originally John McCarthy had intended to use M-Expressions for Lisp, e.g. "car[cons[(A . B); x]]", but programmers preferred the parens-and-whitespace of S-Expressions instead, so they became the default. There's no reason to dismiss the possibility of another such evolution, again based on nothing more than programmer preference. No matter how familiar or useful you might find the existing approach, it's always possible that it can be improved.
- ScottBurson 14y agoThere have been many attempts to solve the approachability problem by creating alternate syntaxes. Vaughan Pratt's CGOL, written almost 40 years ago, was perhaps one of the best. Although these alternate syntaxes may be helpful to newcomers, they have never caught on. Expert users actually prefer the parenthesized form; so anyone working in Lisp for very long has to learn to deal with it -- and usually, once they do, they find it preferable. You said it yourself: programmers preferred S-expressions, so they became the default. The other important point here is that the non-Lispers are right, in a sense: editing Lisp without a paren-counting editor is just as tedious as one would expect. But with a paren-counting editor -- and even better, with something like Paredit that keeps the parens balanced at all times -- editing actually becomes easier, more fluid, and more pleasant than in other languages. That is why expert Lisp users prefer the parens.
- sedachv 14y agoIf you're looking at parentheses instead of using indentation effectively and looking at the first thing in the list you haven't learned how to read Lisp code yet. People look at Lisp and think that because of the parentheses they don't have to bother thinking about the typographic layout of the code like they do in C, so their code ends up with shitty formatting and they think it's because of the parentheses, when in reality it is because they didn't bother formatting it. Getting rid of parentheses means you cannot use structured editing tools like Paredit anymore (http://emacswiki.org/emacs/ParEdit http://emacswiki.org/emacs/ParEdit). You can't appreciate how slow and clumsy it is to edit code in other languages until you've been using Paredit for a while. One sometimes valid argument against prefix notation is for expressions primarily involving binary math operations (+ * - / etc.). In some cases it's true, in other cases the Lisp code looks gnarly because people try to write the formula out without introducing intermediate variables. There's macros out there that will parse infix arithmetic (http://cliki.net/Infix http://cliki.net/Infix); I've never used them so I can't comment on whether they improve code readability or not.
- lowboy 14y agoI don't see how the lack of (IMO) optional parens would prevent tools from working - they'd just have to be adjusted. Assuming this example from the ParEdit page is well-formed lisp: (defun paredit-barf-all-the-way-forward () (interactive) (paredit-split-sexp) (paredit-forward-down) (paredit-splice-sexp) (if (eolp) (delete-horizontal-space))) It doesn't seem that hard to rework a tool to use sig whitespace as indicating parens to have it operate the same over this code: defun paredit-barf-all-the-way-forward () interactive paredit-split-sexp paredit-forward-down paredit-splice-sexp if (eolp) (delete-horizontal-space)
- wes-exp 14y agoWhy the dependency on node?
- mistercow 14y agoThe obvious reason would be that to make it work nicely as a compiler, they wanted to make it pull in files and compile them. It shouldn't be terribly difficult, though, to patch it and make it compile in-browser like CoffeeScript does with special script tags.
- stevelosh 14y agoAccording to the docs it's pretty close to that already: http://lispyscript.com/docs/#browser http://lispyscript.com/docs/#browser You'd just need to make it find the special script tags and eval them. EDIT: Yeah actually it's already in there: https://github.com/santoshrajan/lispyscript/blob/master/src/browser.ls#L34 https://github.com/santoshrajan/lispyscript/blob/master/src/...
- mistercow 14y agoActually, it turns out it's already implemented: https://github.com/santoshrajan/lispyscript/blob/da6602126eb0707c886c88f6ef6627f7c3882dec/src/browser.ls https://github.com/santoshrajan/lispyscript/blob/da6602126eb... So any script with type "application/lispyscript" will automatically be parsed and run. The only requirements appear to be RequireJS and underscore.
- cheez 14y agoI prefer Parenscript http://common-lisp.net/project/parenscript/ http://common-lisp.net/project/parenscript/
- irfn 14y agohave you tried clojurescript
- klibertp 14y agoI did - I don't like Clojure (because I much, much prefer Scheme to CL) but it seemed very interesting. However, it felt very heavy, almost like GWT. There is something very similar for Racket[1], but even though it's Scheme it still feels much to heavyweight and I couldn't bring myself to use it. [1] http://hashcollision.org/whalesong/ http://hashcollision.org/whalesong/
- ynniv 14y agoI was very disappointed by whalesong. Instead of a source->source translator like parenscript, whalesong generates a bytecode level VM inside the browser. Doing so provides support for any racket language, but it does so at the cost of immense quantities of "pre-obfuscated" JavaScript. The genesis of whalesong was to support "World"[1] games on the web, and to that end it seems successful. I don't think it makes a good general purpose tool. Perhaps someone wants to port parenscript to scheme? [1 | http://world.cs.brown.edu/ http://world.cs.brown.edu/]
- batgaijin 14y agoHow slow is whalesong though? I know people like to say that js is slow, but it's really only the DOM manipulation that makes it so.
- wahnfrieden 14y agoI don't know whalesong. But if you include a giant runtime, the compilation and evaluation of it on every page load, and downloading it (there's evidence to show many hit CDNs with cold caches, probably screwed up firewalls or proxies that mess with caching) can make for a suboptimal experience that can't be optimized without rewriting in something that doesn't require a bytecode VM embedded in your JS.
- Xurinos 14y agoI experience a kind of jolt when I read lispy syntax mixed with constructs like [1, 2, 3]. It shouldn't be a big step to make a syntax for #(1 2 3) or (make-array 1 2 3) instead. Get rid of that infix comma syntax! Then there is the record syntax... {foo: 3, bar: 4}... Infix commas and colons! How about (make-object foo 3 bar 4) or #O(foo 3 bar 4)? Or support reader macros so that you can override []s and {}s to do something a little prettier.
- piranha 14y agoWhy not [1 2 3] and {foo 3 bar 4}? Clojure gets it right. :)
- ynniv 14y agoTwo of the best parts of clojure (over other lisps).
- Xurinos 14y agoFor Common Lisp to support converting [1 2 3] to a vector: ; [] to #() (defun bracket-reader (stream char) (declare (ignore char)) `(vector ,@(read-delimited-list #\] stream t))) (set-macro-character #\[ #'bracket-reader) (set-syntax-from-char #\] #\)) And for your in-place hash: ; {} to hash (defun set-hash-values (hash pairs) (when pairs (setf (gethash (car pairs) hash) (cadr pairs)) (set-hash-values hash (cddr pairs)))) (defun in-place-hash (stream char) (declare (ignore char)) `(let ((hash (make-hash-table))) (set-hash-values hash ',(read-delimited-list #\} stream t)) hash)) (set-macro-character #\{ #'in-place-hash) (set-syntax-from-char #\} #\)) I just sketched these together. I am a CL noob. No doubt there are more concise approaches.
- postfuturist 14y agoAccording to the docs, (array 1 2 3) and (object "foo" 3 "bar" 4) works, too.
- 14y ago
- ajanuary 14y agoCool, but could do with shortening the 'function' keyword. It's just too long for the amount it's used.
- postfuturist 14y agoThis is just a light lisp-like syntactic layer, as the docs say "LispyScript is not a dialect of Lisp. There is no list processing in LispyScript ." It's just enough to allow nice macros, which adds quite a bit, IMO. There's no CONS, etc. It adds a couple nice things, like an "each" function that does the right thing, and (= foo bar) becomes foo === bar.
- deleted 14y ago[deleted]
- aufreak3 14y agoSome time back, I tried to take JSON as the AST and see if I can build a Scheme-like programming language with it. I did it just for kicks, but if it interests anyone .. [1]. It's lacking in docs, but this might be of interest - you get a Scheme-like language (without tail recursion), keyword arguments, lambda, macro, quote & quasi-quote, let expression, where clauses, generators, and some degree of code isolation. The compiler is a very simple one and is written in "stream of thought" style [2] and so might be quite easy to follow. [1] http://github.com/srikumarks/jexpr http://github.com/srikumarks/jexpr [2] http://srikumarks.github.com/jexpr/ http://srikumarks.github.com/jexpr/