I agree with all of that.

If you are extracting and writing jvm, py, clr, cljs interop as a means to 
enable portability, then you are effectively writing extensions to the core 
clojure platform libs. 

I.e providing a base, in a similar way that, for example, clojure.string 
extends common string operations across platforms.

It is the capability of the core platform that enables portability.

It's a double edged sword though and there are certainly many cases where 
it does not make sense.

I think that there are a couple of areas where core extensions for 
portability might be useful.

I have used this for cljs and jvm with:
1. math, as above
2. string -> numeric parsing, (although the reader can be used too)
3. logging - but only in simple cases for debugging.
4. exceptions - but only in very limited form

I find that beyond these - I can pretty much get away with completely 
generic code. 
The only challenge then is how to get the platform specific and generic 
files to the relevant compiler in a clean and standard, rather than ad-hoc 
manner. (lein cljs-build et al)

Dave


On Sunday, 15 April 2012 02:42:27 UTC+10, Kevin Lynagh wrote:
>
> I have no idea what, if anything, Clojure the language(s) *should* do 
> about this issue, but I can explain the reasoning behind CLJX. 
>
> CLJX uses the reader to statically analyze toplevel forms in a file 
> and generate new ones according to declarative rewrite rules. 
> The motivating use case was to make the C2 data visualization library 
> work on both Clojure and ClojureScript. 
>
> C2's source is spit across 
>
> src/cljx ;;most of the code 
> src/clj  ;;Clojure-specific 
> src/cljs ;;ClojureScript-specific (i.e., DOM manipulation code) 
>
> and most of the cljx files only have one or two platform metadata 
> annotations. 
> Any namespace which uses macros has two ns forms to accomidate 
> ClojureScript's :use-macros syntax. 
>
> I explicitly wanted a solution where code for different platforms 
> would be in the same file because it eases the burden on the 
> maintainer to ensure consistency between implementations. 
> That makes sense when the differing implementations are very small: 
>
> (defn ^:clj log10 [x] (Math/log10 x)) 
> (defn ^:cljs log10 [x] (/ (.log js/Math x) 
>                           (.-LN10 js/Math))) 
>
> and I agree with Dave in that it could get unwieldy fast if you try to 
> mix larger implementation-specific functions together. 
>
> If I wanted to write something cross-platform, I'd start by defining 
> the needed foundation (beyond what is provided by the Clojure 
> runtimes, e.g., "str"), write those platform-specific functions 
> completely separate from each other, and then write the shared Clojure 
> code that implements the bulk of the functionality. 
> The CLJX solution works nicely with C2 because 90% of C2 code 
> manipulates Clojure data structures only. 
> There are relatively few implementation details that need to be 
> papered over. 
>
> Clojure was designed to be a hosted language, and it's very easy to 
> reach out to the underlying platform. 
> If you don't need to do that and can get by with Clojure/core---great, 
> your code will be portable. 
> However, if you use libraries and facilites native to the host 
> platform, then you're not writing Clojure so much as you are writing 
> Clojure+Java or Clojure+JavaScript. 
> If that's the case, just have separate projects with a shared spec or 
> test suite and not worry about mashing it all together with compiler 
> or pre-processing tricks. 
>
> On Apr 13, 10:06 am, Aaron <aaroncrael...@gmail.com> wrote: 
> > 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