3 ms·
The GWT team has been working on a next-gen compiler that transpiles directly to readable, JsDoc typed ES6, designed for high levels of optimization by the Clos
by cromwellian 11y ago
The GWT team has been working on a next-gen compiler that transpiles directly to readable, JsDoc typed ES6, designed for high levels of optimization by the Closure Compiler. Because of the new JsInterop system was designed for GWT 2.8, that is shared by both GWT and this new compiler, low impedance interop between Java and JS will be possible, as well as a tool that reads WebIDL and typescript libraries, and generates Java types.
As an example if the level of low impedance between the languages, consider the @JsFunction annotation,
@JsType(isNative = true)
interface EventTarget {
void addEventListener(String event, EventListener listener);
}
@JsFunction
interface EventListener {
void onEvent(Event event);
}
Using Java8, you can write code like:
document.createElement("button").addEventListener("click", x -> Console.log("Hello World"));
The difference between GWT running this, and the new compiler, is that the output of the new compiler is a standard ES6 module.
The JSweet claims about GWT are out of date. First of all, in-browser Java debugging has been available for years. GWT was in fact, the very first transpiler to leverage Chrome source maps. I demoed this three years ago (https://www.youtube.com/watch?v=-xJl22Kvgjg https://www.youtube.com/watch?v=-xJl22Kvgjg)
Secondly, GWT has a "reversible and compatible" JsInterop system that provides full two way low-impedance bidirectional interop, you can even do things like subclass JS objects from Java, or define "fields" via @JsProperty which invoke methods ala Object.defineProperty()
Third, the JSweet stuff looks like it doesn't obey standard JLS semantics. Does it even compile the JRE or Guava? This is absolutely vital for code sharing between platforms (e.g. server, Android, j2objc). If you can't run standard JLS semantics, there's little point to writing the code in Java in the first place.
- amican 11y agoHow can you tell it's disobeying standard JLS semantics?
- cromwellian 11y agoI looked at the source. Doesn't seem to support class initialization properly. It models lambdas as just arrow functions, which won't work if you try to pass them as Objects to other Java functions (where is Object.getClass()/hashCode()/equals() ?) It doesn't handle runtime checks of Java interfaces at all, for example: interface Foo {} class FooImpl implements Foo {} Object o = new FooImpl(); if (o instanceof Foo) -> compile error The inability to even handle Java interfaces should be a clue right off the bat that this won't compile any non-trivial Java code base.
- renaudpawlak 11y agoClass initialization is handled with semantics that approach the Java ones so that it is not confusing for programmers. AFAIK it works but in case it doesn't I'd be curious to know what's wrong. Lambdas are meant to be used like in JavaScript. It totally works. JSweet supports function references (MyClass::myFunction) and defines the JS Function object for passing plain object functions. No need for getClass(), hashCode() or equals() in JavaScript. Regarding interfaces, the situation is quite different. JSweet does not support interfaces in the way Java supports interfaces. JSweet interfaces are mapped to TypeScript interfaces which are pure compile-time entities used only for typing (which differ strongly from Java's). That's why the code you quote will not compile in JSweet, but it does not mean that JSweet is wrong: it means that your way of understanding an interface in JSweet is wrong (unlike Java, JSweet interfaces have no runtime representation). This part requires further documentation though... JSweet is a very young project. Generally speaking, when you program with JSweet, you have to stop thinking too much in terms of Java semantics, and start thinking more in TypeScript or JavaScript, at least for some cases. The very most of it remains close to Java and very intuitive to programmers, since IMO, Java and TypeScript are quite in the same language family.
- jevinskie 11y agoIs there any story for using GWT to go from Java to LLVM bitcode/IR? RoboVM just closed source, and VMKit is dead along with DragonEgg (maybe GCJ had a hope of working at some time?). I guess I'm looking for a sort of GWT + reverse Emscripten? Too bad the LLVM bits of ART were discarded.
- cromwellian 11y agoThere is j2objc, which is a sister project to the new compiler. J2ObjC is the compiler behind Google Inbox and Google Spreadsheets on iOS. It doesn't go to LLVM, it goes straight to ObjC/C. You can then import this into any XCode project.
- daveidol 11y agoHey Ray! Glad to see the GWT team is still making strides :)
- stickfigure 11y agoIf you can't run standard JLS semantics, there's little point to writing the code in Java in the first place. I'm an old user of GWT and hopeful for its revival, but I strongly disagree with this statement. There are two ways of going about this - one is to hew closer to Java semantics (the GWT approach), the other is to hew closer to Javascript semantics. Strict JLS semantics is great for bulk compiling huge projects, but sucks for interop. In the new GWT, does Long become a javascript number? In the old GWT it was an opaque object, which was a constant irritant when interacting with JS. There is room for both approaches, but as a web developer, I need to interop with JS frameworks more than I need to compile Quake.
- cromwellian 11y agoDo you need java.lang.Object and java.lang.String to work properly? Do you need Java interfaces and 'instanceof' to even work? We're not talking about 100% JLS semantics, but if you can't even compile code that utilizes java.lang.* and java.util.*, why not just use Kotlin, Dart, Typescript, and other languages provide high level typed JS like languages. Using a language that doesn't compile properly leads to all kinds of nasty surprises and hard to diagnose bugs.
- skybrian 11y agoEmulation is a matter of degree. There are certainly many places where GWT takes a shortcut or doesn't support a feature compared to a real Java VM. But the idea is to get it right for most of the code a Java developer is likely to write, so you have a chance of writing portable code and getting it to work everywhere without a wholesale rewrite. In particular, mapping Java longs to doubles doesn't make sense. If it's your own code, why are you using long instead of int (or double) which perform much better and interoperate well with JavaScript? If it's someone else's code, how do you know it doesn't need the full 64-bit range?
- stickfigure 11y agoIt makes a ton of sense when working with identifiers, which is so common that it's almost the standard usage of java.util.Long. In most practical applications you can safely assume that identifiers are not going to use the full 64 bit range. And being able to pass them to javascript frameworks is incredibly useful - which is to say, the inability to use them in JS was incredibly frustrating with GWT.
- renaudpawlak 11y agoIf JSweet claims about GWT are inaccurate they will be fixed. But you have to understand that JSweet is a syntax mapper to TypeScript (explained here: http://www.jsweet.org/papers-and-publications/ http://www.jsweet.org/papers-and-publications/). So they are really different techniques. With JSweet, what you see is what you get. There is a direct correspondence between the written Java code and the output TS/JS, and that for ALL the program (not only fractions of it). So we are probably not always referring to the same features and certainly not the same ways of doing things, which probably explains some misunderstanding in JSweet assertions about GWT. JSweet is not meant to obey JLS because JSweet is "just" Java syntax. It is not Java anymore. However, some specific transformations (very few) have been implemented so that Java programmers are not confused by JavaScript runtime behavior (as explained here for instance: http://www.jsweet.org/language-specifications/#Variable_scoping_in_lambda_expressions http://www.jsweet.org/language-specifications/#Variable_scop...). JSweet is not meant to be at all compatible with Java legacy APIs. With JSweet, you will not even be able to access the Java Object API nor the Java String API. Instead you directly access the Object and String JS APIs. So who cares about JLS semantics then? What JSweet is trying to compile is JavaScript applications, not Java, and the examples show that it works for not-that-trival code. In short, JSweet is for writing real JavaScript applications in a Java compile-time environment (not runtime). Nothing more, nothing less. I understand that GWT new generation it aiming somewhat at integrating JS apis too... But AFAIK, JSweet is the first project to give access to hundreds of JavaScript libraries in Java thanks to the TypeScript to Java API translator.