I posed this question briefly in this post here:  
https://groups.google.com/d/msg/clojure/K65Va0rCCls/Ow5bAJ_YTGIJ.  In this 
real world example of porting Korma over to ClojureCLR, I encountered the 
following things:

   - One namespace which handled JDBC interaction needed to be rewritten 
   completely to target ADO.NET
   - Another namespace required a few minor changes, only one of these 
   (changing .indexOf to IndexOf) was platform specific

Korma is a library that is probably exceptional in its avoidance of 
platform specific features in most namespaces.  Porting something like 
swank would not have been so easy.  In general, I would say that for this 
library, I would prefer to use the platform specific folder approach - i.e 
having two namespaces korma.platform.db and korma.platform.util in src-jvm/ 
and src-clr/ folders.  Then there could be a CLR specific project.clj 
(maybe project.clr.clj) sitting next to the JVM project.clj (and eventually 
maybe a project.py.clj).  Each project.clj would reference the correct 
platform specific folder in addition to the shared src/ folder.  Just off 
the top of my head, the reasons for supporting this approach are:

   - It forces the developer to isolate platform specific code into 
   manageable units that can be 1) more easily ported to another platform, 2) 
   easily maintained, and 3) tested in isolation for compatibility
   - There is no need for one clojure dialect to know about the whereabouts 
   or contents of code for another dialect.  This would seem to be unnecessary 
   overhead.

While I can see why it might be nice to be able to quickly add some 
metadata to distinguish this platform specific code while keeping 
everything in one file, as other have mentioned, I would encourage people 
to think about the downsides of this.  Say, I had just taking korma.db and 
put some conditionally compiled CLR code alongside the JVM code.  The file 
doubles in size.  Would I then want the py team to do the same?  Also, for 
the one .indexOf -> IndexOf change, say there are little changes like that 
all over the place.  Would a team adding a new port want to go through the 
whole source tree and find every instance of this?  Without modifying the 
clojure compilers we have now, the platform specific directory approach 
will work and is probably cleaner.  It just requires team consensus on 
adopting this approach.

One thing, I would propose is adding some build tool awareness of this so 
that maybe an NLein or PyLein could use the same project.clj and just see 
:platform-clr, :platform-py, :platform-jvm attributes.  Or this could be 
done by having a shared project.shared.clj included by each platform 
specific project file.  These types of approaches might be simpler and more 
maintainable in the long run.

Aaron
On Thursday, April 12, 2012 12:56:59 PM UTC-4, tbc++ wrote:
>
> I've been thinking lately how to seamlessly merge clojure-py and
> clojure-jvm code in the same packages. This is something I know has
> been discussed in the past, but I'm just looking for
> ideas/brainstorming on how we can solve this problem.
>
> Let's begin by explaining the problem. Let's assume that my project
> needs a platform specific way to convert a int to a string:
>
> On clojure-jvm:
>
> (defn to-string [i] (.toString Integer i))
>
> On clojure-py:
>
> (defn to-string [i] (py/str i))
>
> On Clojurescript:
>
> (defn to-string [i] (.toString i))
>
>
> We could do this inline (inside a common .clj file):
>
> (for-platform "jvm"
>                   (defn to-string [i] (.toString Integer i))
>                   "python"
>                   (defn to-string [i] (py/str i))
>                   "js"
>                   (defn to-string [i] (.toString i)))
>
> But this gets ugly real fast.
>
> My idea, would be to provide some sort of hook to the compiler, that
> would be cross-platform. The compiler, when looking for a namespace,
> would find all files in a given folder that match the required
> namespace:
>
> /test/to_string.clj
> /test/to_string.cljpy
> /test/to_string.cljs
> /test/to_string.cljclr
>
> These function hooks would then pick the best entry based on the
> extension, defaulting to .clj if no better option exists. Since these
> functions could be composable it would be possible to also dispatch on
> platform versions:
>
> /test/to_string.cljpy26       ; Python 2.6 code
> /test/to_string.clj7            ; JVM 7 code
>
> It seems to me that this would be a very clean way to allow clojure
> programs to be cross-platform. The side-effect is that it would force
> non-standard code out into separate namespaces where they can be
> easily maintained. If someone wanted to port the project to a new
> platform, he would need only to find existing platform overrides, and
> create new entries.
>
>
> Thoughts?
>
> Timothy Baldridge
>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Reply via email to