5 ms·
I find your decision surprising. >> there just wasn't a compelling reason to keep it over es6 << How about these reasons: - much simpler language - core.asyn
by smnplk 10y ago
I find your decision surprising.
>> there just wasn't a compelling reason to keep it over es6 <<
How about these reasons:
- much simpler language
- core.async channels/ no callback hell, easier to read async code
- persistent data structures
- great sequence abstraction
- live code reloading
- vibrant community
- improved tooling
- macros
- transit
- drawnwren 10y ago>> - much simpler language Given that it all compiles down to JS before execution, I'm not sure I agree. With Java, you're going to bytecode operations which (imo) allows for a simpler language than compiled to. >> - core.async channels/ no callback hell, easier to read async code I agree, callback hell sucks. I'm not sure that core.async is a huge win over promises, but this is an area that JS is quite horrible. >> - persistent data structures >> - great sequence abstraction I'm not sure I see the benefits of clj's sequence abstraction over js. You get destructuring and sequence comprehension in es6, although clj's recur/callstack fix is quite nice. >> - live code reloading - vibrant community - improved tooling - I'm pretty sure all of these are better in JS than CLJs. >> macros - transit Macros are the old LISP fallback, but seem very counter to any argument of 'simplicity,' I very rarely find need for macros in the front and Clojure's design philosophy generally favors not using them (Data > Functions > Macros) I do like CLJ and CLJS is interesting, but the only reason I really reach for CLJS is if I am feeling like writing something in om.next.
- fnordsensei 10y ago> Given that it all compiles down to JS before execution, I'm not sure I agree. Most likely, they meant "simple" more in the syntactical sense than in the sense of language abstraction level. > Macros are the old LISP fallback, but seem very counter to any argument of 'simplicity' Macros is just transformation over a data structure, albeit a data structure that is interpreted as code later on. It shouldn't add more complexity than other forms of data transformation. > I very rarely find need for macros in the front… Neither do I, but I'm glad they exist. Core.async is built with macros, for example. They are part of what makes it possible to have core.async as a library rather than having to build it into the language.
- drawnwren 10y ago>> Most likely, they meant "simple" more in the syntactical sense than in the sense of language abstraction level. Outside of the Clojure world this would be a reasonable interpretation. However, if you watch 'Simple made easy' by Rich Hickey - that was the definition of simple I was going with (as opposed to easy.) >> Macros is just transformation over a data structure, albeit a data structure that is interpreted as code later on. It shouldn't add more complexity than other forms of data transformation. Because they specifically inject before the eval section they _do_ add a lot of complexity. Writing complex macros is a lot of guesswork. >> Neither do I, but I'm glad they exist. Core.async is built with macros, for example. They are part of what makes it possible to have core.async as a library rather than having to build it into the language. I'm not sure what the benefit of this vs 'language features' is at this point.
- kazinator 10y agoMacros de-risk themselves by going away before compile time. So even if they are complex, they are not complex in a way that causes us to lose sleep at night wondering "does that have a hidden bug that will blow up in the field". Even if a macro is buggy, if the particular instances (i.e. macro calls) don't step on the bug, then we are okay. The expansion is done, and it is good. Macros are deterministic and susceptible to regression testing with simple "X translates to Y" assertions. We don't have to be overly concerned with the time and space performance of macros, either. The code in a macro expander can be structured for clarity and remain that way. (Even in situations in which running Lisp apps are patched, the macro expansion doesn't have to be done in the application image. The translation unit can be compiled using a separate development image, and loaded as compiled files in the running app.)
- greenyouse 10y agoI think macros can still be used for developing simple systems but it comes at a more difficult development cost. Unless you're used to macros, they're weird to write and there aren't many places to learn about macro design patterns (On LISP and LOL are good IMHO). There are examples of major projects that use macros effectively though. Look at core.logic, om.next, core.async, or many other large cljs projects. If knowledge of how to use macros was better, I think some of the macro FUD would go away. If you're not using macros then you might as well not use a LISP. I'd agree though that using macros improperly leads to all kinds of problems.
- edem 10y agoClojure does not have the warts JS has. This is a win in itself. Data structures in clojure are unimaginably better. In js you don't have anything like this. For example you can't tell how operations in js will perform since not even their complexities are documented. Please elaborate about the better community. AFAIK js libraries have the half-life of months and you can't rely on them not being obsolete after you finish a project. Macros are a tool which you don't have to use. Everything in the clojure world is optional. But when you need it you have something powerful. Try and emulate macros in js (like AOP in java) and you are in for a rude awakening.
- shadowmint 10y agoTo be fair, the only thing if your list which is actually tangible is core async, the rest is just personal opinion (live reloading and vibrant community I question somewhat, just because javascript has both too). ...but really, it boils down to the fact that the people who were writing clojurescript in house wrote terrible spaghetti code that didn't work. Without a tangible justification for re-writing (again) in clojurescript, the decision was made to rewrite it in es6 and throw all of the clojurescript away. I think the lesson here is: Having an excellent language (Clojure) can't save you from writing bad code. For some reason writing clojurescript resulted in code that was a far lower quality than the clojure code from the same developers. /shrug I can't explain why that is, but for us, it boiled down to: If you can't play nicely, you can't have nice toys. Quality of the end product is more important than the tools used to build it.