I enjoyed this podcast focusing upon a fellow JVM language. I was distraught to learn that CLJS+Reagent isn’t such a unique snowflake in its approach to wrapping React and providing things like the Figwheel experience and sharing front-back code (which I used to think was only possible with cljc). To be fair, CLJS never actually claimed to be as special as I liked to imagine it was. He also spoke of “fluid typing” for his Scala and Haskell, which sounded identical to our “gradual typing” and spec.
So, as someone who really loves Clojure[script], what are its unique and almost-unique propositions? It sounds like Scala.js might actually be ahead of it in terms of sharing code and leveraging the eco-system.
Some that come to mind as possibilities:
Google Closure, esp. dead-code elimination.
Immutable data structures by default
REPL (no idea if this is a thing with Scala)
Macros (I don’t use them much, but I know I could)
Dynamic typing (hotly contested as an advantage, but I assume we at this forum see it as a pro)
Lisp syntax (same as dynamic typing: take it or leave it as a pro, but I’ll take it)
What would you add, particularly if you know something about Scala work?
Hi there! Scala.js author and lead maintainer here. I saw this on Twitter, and I’ll just answer with some facts about Scala.js.
Scala.js also uses Google Closure automatically in production builds. We use it in a different way than CLJS, though: CLJS chooses to interact particularly well with Closure-aware libraries, which allows to dead code eliminate across the JS libraries and the CLJS code. However, it means that for some JS libs that are not designed for Closure, additional externs and exports annotations may be necessary to preserve semantics. In Scala.js, we want to guarantee semantics at all cost, and don’t require users to add any annotation. However that means that we only let Closure run on our code, and not across JS dependencies.
Scala also uses immutable data structures by default.
Scala for the JVM has a very good REPL. However, there is no REPL in Scala.js, because of technical difficulties linked to core design choices (there are tradeoffs at play here).
CLJS is clearly ahead of us here.
Also available in Scala/JVM and Scala.js.
Cheers everyone, I love that CLJS exists and gives us such hard yet friendly competition
Going to be hard to answer this without devolving into a language war, but I’ll try
In my opinion, what makes Clojure unique is the intersection of all its features, and the conscious choice to omit certain features as well. And I feel this is true for most languages, you need to consider the sum of all its part.
So what’s unique about Clojure in my opinion is that it has all at ounce:
An homoiconic syntax where code is data, and data is code
Which is clear, consistent, concise and enables full structural editing
Which can be extended with new semantics through macros trivialy
Where data is a first class citizen, and at the center of everything
In that it comes with a full suite of immutable persistent collections like map, lists, vectors, sets, sorted sets, queues, stacks, etc.
And those all support heterogeneous data, because the world is such
And they are the basic holder of data that all other function operate over so that data can be very easily manipulated
And where equality of data is inherent and automatic
Where functional programming is the dominant paradigm
And meta-programming the second most common paradigm
Yet the good parts of Alan Kay style OO are first class (late binding and polymorphic dispatch)
And even still Java style OO can be used where it is actually the best for the task, i.e., to build language constructs like data-structures, where encapsulation is a must
With pretty darn good support for Logic programming as well
Yet where using the wrong paradigm for a given task is made purposely more painful, to drive correct choice of paradigm for given problem
Which is fast and efficient, able to handle modern workloads competitively
Fully dynamic, where every aspect of a program can be modified and modify itself at runtime
Targeting existing platforms such as JVM, CLR, and JS
With first class interop
That doesn’t try to reinvent the wheel, using each platform for what it is good at.
With a small enough core, that the community can extend its reach to new hosts: Joker, Clojerl, Ferret, etc.
With full support for multi-threaded and multi-core programming
Designed for concurrency
But offers a selection of concurrent paradigm: CSP, Executor, Future, Locks
With an amazing REPL
Smartly avoiding having inheritance, reader macros, static types, custom data containers, implicits, etc.
And a great community!
It isn’t anyone of those that in my opinion make Clojure my favorite language yet, but the sum of all these things and some more I mostly forgot.
@sjrd The main differences between Clojure and Scala are:
Scala is a traditional FP, and Clojure is a FP based on RMDB theory. Therefore Clojure is more suitable for processing data.
Clojure -> DBMS, Super Foxpro
STM -> Transaction，MVCC
Persistent Collections -> db, table, col
hash-map -> indexed data
Watch -> trigger, log
Spec -> constraint
Core API -> SQL, Built-in function
function -> Stored Procedure
Meta Data -> System Table
Note: In the latest spec2, spec is more like RMDB.
Clojure is Lisp dialect, simpler.
Clojure is more suitable for data flow programming and Warehouse/Workshop Model. It systematically simulates integrated circuit systems and large industrial production lines. In the computer field, for the first time, it was realized that the unification of hardware engineering and software engineering on the logical model. It has been extended from Lisp language-level code and data unification to system engineering-level software and hardware unification. and it brings large industrial production theory and methods to software engineering. It incorporates IT industry into modern large industrial production systems, This is an epoch-making innovative theory and method.
Honored to have you here and your comments on Scala.JS. Thanks!
I haven’t dug into the history yet, but did cljs (e.g. David Nolan’s work) precede or follow scala.js? After your comment about friendly competition, I’m very curious to know in what ways the languages have influenced each other. Also, what is scala.js reason for using Closure if not deadcode elimination?
ClosureScript preceded Scala.js by a year or so, IIRC. There hasn’t been much direct inspiration–in fact major technical decisions are diametrically opposed between the two systems–but it’s always been good to check up on what works better on the other side, so that we know what we could do better. Live reloading is a major example where we’re jealous of CLJS, and where I’d like us to do better.