51 comments

[ 3.2 ms ] story [ 113 ms ] thread
Page is a frameset around https://clojerl.github.io, which breaks the mobile experience (fixed width, content too small). Going directly to the github.io copy scales the content correctly and provides https.
Clojerl is really cool, and you should play with it; it's actually surprising how well the semantics transfer over to the Erlang VM.

If anyone wants something that feels a bit more vanilla-erlang-ish, one should also check out Lisp Flavoured Erlang. It is almost a direct one-to-one translation of Erlang into Lisp-land (actually made by one of Erlang's co-creators), but also provides Common-Lisp-Style macros, and a much more consistent, cleaner syntax than vanilla Erlang.

that was insightful, thank you
There are at least 19 alternative languages for the BEAM[1]. If anyone knows of any I’ve missed, let me know.

[1]: https://gist.github.com/macintux/6349828#alternative-languag...

There are 4 relevant VMs: .net, java, js and erlang.

If you're making a language and not targeting one of them, you're DOA.

Also LLVM, wasm, amd64, ARM, aarch64, RISC-V, Vulkan, Radeon, NVIDIA, Gen, and iCE40. Instruction sets are more exciting than they have been since the 1980s.
These are native instruction sets, not a VM. The parent seems to also mean runtimes, which LLVM does not provide
I think all of those have software implementations ("VMs")†, although it's true that some of them have hardware implementations as well ("native instruction sets"). Since the IBM 360, though, the distinction has been very fuzzy.

† although Intel Gen, RADEON, and the NVIDIA GPU ones might be an exception

And none of them guarantee tail call optimization leading to trade offs in the design of particular languages that may or may not be acceptable.
Erlang guarantees tail call optimisation.
Pretty sure .Net has a TCO opcode that F# uses.
What does "guarantee" mean here? If you end a function in BEAM with another function call, it's TCO.
Tail Call Optimization is an optimization done by the compile/vm that replace (in assembly terms) a CALL by a JMP. Therefore removing a call stack.
Dead or arrival? I'd argue Go and Rust are pretty prominent recent arrivals that have seen great uptake.
The site does a great job explaining what Clojure features exist in this port ... but what about Erlang features? There doesn't appear to be a first-class adoption of things like supervisors and actors like you see in Elixir, for example. Or at least the docs don't do a great job explaining it?
That was also the first thing I was looking for in the docs. I mean how it ties to the Erlang OTP. It's the reason why anyone would use Erlang's platform after all.
I found the project via this article:

https://medium.com/clojure-on-the-beam/agents-9de923017adf

that discusses why Clojure 'agents' haven't been implemented in BEAM yet. I think (and I'm not familiar with Erlang) that Clojure agents are very similar to Erlang actors.

This is my understanding of agents vs actors, I may be naive or wrong:

Actors are an instance of an object that has inherent logic and maintains mutable state within itself

Agents are state with logic attached to them that are immutable and return a new instance of the state (along with attached logic)

(comment deleted)
With the ability to reach Java, JavaScript, .Net, and Erlang runtimes, plus interop with many other languages via GraalVM, Clojure has incredible reach across runtimes, perhaps more than any other modern programming language, certainly among Lisps. That said, its pretty gnarly to try to navigate all of the implementation differences among platforms. I wonder if there is a subset of Clojure that is 'safe' to run on any of its supported environments.

This list is pretty long: https://clojerl.github.io/differences-with-clojure/

For now, the JVM is the only way to get the full Clojure experience.

The Clojure community believes strongly in the idea that it is a hosted language, and therefore prioritizes maintaining the semantics of its host (whether that be the JVM, a JS engine, or some other VM) over independent, consistent semantics for Clojure itself.

That being said they've made some concessions to the fact that it would be really nice to have portable Clojure code with `.cljc` files, but those are only portable Clojure code by matter of convention (the only technical thing `.cljc` files accomplish is allowing you to use reader conditionals).

Personally, I wish Clojure went further. Even with the commitment to being a hosted language, it still is clunkier at interop than Scala or Kotlin, two languages which nonetheless do have independent semantics as specified in their respective language specifications. It kind of seems you end up with the worst of both worlds (worse interop and no consistent semantics), although to be fair Clojure also commits far more heavily to the FP paradigm than Kotlin or even Scala, which makes it intrinsically more difficult to have seamless interop with Java (yes yes yes its interop with Java is already quite good, just not quite at the level of the others).

Yeah, I’ve developed some clj/cljs code. It’s full of conditional compilation. It’s even full of conditional compilation expressions in the ns header.
It's great, but the differences between runtimes can be painful. In practice you still need your project to be aware of which Clojure code files are platform-specific and which are safe to run across all platforms.
Submarines are useless underwater -- George Zimmerman(n). Signed by James Goulding
I'm curious to see a detailed list of language constructs and features that are and aren't supported.
I don't see how this brings anything new to the ecosystem. Clojure is a LISP and we already have lfe (http://lfe.io/) - LISP floured Erlang for quiet a while now, hence it will definitely be more mature than a new implementation altogether. Moreover I feel, seeing the the currently more effort should be made in maturing the classic clojure implementation and the tooling around it itself, rather than diverting the community into fancy new (not so useful) ports of the same syntax for other runtimes. Seriously, just go improve clojure itself. And if you want to be able to write lisp for BEAM, just use lfe.
I don't think this implementation harms either Erlang or JVM clojure ecosystems. I also doubt the creator of this has as much interest in maturing JVM tooling as you so demand of them, if they did, they wouldn't have made this port.

If this is inferior in every way to lfe then it will remain a niche project. If not, perhaps it will encourage some improvements either in lfe or Erlang itself (though I think the latter is unlikely).

one does not simply say one lisp dialect is better than the other.
I never said one is better than the other. All I said is, if you want lisp on BEAM, you already have lfe.
> if you want lisp on BEAM, you already have lfe

if you want lisp <insert condition>, you already have <insert lisp satisfying condition>.

your assumed condition is wrong, a person may not just want lisp on beam, they may want clojure on beam.

the only major difference I see between what you're calling 'clojure' and a lisp is that clojure compiles to JVM. That alone goes for a toss when you say you're porting it to BEAM. There is no more java in the equation. Its interop with erlang/elixir ecosystem. Which is exactly what lfe is (apart from some minute differences in syntax which may or may not be there).
> the only major difference I see between what you're calling 'clojure' and a lisp is that clojure compiles to JVM

it's always better to ask than to make incorrect assumptions

A quick plug for LFE and its very simple premise: in mortal fear of Rails, I embraced the potential of Elixir (with 100% more Phoenix); I had a wonderful test case for macros (can't even remember what it was anymore); I spent hours trying to craft it and fought, fought, fought the AST/syntax/complexity; finally, in anger remembered the mere existence of LFE and its promise of DEFMACRO.

I wrote my first vaguely non-trivial LFE program as a macro in the REPL as a guess, and it worked on the first try.

If I need a lisp in BEAM, I would run with LFE on that alone.

More to the point, Clojure is in 2020 the only Lisp that matters. If ypu want to develop a Lisp that attracts the attention of people who work on things that make actual money, your best bet is to port Clojure.

    <frameset rows='100%, *' frameborder=no framespacing=0 border=0>
        <frame src="https://clojerl.github.io/" name=mainwindow frameborder=no framespacing=0 marginheight=0 marginwidth=0></frame>
    </frameset>
What...? Why...? I just can't...
Custom domains on GitHub are not free... people find ways.
I'm pretty sure they are.
Why Clojerl when LFE maps directly to the best of what BEAM offers - supervisor trees and pattern matching?