Convert a reversed array to a java.math.Biginteger in java - biginteger

I'm trying to write a Java code equivalent of the below Javascript code
(convert JS to Java)
JavaScript Code (it reverses an Array and converts to/forms a Big Integer to the base decimal):
var decimal=bigInt.fromArray(binArr.reverse(), 2);
Java code I tried:
BigInteger bigint1=new BigInteger(Collections.reverse(Arrays.asList(a)),2);
(using a syntax I saw online,but I couldnt proceed anything beyond that)
Could you provide some inputs on this?

Related

Bug? JsNumber toFixed returns different values in SuperDev and JS

I'm using GWT 2.8.2.
When I run the following code in SuperDev mode, it logs 123.456, which is what I expect.
double d = 123.456789;
JsNumber num = Js.cast(d);
console.log(num.toFixed(3));
When I compile to JavaScript and run, it logs 123 (i.e. it does not show the decimal places).
I have tried running the code on Android Chrome, Windows Chrome and Windows Firefox. They all exhibit the same behavior.
Any idea why there is a difference and is there anything I can do about it?
Update: After a bit more digging, I've found that it's to do with the coercion of the integer parameter.
console.log(num.toFixed(3)); // 123 (wrong)
console.log(num.toFixed(3d)); // 123.456 (correct)
It seems that the JsNumber class in Elemental2 has defined the signature as:
public native String toFixed(Object digits);
I think it should be:
public native String toFixed(int digits);
I'm still not sure why it works during SuperDev mode and not when compiled though.
Nice catch! This appears to be a bug in the jsinterop-generator configuration used when generating Elemental2's sources. Since JS doesn't have a way to say that a number is either an integer or a floating point value, the source material that jsinterop-generator works with can't accurately describe what that argument needs to be.
Usually, the fix is to add this to the integer-entities.txt (https://github.com/google/elemental2/blob/master/java/elemental2/core/integer_entities.txt), so that the generator knows that this parameter can only be an integer. However, when I made this change, the generator didn't act on the new line, and logged this fact. It turns out that it only makes this change when the parameter is a number of some kind, which Object clearly isn't.
The proper fix also then is probably to fix the externs that are used to describe what "JsNumber.toFixed" is supposed to take as an argument. The spec says that this can actually take some non-number value and after converting to a number, doesn't even need to be an integer (see https://www.ecma-international.org/ecma-262/5.1/#sec-15.7.4.5 and https://www.ecma-international.org/ecma-262/5.1/#sec-9.3).
So, instead we need to be sure to pass whatever literal value that the Java developer provides to the function, so that it is parsed correctly within JS - this means that the argument needs to be annotated with #DoNotAutobox. Or, we could clarify this to say that it can either be Object or Number for the argument, and the toFixed(Object) will still be emitted, but now there will be a numeric version too.
Alternatively, you can work around this as you have done, or by providing a string value of the number of digits you want:
console.log(num.toFixed("3"));
Filed as https://github.com/google/elemental2/issues/129
The problem is that "java" automatically wraps the int as an Integer and GWT end up transpiling the boxed Integer as a special object in JS (not a number). But, if you use a double, the boxed double is also transpiled as a native number by GWT and the problem disappears.
I'm not absolutely sure why this works in super-devmode, but it should not. I think that the difference is that SDM maps native toString to the Java toString, and (even weirder) the native toFixed call the toString of the argument. In SDM the boxed-interger#toString returns the string representation of the number which ends up coercing back to int, but in production, the boxed-interger#toString returns "[object Object]", which is handled as NaN.
There is a special annotation #DoNotAutobox to being able to use primitive integers in JS native APIs. This prevents integer auto-wrap, so the int is transpired to a native number (example usage in the Js#coerceToInt method). Elemental2 might add this annotation or change the type to int as you suggest. Please, create an issue in the elemental2 repo to fix this (https://github.com/google/elemental2/issues/new).

Working with opaque types (Char and Long)

I'm trying to export a Scala implementation of an algorithm for use in JavaScript. I'm using #JSExport. The algorithm works with Scala Char and Long values which are marked as opaque in the interoperability guide.
I'd like to know (a) what this means; and (b) what the recommendation is for dealing with this.
I presume it means I should avoid Char and Long and work with String plus a run-time check on length (or perhaps use a shapeless Sized collection) and Int instead.
But other ideas welcome.
More detail...
The kind of code I'm looking at is:
#JSExport("Foo")
class Foo(val x: Int) {
#JSExport("add")
def add(n: Int): Int = x+n
}
...which works just as expected: new Foo(1).add(2) produces 3.
Replacing the types with Long the same call reports:
java.lang.ClassCastException: 1 is not an instance of scala.scalajs.runtime.RuntimeLong (and something similar with methods that take and return Char).
Being opaque means that
There is no corresponding JavaScript type
There is no way to create a value of that type from JavaScript (except if there is an #JSExported constructor)
There is no way of manipulating a value of that type (other than calling #JSExported methods and fields)
It is still possible to receive a value of that type from Scala.js code, pass it around, and give it back to Scala.js code. It is also always possible to call .toString(), because java.lang.Object.toString() is #JSExported. Besides toString(), neither Char nor Long export anything, so you can't do anything else with them.
Hence, as you have experienced, a JavaScript 1 cannot be used as a Scala.js Long, because it's not of the right type. Neither is 'a' a valid Char (but it's a valid String).
Therefore, as you have inferred yourself, you must indeed avoid opaque types, and use other types instead if you need to create/manipulate them from JavaScript. The Scala.js side can convert back and forth using the standard tools in the language, such as someChar.toInt and someInt.toChar.
The choice of which type is best depends on your application. For Char, it could be Int or String. For Long, it could be String, a pair of Ints, or possibly even Double if the possible values never use more than 52 bits of precision.

Why is this Coffeescript invalid?

I'm playing around with Coffeescript, trying to convert a JavaScript file to Coffeescript. This is valid JavaScript:
element(by.model('query.address')).sendKeys('947');
This is invalid Coffeescript:
element(by.model('query.address')).sendKeys('947')
What is invalid about the Coffeescript? Coffeelint says "unexpected BY".
CoffeeScript uses the by keyword to let you use a specific step when looping through a range.
From the documentation:
To step through a range comprehension in fixed-size chunks, use by, for example:
evens = (x for x in [0..10] by 2)
Since JavaScript doesn't use by it's valid. For CoffeeScript, try renaming the by to something else.
In response to the comment, since Protractor provides its own by global variable, one idea is to alias it via CoffeeScript's embedded JavaScript syntax (code surrounded by back-ticks), then continue using CoffeeScript and the alias throughout your code.
You'll need to test this type of code:
ptorBy = `by`
element(ptorBy.model('query.address')).sendKeys('947')
Where ptor is just my short-hand for "Protractor." This translates to the following JavaScript:
var ptorBy;
ptorBy = by;
element(ptorBy.model('query.address')).sendKeys('947');

Embedding XML (and other languages?) in Scala

I'm wondering how the scala.xml library is implemented, to get an Elem-instance out of XML.
So I can write:
val xml = {
<myxml>
Some wired text withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
</myxml>
}
xml.text
String =
"
Some text wired withoud "'s or code like
import x
x.func()
It's like a normal sting in triple-quotes.
"
A look at the source code doesn't gave me the insight, how this is achieved.
Is the "XML-detection" a (hard) scala language feature or is it an internal DSL? Because I would like to build my own things like this:
var x = LatexCode {
\sqrt{\frac{a}{b}}
}
x.toString
"\sqrt{\frac{a}{b}}"
or
var y = PythonCode {
>>> import something
>>> something.func()
}
y.toString
"""import something ..."""
y.execute // e.g. passed to python as python-script
or
object o extends PythonCode {
import x
x.y()
}
o.toString
"""import x...."""
I would like to avoid using such things like PythonCode { """import ...""" } as "DSL". And in scala, XML is magically transported to a scala.xml-Class; same with Symbol which I can get with val a = 'symoblname, but in the source code there's no clue how this is implemented.
How can I do something like that on myself, preferably as internal DSL?
XML is a scala language feature (*) - see the SLS, section 1.5.
I think that string interpolation is coming in 2.10, however, which would at least allow you to define your own DSL:
val someLatex = latex"""\sqrt{\frac{a}{b}}}"""
It's an experimental feature explained more fully in the SIP but has been additionally blogged about by the prolific Daniel Sobral. The point of this is (of course) that the correctness of the code in the String can be checked at compile time (well, to the extent possible in an untyped language :-) and your IDE can even help you write it (well, to the extent possible in an untyped language :-( )
(*) - We might expect this to change in the future given the many shortcomings of the implementation. My understanding is that a combination of string interpolation and anti-xml may yet be the one true way.
It's an XML literal, just like "foo" is a string literal, 42 is an integer literal, 12.34 is a floating point literal, 'foo is a symbol literal, (foo) => foo + 1 is a function literal and so on.
Scala has fewer literals than other languages (for example, it doesn't have array literals or regexp literals), but it does have XML literals.
Note that in Scala 2.10 string literals become vastly more powerful by allowing you to intercept and re-interpret them using StringContexts. These more powerful string literals would allow you to implement all of your snippets, including XML without separate language support. It is likely that XML literals will be removed in a future version of the language.

Java Hashmap and Mutlidimensional array type sig in JSNI?

I've got a method JSNI that calls a Java method that take a Hasmap as input.
I've tried
handler.#com.mypackage::myMethod(Ljava/util/Hashmap;)(myHashMap);
handler.#com.mypackage::myMethod(Ljava/util/Hashmap<Ljava/lang/String,Ljava/lang/String>;)(myHashMap);
I'm can't seem to define the correct type signature to include the Strings or find if this usage is even allowed.
Since I'm doing this in gwt I though it might be the implementation of hashmap and the alternative approach I've though takes a String[][] array as input
I was hoping for somwthing like
handler.#com.mypackage::myMethod([[Ljava/lang/String;)(myArray);
However, I hit another issue of finding the correct JNSI sntax for the 2nd dimension of the array
A single dimension array ie. [Ljava/lang/String; is fine but I need the 2nd dimension.
Any help/ideas or links to good jnsi doc appreciated.
I think you're running into type erasure. Every generic object parameter is really just java.lang.Object at runtime. I don't believe generics are exposed to JNI.
I've written JNI code but never attempted to use generic types from native code so I'm not certain. Googling has turned up no specific references or examples.
See Java VM Type Signatures for a reference to the type signatures used in JNI (and JSNI)
However, you may not need to pass a Java HashMap to Javascript anyway. Instead, consider using JSONObject and passing a native JavaScript object to your javascript code. It looks like this:
public void callFoo() {
JSONObject obj = new JSONObject();
obj.put("propertyName", new JSONString("properyValue"));
JavaScriptObject jsObj = obj.getJavaScriptObject();
nativeFoo(jsObj);
}
public native void nativeFoo(JavaScriptObject obj) /*-{
$wnd.alert(obj['propertyName']);
}-*/;
This gets compiled to roughly:
var obj = {'propertyName': 'propertyValue'};
$wnd.alert(obj['propertyName']);
Can you post the error that your getting, and also what kind of javascript object your trying to pass as a hashmap. I'm assuming you're getting a compile time error?
Here is a good start for JSNI documentation:
GWT JSNI doc
GWT Blog post on JSNI
Ok, after looking at it...
I was unable to find any documentation or arrangement that gives the multidimensional array of strings.
Managed to get this done using the HashMap, using:
handler.#com.mypackage::myMethod(Ljava/util/Hashmap;)(myHashMap);
worked if I define the input without defining the types. Such as:
HashMap myHashMap = new HashMap();
This gives the JSNI a HashMap of type <Object, Object>.
I'm then handling the object on the other side by casting the contents of the hashmap into strings.
Thanks to rusty for the links:
GWT JSNI doc -
This is good for getting the correct formatting of primitives
GWT Blog post on JSNI -
Hadn't seen this blog before