Hacker News new | ask | show | jobs
by axelrosen 2722 days ago
As a Lisp dialect it isn't that innovative besides a few syntactic improvements [0]. I'd gladly use Common Lisp instead if it could do something like ClojureScript. But by design it'd be hard to pull off.

Like a good politician Clojure is pretty unimpressive in of itself, for any given characteristic, someone has a better take. But as a whole it's one of the few sensible choices out there.

[0] I feel like they're generally underrated. Adding [] {} and #{} might not seem like much, but when writing DSLs they really do make all the difference.

4 comments

I appreciate that CL doesn’t have reader macros for those characters too: it allows me to do things like repurpose [] for objective-c method calls.

https://github.com/fiddlerwoaroof/objc-lisp-bridge

Well, Clojure doesn't have programmable reader macros either way.

As long as you're not dead set on specific characters you could do:

   (defun extract-from-objc (obj)
     (objc-typecase
      obj
      (%@NSDate [[[[%@NSISO8601DateFormatter @(alloc)]
                   @(init)]
                  @(stringFromDate:.) :pointer obj]
                 @(UTF8String)]s)
      (%@NSString [obj @(UTF8String)]s)
      (%@NSNumber (parse-number:parse-number
                   (objc-runtime:.:extract-nsstring
                    [obj @(stringValue)])))
      (%@NSArray (map-nsarray #'extract-from-objc obj))
      (%@NSDictionary (fw.lu:alist-string-hash-table
                       (pairlis (map-nsarray #'extract-from-objc [obj @(allKeys)])
                                (map-nsarray #'extract-from-objc [obj @(allValues)]))))
      (t (or (funcall-some (cdr (objc-pick-by-type obj *objc-extractors*))
                           obj)
             obj))))
The reason I say they're good for DSLs is exactly for re-purposing to have a special meaning. Yes, nowhere close to being as powerful as reader macros. But the nice part is everyone can and knows how to work with these primitives.

I do wish we had reader macros like CL, but I'd still totally want the built-in [] and {}.

I really like how most of the non-sexp syntax is optional in CL. Anyways, I'm also a bit ambivalent about the merits of [] vs. #(): I like how the latter syntax is more "standard", since the # dispatching macro character is used for a bunch of things. E.g. multidimensional arrays #2a() #3a() complex numbers #c(1 2) character literals #\space, pathnames #p"/foo/bar" etc.: it adds to the uniformity of the syntax, ime.
Anyways, I guess I like CL's approach where #[] #{} [] and {} are all specified as reserved to the user and then, using named-readtables, you can pick an appropriate implementation as you see fit.
> do something like ClojureScript

I'm betting on the ongoing Weblocks rewrite: http://40ants.com/weblocks/quickstart.html Here no need to transpile to JS, you just always stay in CL, in the CL environment, state is preserved on edits, etc.

Parenscript is pretty close, as is js-cl. The issue is mostly that no one has written something like figwheel or shadow-cljs yet.
Never heard of js-cl, but Parenscript definitely isn't. It's a glorified s-exp notation for javascript. ClojureScript doesn't compile to plain js. It maintains a lot of it's characteristics at run-time. And this is possible because Clojure does something very similar on the JVM. This in turn enables you to write code targeting both platforms without too much effort.

WISP is a little more like the Parenscript of Clojure (though it's written in javascript itself) https://github.com/Gozala/wisp/blob/master/doc/language-esse...

js-cl is a (still-partial) Common Lisp implementation in JavaScript. https://github.com/jscl-project/jscl/blob/master/README.md

Parenscript is a bit more than just a glorified s-expression wrapper for JavaScript: it also implements a lot of the core CL macros (defun, let, lambda, etc.) in ways that are close to the CL semantics. It’s limited by the fact that it doesn’t want to have its own runtime: so, while there is some degree of source-level compatibility, it doesn’t have things like restarts and CLOS that would require runtime support (although, there is a library called the Parenscript object system that provides some degree of source compatibility with CLOS.

Yea, it looks like js-cl is more like it. You'd want to implement some reasonable subset of CL. And ClojureScript really didn't have to compromise on much, which is why it's been embraced so easily.

Most of the time you just have a .cljc file and pretty much the same exact code just works on both platforms. In a few places you'll use the #? reader macro that lets you do different stuff based on platform, and that's it.

Well, you basically get simple macros for free as long when you have an s-exp based notation for something. Which is why I do in fact like them. Something like Parenscript or Wisp is really great for lightweight websites.

I remember way back around 2010 or 2011 playing around with CL and Parenscript a bit and it looks like the landscape isn't too different today.

>Parenscript definitely isn't. It's a glorified s-exp notation for javascript.

It is not. Parenscript is a subset of Common Lisp that then gets translated to Js.

ClojureScript is also a subset of Clojure that runs on javascript.

> ClojureScript doesn't compile to plain js

How does it run on a javascript-enabled browser, then?

Yes, you could call both of them subsets. But one is so small that for most purposes is incompatible for anything but the simplest uses. While the other lets you run an almost identical codebase on two platforms. There are plenty of people who only ever write ClojureScript and couldn't care less about the JVM Clojure, because it really is that close.

And yes, as other mentioned js-cl is trying to do something similar, and I hope it works out!

Sorry bad wording on my part, was just reiterating the point that Parenscript maps closely to regular looking js, while cljs abuses js quite heavily.

Someone has a long time ago:

https://github.com/johnmastro/trident-mode.el

It works like a charm.

> I'd gladly use Common Lisp instead if it could do something like ClojureScript

It does. Parenscript has existed for years.

And there's also JSCL.