core.matrix icon indicating copy to clipboard operation
core.matrix copied to clipboard

ClojureScript support

Open podviaznikov opened this issue 11 years ago • 41 comments

Is it possible to implement this library in ClojureScript? Or at least some parts of it.

podviaznikov avatar Nov 20 '13 21:11 podviaznikov

ClojureScript support should certainly be possible in core.matrix.

Some general points:

  • The API should work for both Clojure and ClojureScript, with virtually no modification.
  • Likewise the protocols that support the API should also work for both ClojureScript
  • The implementations will generally need to be different, as they will depend on host-specific interop and/or libraries

Getting this done will need someone reasonably proficient in ClojureScript to take it on as a project. If anyone is interesting in doing this, let me know (on this issue or by email) and I'm happy to help give some guidance.

mikera avatar Nov 21 '13 00:11 mikera

I'm happy to work on this. Would wrangling the protocols with http://sylvester.jcoglan.com/ work?

zcaudate avatar Nov 25 '13 11:11 zcaudate

Possibly - I'm not too familiar with Sylvester. Other options that it might make sense to implement the protocols for:

  • raw Javascript arrays (analogous to how we handle double[] and Object[] arrays in JVM core.matrix)
  • The Google Closure matrix library (http://docs.closure-library.googlecode.com/git/class_goog_math_Matrix.html)
  • An NDArray implementation - possibly the current NDArray can be made to work with JavaScript?

mikera avatar Nov 25 '13 16:11 mikera

There is a js implementation of ndarray here: https://github.com/mikolalysenko/ndarray

I think the goog.matrix and Sylvester are strictly 2d. Are the protocols for n-dimensional arrays?

There is http://www.numericjs.com/ which looks pretty nice and it is for native js arrays. The benchmarks look interesting http://www.numericjs.com/benchmark.html

zcaudate avatar Nov 25 '13 19:11 zcaudate

Looks like there are some good implementation options! My suggestion would be to try and get two or three of them working, it's fairly easy to implement just the mandatory protocols.

The protocols are designed to handle N-dimensional arrays, but you can implement them for 2D arrays and have the implementations fall back to other implementations for different dimensionalities. For example, Clatrix currently only supports 2D matrices natively (although it used a trick of wrapping a 2D matrix to implement 1D vectors as well).

mikera avatar Nov 26 '13 16:11 mikera

Okay. that's great. I'm going to go with js-ndarray then. Its the most well thought out of all of them:

http://0fps.wordpress.com/2013/05/22/implementing-multidimensional-arrays-in-javascript/

is there a project namespace/name that I should just? Else I'll just name it as cljs-ndarray

On 27/11/2013, at 3:58 AM, Mike Anderson [email protected] wrote:

Looks like there are some good implementation options! My suggestion would be to try and get two or three of them working, it's fairly easy to implement just the mandatory protocols.

The protocols are designed to handle N-dimensional arrays, but you can implement them for 2D arrays and have the implementations fall back to other implementations for different dimensionalities. For example, Clatrix currently only supports 2D matrices natively (although it used a trick of wrapping a 2D matrix to implement 1D vectors as well).

— Reply to this email directly or view it on GitHub.

zcaudate avatar Nov 26 '13 21:11 zcaudate

Hmmm... looking at the source of js-ndarray, it is written for node.js. Node has its own packaging system which is really quite nice.

The ndarray implementation uses some sort of compilation process https://github.com/mikolalysenko/ndarray/blob/master/ndarray.js

as well and the operations build on top of them: https://github.com/mikolalysenko/cwise/blob/master/cwise.js

There is a way to turn node code into browser code through browserify - http://browserify.org/. I'm not too concerned as I'm targeting node but it may be for other people

zcaudate avatar Nov 26 '13 22:11 zcaudate

If you can, it would be good to minimise the number of dependencies if possible (e.g. on Node), to make it easier for people to run the implementation on different platforms / clients.

It probably makes sense for the ClojureScript implementations themselves to have their own repo. This gives us more flexibility around releases, naming conventions etc, and means that they can have separate dependencies as appropriate (Clatrix and vectorz-clj have their own repos for similar reasons)

In the main core.matrix repo itself, the main thing to figure out is how to define the API / protocols in a way that works for both Clojure and ClojureScript. I think this will need some kind of proof of concept.

mikera avatar Nov 27 '13 02:11 mikera

hmmm... in that case, I'll port the code over. It'll take a bit longer but it should be worth it.

zcaudate avatar Nov 27 '13 21:11 zcaudate

I think it should also be possible to extend current NDArray implementation to support CLJS. I've tried to implement NDArray in a way that will make translation to CLJS easier: most of the code uses very primitive stuff like aset and aget, and backend-specific details like type hints are mostly wrapped in macros (here clojure.core.matrix.impl.ndarray-macro). There are few Java calls like java.utils.Array/copy, but they can be replaced with macros.

The problem here is that, being core.* lib, core.matrix can't depend on cljx. However, it's still possible to copy an entire namespace into .cljs using macro.

si14 avatar Nov 27 '13 21:11 si14

That could work. We can copy it manually too =) Or another option is lein-dalap to generate the .cljs file

There are also a couple of java-specific things hanging about in protocols.clj. Can that be refactored somehow?

zcaudate avatar Nov 27 '13 21:11 zcaudate

I'm interested in using core.matrix functionality in the browser and I'm curious if there's been movement on this front not reflected in this ticket. I'd like to help, but I'll be slow since I'm not very familiar with core.matrix internals or ClojureScript yet.

nyx avatar Mar 13 '14 14:03 nyx

I've been slack and haven't looked at it for a while, but i do remember thinking that the protocols file may have to be refactored for cljs in order to get started. But this was half a year ago.

On 14/03/2014, at 1:13, Andrew Andkjar [email protected] wrote:

I'm interested in using core.matrix functionality in the browser and I'm curious if there's been movement on this front not reflected in this ticket. I'd like to help, but I'll be slow since I'm not very familiar with core.matrix internals or ClojureScript yet.

— Reply to this email directly or view it on GitHub.

zcaudate avatar Mar 13 '14 21:03 zcaudate

I'm not aware of anyone having a serious go at this yet (i.e. I don't think there are any working core.matrix implementations on ClojureScript yet, unless someone is hiding something?)

My view is that it all should be possible, but will need quite good knowledge of the internal workings of both Clojure and ClojureScript to make it work smoothly.

Also it needs a really good design to make sure it coexists nicely with core.matrix JVM version. My suggested approach would be:

  • Refactor the API and protocols to make them ClojureScript friendly.
  • Create a core.matrix.cljs library that contains the ClojureScript specific implementations, and depends on the standard core.matrix for the API and protocol definitions

I'm happy to support this effort / provide advice, but someone else needs to drive it forward as it isn't really a priority for me right now.

mikera avatar Mar 22 '14 04:03 mikera

would it be possible to share the main code (ie the protocol definitions, etc) between clojure and clojurescript with tools like cljx https://github.com/lynaghk/cljx ?

On Sat, Mar 22, 2014 at 5:28 AM, Mike Anderson [email protected]:

I'm not aware of anyone having a serious go at this yet.

My view is that it should be possible, but will need quite good knowledge of the internal workings of both Clojure and ClojureScript to make it work smoothly.

Also it needs a really good design to make sure it coexists nicely with core.matrix JVM version. My suggested approach would be:

  • Refactor the API and protocols to make them ClojureScript friendly.
  • Create a core.matrix.cljs library that contains the ClojureScript specific implementations, and depends on the standard core.matrix for the API and protocol definitions

I'm happy to support this effort / provide advice, but someone else needs to drive it forward as it isn't really a priority for me right now.

Reply to this email directly or view it on GitHubhttps://github.com/mikera/core.matrix/issues/81#issuecomment-38342733 .

mschuene avatar Mar 22 '14 10:03 mschuene

Possibly cljx would work. I haven't experimented with it. It would need to work with Maven builds (that's what core.matrix uses, and it is a clojure contrib requirement too...) - any idea if it does this?

mikera avatar Mar 22 '14 14:03 mikera

This is almost certainly too beta right now, but it would be amazing if core.matrix could eventually wrap the new WebCL standard to make use of the GPU for matrix computations...

https://www.khronos.org/news/press/khronos-releases-webcl-1.0-specification

xcthulhu avatar Mar 30 '14 14:03 xcthulhu

We could just have separate .cljs sources, optimized for JS. core.async does it too afaik.

skrat avatar Aug 20 '14 19:08 skrat

@xcthulhu this looks possible. It should just be another core.matrix implementation

mikera avatar Aug 21 '14 01:08 mikera

@skrat that could make sense. Although I'd quite like the public API to be shared.... it makes things like maintaining consistent docstrings much easier!

mikera avatar Aug 21 '14 02:08 mikera

Unfortunately it seems that core.async duplicates a lot of code, while in core.matrix a lot can be reused. That makes me incline toward using cljx.

skrat avatar Aug 21 '14 13:08 skrat

@skrat, @si14 says above that cljx cannot be used, because this is a core.* library. I wonder if this constraint is still true.

nybbles avatar Oct 04 '14 19:10 nybbles

I don't think it is, I'm not aware of any law mandating that cljx cannot be used. It would be used during the publish phase anyway, and thus there wouldn't be any dependency in the published jar.

skrat avatar Oct 05 '14 17:10 skrat

Has there been any progress on this?

gleenn avatar Aug 16 '15 22:08 gleenn

Nobody has created any patches that I'm aware of. Anyone want to take a shot at it?

I think I'm happy with either cljx or separate cljs files. This mostly applies to just the clojure.core.matrix API namespace itself, since the implementations will generally need to be separate.

My only firm requirement is that it mustn't mess up the standard build/ release process, i.e.:

  • I still need to be able to do mvn release:prepare and mvn release:perform to create a release.
  • Tests need to test both Clojure and ClojureScript side

mikera avatar Aug 17 '15 00:08 mikera

cljx was superseded by reader conditionals in Clojure 1.7. I don't see any reason why should it change the build/release process. The conversion should be fairly simple. Fast matrix storage and operations should be implemented with Javascript's typed arrays.

skrat avatar Aug 24 '15 09:08 skrat

Currently we still need to support Clojure 1.6, so I think that rules out reader conditionals right now.

mikera avatar Aug 24 '15 14:08 mikera

I have a .cljc port in progress. Trying to find the core issues with a port to JS runtime. There are more issues than I previously thought. To have this done would require a lot of willpower from the maintainers. I don't expect this to happen before the Clojure 1.6 requirement is out of the way.

skrat avatar Aug 24 '15 16:08 skrat

@skrat Can you share a link to your repo?

mikera avatar Aug 24 '15 23:08 mikera

Hi all I see an interesting opportunity to get ClojureScipt support using the NDArray implementation here: https://github.com/thi-ng/ndarray

The author @postspectacular would be happy with a PR that implements core.matrix support (although we would need to get the ClojureScript-side protocols working first...)

See this issue for context and discussion::

https://github.com/thi-ng/ndarray/issues/1

mikera avatar Oct 12 '15 01:10 mikera