Can JSweet viably port Java libraries for use in cross-built Scala.js projects?

你说的曾经没有我的故事 提交于 2019-12-11 00:31:43

问题


In the search for ways to make Java libraries accessible to both the JavaScript and JVM sides of Scala.js cross-built projects, please consider the following experiment:

Imagine that a Scala.js project needs advanced matrix math capabilities such as Singular Value Decomposition. Although the JavaScript world has Numeric.js and the JVM world has many options, JAMA not least among them, no cross building Scala.js solution exists at the time of this question's formulation.

What options do we have?

  1. Write anew or port a matrix library for Scala.js.
  2. Wrap Numeric.js facades and JAMA into a common Scala.js interface.
  3. Write facades for Numeric.js, then compile it with Nashorn for JVM support.
  4. Transpile JAMA to JavaScript with JSweet and fashion appropriate Scala.js facades.

This question reflects option 4.

After reconditioning JAMA for the JSweet transpiler, publishing the transpiled JavaScript as a CommonJS module through npm, and writing Scala.js facades for the CommonJS module, Scala code can now access Jama on the JVM side, and a port of it on the JS side.

Unfortunately, the core data structure on the JVM side has type: double[][], Array[Array[Double]] in Scala syntax, but JSweet converts it to the JavaScript array type, js.Array[js.Array[Double]] in Scala.js syntax.

Now, from the Scala.js cross built perspective, two identically named, equivalently functional, but utterly distinct and separate libraries exist.

From Scala syntax, we can construct the 3D identity matrix on the JS side as so:

new Matrix(
  js.Array[js.Array[Double]](
    new js.Array[Double](1.0, 0.0, 0.0),
    new js.Array[Double](0.0, 1.0, 0.0),
    new js.Array[Double](0.0, 0.0, 1.0)
   )
 )

On the JVM side, we write:

new Matrix(
  Array[Array[Double]](
    new Array[Double](1.0, 0.0, 0.0),
    new Array[Double](0.0, 1.0, 0.0),
    new Array[Double](0.0, 0.0, 1.0)
  )
)

How could we unify these two implementations?

Is there a trick to equate js.Array and Array?

Would you suggest an entirely different approach to make Java libraries accessible to cross-built Scala.js projects?


回答1:


Let me start with the easy question:

Is there a trick to equate js.Array and Array?

No, there is no such "trick". Those data structures are fundamentally different. js.Array's length is variable, and can be patched with additional properties. Array is Java's fixed-length array. If there was any way to equate them, Scala.js would have done that for you, like it does for Double and number.

One relatively easy way to unify the APIs would be to rebuild the API of JAMA in Scala.js code, where every class is a wrapper for the facaded JS class coming from the JSweet-compiled library. This allows the Scala-level API of JAMA to be exactly equivalent between Scala/JVM and Scala.js. It does require some amount of code writing to replicate the APIs, but at least the body of the methods need not be rewritten.

A completely different approach, very radical and requiring an insane amount of man·hours would be fork the JSweet compiler to emit Scala.js IR (.sjsir) files instead of .js files. That way, you could link the JSweet-generated .sjsir files for JAMA together with the Scala.js-generated .sjsir files for your application. This would give the maximum performance, since the Scala.js optimizer would be able to optimize across the app/library border.




回答2:


A recipe for porting Java libraries to Scala.js:

  1. Procure Java source code.
  2. Strip out IO and other JSweet incompatible functionality.
  3. Compile it with JSweet as a Node.js module.
  4. Hand roll a package.json file and publish the JSweet transpiler output on npm.
  5. Add ScalaJS-bundler to a cross compiled Scala.js project; include the CommonJS module from step five.
  6. Include the Java version in the JVM dependencies of build.sbt.
  7. Write a Scala.js facade for the CommonJS module.
  8. Write a wrapper for the Scala.js facade with the exact interface from the original Java library. Add in whatever IO and other JSweet incompatible functionality if Scala.js supports it.


来源:https://stackoverflow.com/questions/51033981/can-jsweet-viably-port-java-libraries-for-use-in-cross-built-scala-js-projects

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!