9 ms·
Code-sharing between ClojureScript and Clojure is a killer app
by dustingetz 8y ago
Code-sharing between ClojureScript and Clojure is a killer app
- saosebastiao 8y agoNot really. Although Clojure and Clojurescript are both dynamically typed, Clojure is strongly typed while Clojurescript is weakly typed. Clojure: (+ "1" 1) ClassCastException java.lang.String cannot be cast to java.lang.Number clojure.lang.Numbers.add (Numbers.java:128) Clojurescript: (+ "1" 1) "11" They may be close, but that is all the reason for concern. There are a million ways that small semantic differences like this can completely fuck you and leave you in a debugging nightmare. I would rather use javascript, AKA the worst language ever invented, than a language that claims to be cross platform but with semantics that change depending on the platform.
- drcode 8y agoI see your point, but I've never once run into any issues with these minor syntax differences when building libraries shared between clj & cljs.
- jgalt212 8y agoYou raise a good point. Is there a linter available that would flag such non-portable code?
- saosebastiao 8y agoThere probably is, but I haven't used clojure for at least 4 years so I'm not the person to ask. Regardless, a linter might flag things like that, but in my experience the most pernicious ways that it hurts wouldn't be found because they exist outside the application due to IO boundaries. Things like API or database calls, etc.
- yogthos 8y agoyou get a warning from the compiler in ClojureScript when type coercion happens: cljs.user=> (+ "1" 1) ⬆ WARNING: cljs.core/+, all arguments must be numbers, got [string number] instead. at line 1 "11" You can also use Spec and Schema to validate data at the edges, so that you don't end up with unexpected inputs. I highly recommend doing that for any non-trivial projects.
- dustingetz 8y agoHere is just one example of what client/server code-sharing makes possible: Hyperfiddle apps are fully CLJC which means literally the same code runs in the browser for view things, the JVM for web service things, inside Datomic Peer for database things, also Node and soon lambdas. Since they all share the same code, they can coordinate I/O automatically and transparently. Never code network side effect ever again! http://www.hyperfiddle.net/ http://www.hyperfiddle.net/
- zbentley 8y ago> literally the same code runs in the browser for view things, the JVM for web service things No, it does not. The same Clojure code may be the source for both execution environments, but that doesn't mean that the code that runs (JVM bytecode or JavaScript in the browser) is remotely similar, follows the same rules, errors under the same conditions, or otherwise behaves similarly. That's not an argument against code sharing. But please read the post you're responding to thoroughly before you post "I can write it once and run it anywhere" without a whole lot of asterisks after "anywhere".
- deleted 8y ago[deleted]
- yogthos 8y agoYou're correct that there is a difference between execution environments between the JVM and Js. However, in practice you're very unlikely to run into them. My team has been heavily relying on cross-compilation for about three years now. We have yet to run into a scenario where this kind of problems actually came up.
- deleted 8y ago[deleted]
- Scarbutt 8y agoThat clojurescript snippet will issue a warning, is that way because of compiler performance reasons if I'm not mistaken. Still, you get immutability by default and a nice std lib of functions, think of lodash/fp and immutablejs together but better since lodash and immutablejs can't be use together anyway. than a language that claims to be cross platform but with semantics that change depending on the platform. This is not true, on the contrary, Clojure[script] claims to embrace the host semantics and platform, is just that there is this capability to share some code between Clojure and Clojurescript that might be useful for some parts of your application, I don't think this is a killer feature of Clojure btw.
- threatofrain 8y agoIs code sharing actually a thing between the front-end and back-end? I find that almost all interesting code "re-use" comes from libraries.
- drcode 8y agoIt's pretty awesome now that graph query languages (graphQL, etc) are so popular: Lots of reuse possibilities when you use the same query language for updating the browser state and also updating server side actions.
- dustingetz 8y agoThe question is motivated by the observation that a set of REST webservices, and a set of React views that consume them, are so different that there isn't any code reuse. I'd ask you to note the parallel structure between them. They are two sides of the same data sync problem. Yes, of course there are common bits that can be factored out. The problem is that most people have never so much as thought about it, because of the language barrier, and other barriers – for example teams are structured around this artificial divide of frontend and backend. You need a new architecture to take advantage of the parallel structure. GraphQL is just the beginning.
- deleted 8y ago[deleted]
- dustingetz 8y agoReact.js, if you squint, is also a step in this direction – React.js on the client can bind to a DOM, or run in Node and stream strings to a socket. In other words React decoupled HTML rendering from platform APIs by making it data driven. Data is universal and can be manipulated on any platform, even pencil and paper. What other platform APIs can be replaced by something data driven? I know from my study of Haskell that the answer is probably: all of them.
- threatofrain 8y agoI'm quite curious as to when types and methods are going to be shared across boundaries.