5 ms·
I don't really think of Lisp as a functional language: it's really an imperative language with some functional features, and some OO features, and some aspect-o
by wtbob 11y ago
I don't really think of Lisp as a functional language: it's really an imperative language with some functional features, and some OO features, and some aspect-oriented features and so forth.
The advantage that I see in switching to Lisp is that it's a nice, pleasant, powerful language in which to work. The standard is well-thought-out. The abstraction capabilities are wonderful.
Compared to JavaScript, there's no comparison:-) Just off the top of my head, Lisp has integers, ratios (e.g 1/2), big integers (e.g. (expt 2 2048) →
a number so large it breaks the HN page wrap) and complex numbers (e.g. (sqrt -3) →
#C(0.0 1.7320508)).
Lisp's error-handling system of conditions and restarts is profoundly powerful: one part of code hand signal an error, another can determine how to fix it, and execution can resume without unwinding the stack (as opposed to exceptions, where by the time a higher level of code determines what to do the function encountering the problem has already returned). Technically, one could implement this in JavaScript (it's all based on first-order functions), but since JavaScript doesn't have macros it'd be pretty hideous.
Which raises the point of macros, which are enabled by the uniform syntax. They're a powerful tool for syntactic abstraction, just like functions are a powerful tool for procedural abstraction. A language without macros is almost as primitive as one without functions.
There are also read-macros, which enable one to customise or even replace the parser (called a reader in lisp). Don't like Lisp? That's okay, you can write a reader which parses JavaScript and returns Lisp objects to be evaluated or compiled! Then there are compile macros, which enable compile-time optimisation. And there are symbol macros, which can make what looks like a variable access actually able to perform any operation. Imagine being able to write 'foo = bar' in JavaScript, and having that assignment be logged. In Lisp, you can do that.
One big advantage is that all of these macros systems are … just Lisp. They're not special: you can do anything in a read macro that you can do in your code. You don't have to learn a special syntax or a limited subset of the language: it's all there if you need it.
Then there's the object system (which is enabled by macros). CLOS is the most powerful, most convenient object system with which I'm familiar. JavaScript methods belong to a prototype, which means that in foo.bar(baz) only foo determines what bar is; in Lisp, methods are multimethods, and may be specialised on any and all arguments: (bar foo baz) could do different things depending on the type of foo, the type of baz or the types of both.
Places are an amazing concept. In most languages there's no way to say 'foo(bar) = baz', but in Lisp one can do (setf (foo bar) baz) with the right setf functions and it Just Works.
Lisp has optional type annotations, which can lead to extremely fast code.
Then there are little things like well-thought-out equality predicates, cleaner-looking code &c.
The advantage of JavaScript over Lisp is that because it is installed everywhere it has a much, much, much larger community, which means more libraries, wider support. But install base and community size are honestly the only real advantages I can think of.
- petra 11y ago>> The advantage of JavaScript over Lisp is .. more libraries, wider support. Clojure solves that.
- adrusi 11y agoIt doesn't, really. Not all that much is written in Clojure. Clojure has a nice FFI, and it turns out that lisps are pretty good at calling into java code, but other lisps also have FFIs. The FFI support is inconsistent between implementations, but of course the same could be said of JVM Clojure and Clojurescript.
- wging 11y ago> it turns out that lisps are pretty good at calling into java code I think that gives the design of Clojure too little credit. I can imagine MUCH worse ways to do it than Clojure's well-designed Java interop.