Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Sometimes I think Clojure should have been developed on top of the ErlangVM instead of the JVM. I think that the ErlangVM solves a lot better the problems that Clojure is trying to solve. Also, seems like targeting the ErlangVM is an achievable feat, since Elixir in its version 1.3 has proven to be extremely solid.

Crazy idea: if I wanted to implement Clojure on top of the ErlangVM, where should I start?



I think shared memory is foundational to Clojure's approach to concurrency, and that is something the Erlang VM cannot provide. So some main fixtures of Clojure's standard library, like atoms, STM, agents, become either useless or nonsensical.

It's also not clear to me wether the Erlang VM provides what Clojure needs to efficiently implement its user-defined types, protocols, etc

That said, a Clojure-like dialect of lisp built on Erlang is a fine idea and, as others have said, I would probably start by seeing how the Lisp-Flavoured-Erlang (LFE) guys built their lisp.


Mnesia is sorta like STM in Erlang.


Actually no, it is completely different internally with different properties.


How about targeting Go instead?


Like via transpilation or what? LLVM would be a more natural choice if looking to compile to native.


Yes but it doesnt have a concurrent garbage collector.


One of the main objectives of Clojure was interoperability with Java because of the ecosystem. Java and Erlang ecosystems are not comparable.

Also, JVM is great. :)


That's not true. One of the main objectives of Clojure was to be a hosted language. Not just 'language hosted on JVM'. So idea to make it work on top of Erlang VM is perfectly valid and consistent with original design assumptions.


Whether it's as important now or not is a different matter I suppose, with various targets for the language (including other VMs), but I don't think it's in dispute that originally the extensive java ecosystem was core to what clojure was, and was designed to be.

...but hey, don't take my word for it:

    The net result is that the prospects for Clojure going forward are
    very good. The core model of Clojure has held up well and continues to
    appeal - accessible, robust, thread-safe, efficient dynamic functional
    programming, on a world-class infrastructure, with a huge set of
    libraries. Oh yeah, and it's great fun! 

    - Rich Hickey, 2008
    https://groups.google.com/forum/#!topic/clojure/2CA_H58Cbo0


That might have referred to the CLR and the JVM though since Clojure has targeted both runtimes from the start (although the JVM implementation is leading of course.)

This talk should go into a bit more detail about this: https://channel9.msdn.com/blogs/charles/emerging-langs-cloju...


Except then it might not have had as much uptake (tooling, existing Java libraries, installability to various providers and interoperability with existing systems etc.).

Now that Clojure has a varied and excellent set of libraries of its own maybe some of this is less important, but not all (the ability to interact with existing Java systems is still very useful).


> One of the main objectives of Clojure was to be a hosted language. Not just 'language hosted on JVM'.

Uhm... I always thought it was meant to be a Lisp for JVM. Where did you get your information from?


The erlang ecosystem has new-found life with Elixir. The ecosystem for Elixir is rock-solid. Very high quality libraries abound.


Absolutely. The level of robustness is outstanding for such a new language / ecosystem.


To be fair, and I find this to be a bit of a shame, but most of that robustness and ecosystem comes straight from Erlang, which was always solid. Though I do enjoy the consistency that Elixir brings and the improved macros. I'm a Clojure guy, so I also love the protocols.

Just wanted to say that Erlang vanilla is robust and has a great ecosystem. So Elixir builds itself on top of a solid foundation.


Take a look at LFE [0]

[0] http://lfe.io


If I remember correctly, LFE is a Lisp2

Joxa (just like Clojure) is a Lisp1, thus maybe more apt http://joxa.org


I'm curious, what are the practical differences? I know what the theoretical differences are, but do you have any experience with how lisp1 and lisp2 are different in daily use?


I'm afraid I don't have a satisfactory answer for you.

I just prefer to pass around functions/closures as values, and being able to invoke them like any normal function, instead of having to call an helper `apply`/`invoke`/`call` function on them (depending on the language)

That's why I said: "maybe more apt"... if OP doesn't care at all about that difference, and it's not among the details that they'd want to replicate from Clojure, it's perfectly ok to ignore


I never found the funcall argument terribly convincing, because there is no reason it couldn't be much more concise. And it allows you to avoid silly variable names like lst or fst.

In Common lisp to refer to a function as a variable you do (function f) or as (read-table) syntactic sugar #'f. You could easily use destructuring to write HOFs without funcall.

So instead of requiring people to write

  (defun bad-map (f list)
    "Maps function `f' over `list', inefficiently."
    (when list (cons (funcall #'f (first list) (bad-map f (rest list)))))
  (bad-map #'- '(1 2 3))
A hypothetical lisp-2 could just as well allow destructuring like this:

   (defun bad-map (#'f list)
     "Maps function `f' over `list', inefficiently."
     (when list (cons (f (first list) (bad-map #'f (rest list)))))
   (bad-map #'- '(1 2 3))
The fact that higher order functions stick out a bit by the extra #' is not necessarily a bad thing IMO; it helps when reading unfamiliar code to know immediately what arguments are functions and which ones are just plain objects.


In Common Lisp in your first example it's not

   (funcall #'f (first list) ...)
but

   (funcall f (first list)) ...
f is already a function object.

We could write a macro for that or a new version of defun. Here just a macro lisp1fy:

    (defmacro lisp2fy ((&rest calls) &body body)
      `(flet (,@(loop for (f . args) in calls
                  collect `(,f ,args (funcall ,f ,@args))))
         (declare (inline ,@(loop for (f . nil) in calls collect f)))
         ,@body))


    (defun bad-map (f list)
      "Maps function `f' over `list', inefficiently."
      (lisp2fy ((f a))
        (when list
          (cons (f (first list))
                (bad-map f (rest list))))))


Yeah, braino -- thanks. A custom binding form would be another way to do it, but I'd prefer the pseudo-destructuring -- cleaner and more concise. I'd hope a new lisp-2 dialect would come with better destructuring support for defun and binding forms anyway (destructuring-bind, multiple-value-bind and flet could all be subsumed by let if (values ...) (function ...) where valid left hand patterns).


I just felt that as you can many functions with the same name but with different arities (number of args) at the top-level why shouldn't I be allowed to have it deeper down as well. Also this means that I can only sometimes refer to a function with just its name, when it is at the top-level you need need both name and arity.

This means that Lisp-1 doesn't really fit anyway so why let it limit you?


I would start with lisp flavored erlang, and add clojure's immutable yet fast-copy data structures. They are based on work by Phil Bagwell,

https://en.wikipedia.org/wiki/Hash_array_mapped_trie http://infoscience.epfl.ch/record/64398/files/idealhashtrees...

You might do better to create a Lisp Flavored Haskell (if one hasn't been started already). I'm sure haskeller's would be offended by the idea, but it already uses HAMT.


Why do you think Haskellers would be offended by this?


Because they hate parens so much they spent a $ to eliminate them.


Read up on Lisp Favored Erlang, there's a lot of reasons why Clojure doesn't work well on BEAM, and they're covered by the author of LFE.


Crazy idea: if I wanted to implement Clojure on top of the ErlangVM, where should I start?

I would look at retargeting the ClojureScript code generator. Clojure implements a lot of primitives in Java, but ClojureScript is largely written in Clojure and ClojureScript itself so should be easier to port.


Suggestion: Have a look at Lisp Flavoured Erlang [1], a Lisp-2 on top of Erlang/OTP that might be 90% of what you want to achieve. :^) I am sure they are happy for new members of the community!

[1] http://lfe.io/


It would be very interesting to have pointers here. I would have liked to do the same thing, but for Golang.


Maybe here: http://lfe.io/


I think I'd have a look at ClojureScript and/or Clojure CLR (https://github.com/clojure/clojure-clr). The former is Clojure on top of Javascript, the latter Clojure on top of .Net.

It will not be easy, but I'm no expert. I'm also not sure why you'd really want that? Just to solve the long startup time?


Forking Joxa (https://github.com/joxa/joxa) could be a good place to start.

Might I propose Cloxure ("clock-jur") as the language name? :)


Hmm hmm study the internals of Lumo maybe? Here's a question, would you be able to build non-actor based concurrency primitives like async's go blocks on a actor based erlang framework? (sorta shooting the shit here)




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: