-
Notifications
You must be signed in to change notification settings - Fork 153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handling Clojure/ClojureScript protocol differences and other platform discrepencies #49
Comments
I guess this is because there is no "standard library" in both clj and cljs. clj provides things like Other things, like timers or logging could be unified too. However, the problem with different |
I can't really speak to the protocol issues; that sounds like a difficult problem. I do like the idea of using metadata or something similar to provide differing implementations for clj/cljs. One thing that comes to mind would be implementing two new macros: I'm not sure if this would work, though; I worry that the reader would have problems with cljs symbols appearing in clj code. I feel like this could be solved with some careful quoting in the new |
To be honest, I don't really see a problem with having two different files for clj and cljs, it keeps the code clean. I think it's really just a matter of making a The protocol issues are a much harder problem though. Apart from some ungodly hacks like rewriting protocol names in |
I think overall I agree with keeping separate clj/cljs files when the implementations diverge. One problem with that, though, is with macros that need to generate different code depending on the language. It's easy enough to put those macros in different namespaces and include them differently from clj/cljs when the clj and cljs files are distinct, but it becomes more difficult when using the crossover feature to run the same code in clj/cljs. Right now it's possible to use the horrible The macros are a sore point in general for sharing code between languages, seeing as they have to be required differently ( |
As far as protocols, the the problem is that Clojure on the JVM is largely defined on top of Java interfaces and not protocols. In a certain sense, ClojureScript is ahead of Clojure on the JVM here. I don't see this getting resolved until a much larger portion of Clojure on the JVM is written in itself. |
@emezeske, I'm not too concerned about macros that need to generate different code for clj/cljs quite yet (i.e., meta-issue 49). I feel like trying to keep clj/cljs for the same namespace separate manually is just bound to lead to diverging implementations and other sorts of trouble. What about having a (if-cljs
(my-javascripty-form js/xyz 1 2)
(my-clojure-form xyz 1 2)) with the appropriate form and write the result to If we have a hook inside lein cljsbuild for users to add their own munging functions to walk |
I still like the idea of keeping both implementations in separate files; optionally compare top level public functions and their argument counts and print a warning when they differ. However, to expand on @lynaghk's idea, I see one big advantage in keeping both platforms in a Every platform would need to define the same set of meta-macros. For example, the This may also be simpler from an implementation point of view? Dynamically include the platform meta-macros, edit: this may also aid in solving the |
I may be starting to warm up to the .cljx file format. :) Using the (currently) unused file extension would prevent the files from being picked up as Clojure or ClojureScript, so they could reside in the classpath without breaking anything. Then they could be processed similarly to how crossovers are handled right now, except with far less ugliness. If the code was rewritten as part of the copying process, I think it would in fact solve the One interesting thought: this could be made very general if the cljx transformations were configured via a sort of middleware stack. I'll be at Clojure West this week, maybe this is something to discuss over a beer! |
I hadn't thought of it that way, but yeah---something like middleware is pretty much what I'd like. I'll look for your amorphous fractal-green face at Clojure/West. |
Implemented my (very simple) take on this issue here: https://github.com/lynaghk/cljx |
How should we handle language runtime and platform between Clojure and ClojureScript?
One option for handling platform differences is to duplicate namespaces across clj and cljs.
In
maths.cljs
:and in
maths.clj
Then use Clojure as usual and in ClojureScript just let the cljs version of the namespace get picked up (don't list
maths
in the crossovers).That feels like a lot of unnecessary juggling for a LISP though; perhaps we should take advantage of metadata to mark platform-specific functions and provide alternatives all in the same file?
I've also run into problems with differences in the language runtimes.
For instance, in Clojure:
but in ClojureScript:
Is there anything we can do to crossover Clojure code like this automatically within lein-cljsbuild?
It's probably easier to make the changes in ClojureScript itself, but maybe there is a reason ClojureScript's protocols have slightly different names than Clojure's (pinging @how should we handle language runtime and platform between Clojure and ClojureScript?
One option for handling platform differences is to duplicate namespaces across clj and cljs.
In
maths.cljs
:and in
maths.clj
Then use Clojure as usual and in ClojureScript just let the cljs version of the namespace get picked up (don't list
maths
in the crossovers).That feels like a lot of unnecessary juggling for a LISP though; perhaps we should take advantage of metadata to mark platform-specific functions and provide alternatives all in the same file?
I've also run into problems with differences in the language runtimes.
For instance, in Clojure:
but in ClojureScript:
Is there anything we can do to crossover Clojure code like this automatically within lein-cljsbuild?
It's probably easier to make the changes in ClojureScript itself, but maybe there is a reason ClojureScript's protocols have slightly different names than Clojure's (pinging @swannodette).
The text was updated successfully, but these errors were encountered: