2

Ideally, a common interface or type would allow code compiled to both JS and JVM to make use of a fast Array type without the need to use a buffer. Presumably the fastest array type in Scala.js is a js.Array (resizable) and on the JVM it is the Array (not resizable), so Array does not really work here.

It could be that type classes are the way to go here, but that may be overkill. Still, if it is the best solution, I'd be interested to know.

Another possible solution that comes to mind, that would require a fair bit of collaboration though maybe not a lot of effort, would be to get the new Scala Collections API to agree on an API for just this purpose (although it would not be limited to libraries used on the JS and JVM). It could possibly end up being a restricted view of an existing Array implementation in Scala collections for the JVM, assuming no performance penalties would be incurred with such an approach.

4
  • 2
    scala.collection.Seq is a common interface for js.Array and scala.Array. What else do you want? Commented Aug 1, 2017 at 2:11
  • 1
    It is probably worth noting here that in Scala.js, scala.collection.mutable.Buffer (and ArrayBuilder) are backed by a js.Array. Commented Aug 1, 2017 at 11:11
  • Aha, I was looking at ArrayBuffer, which I gather is not backed by a js.Array, but by developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… Commented Aug 1, 2017 at 12:17
  • You mean scala.scalajs.js.typedarray.ArrayBuffer? That is not backed by a JS ArrayBuffer, it is a JS ArrayBuffer. If you need an interoperable type that is backed by a typed array (in JS), you can use a direct ByteBuffer. See TypedArrayBuffer for access. Commented Aug 2, 2017 at 4:34

1 Answer 1

4

As @sjrd already pointed out, if you are just concerned about the interfaces, all the normal Scala collection interfaces work.

If you are concerned about efficiency, it is worth noting, that in Scala.js, we back a scala.Array by a js.Array (plus some RTTI). So if you use an scm.ArrayBuilder it will essentially boil down to a simple JS Array:

import scala.collection.mutable.ArrayBuilder

val builder = ArrayBuilder.make[Int]

builder += 1
builder += 2
builder += 3

println(builder.result())

Will, after optimization, give you (Scala.js 0.6.19, Scala 2.11.11)

var elems$2 = null;
elems$2 = [];
elems$2.push(1);
elems$2.push(2);
elems$2.push(3);

// builder.result()
var x = $makeNativeArrayWrapper($d_I.getArrayOf(), elems$2);

// println(...)
var this$6 = $m_s_Console$();
var this$7 = $as_Ljava_io_PrintStream(this$6.outVar$2.v$1);
this$7.java$lang$JSConsoleBasedPrintStream$$printString__T__V((x + "\n"))
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.