JEP 276 proposed to target JDK 9 discussion (was: JEPs proposed to target JDK 9 (2015/11/5))

Attila Szegedi attila.szegedi at oracle.com
Thu Nov 12 11:03:04 UTC 2015


On Nov 12, 2015, at 10:19 AM, Rémi Forax <forax at univ-mlv.fr> wrote:
> 
> Java is a typechecked langage.
> As you said you 'can' use this proposed API offers a gate to access to artifacts of a dynamically typed languages but it's messy.

I wouldn’t call it messy but it’s certainly verbose in absence of compiler support.

> In C#, you can use the dynamic keyword to interropt with dynamic languages but you loose type checking and also box everything. That's not the only solution, you can also use interfaces to type values that goes back and forth between Java and your languages.

Nice thing about invokedynamic (and Dynalink) is that you don’t have to box everything. If your call site has primitive parameter types or return value, and the method handle it ends up being linked to has similar signature, parameters/return values end up being pass-through (or subjected to widening primitive conversion). Of course, a primitive return value is only appropriate if the code would otherwise immediately coerce it to that type…

> From the point of view of javac the methods of these interfaces are compiled using invokedynamic which link to the runtime of the dynamically typed languages associated with the interfaces.

I’m not sure if I follow your train of thought; but I did think a lot about whether Dynalink approach is equivalent in expressive power to declaring an interface and having objects implement it. (Because if it is, it’d be simpler to go that route.) In the end, I realized that linker composition is is more powerful than that, and is actually even more powerful than interface injection (which we also currently don’t have in the platform). Nashorn specifically can do nice things like:
- Adding binding support to anything that can be linked for a CALL operation (by delegating a linker call to the unbound object and then binding the resulting method handles and linking those into the call site). This could be solved with just interfaces.
- Adding support for NEW operation to a StaticClass in its own internal linker (and thus allow the “new Runnable() { … }” idiom in the language) without StaticClass ever being aware of it. This could be solved with interface injection.
- It optimizes linking of CALL operation on “Function.call” e.g. in f.call(this, args…) to actually linking the call to “f” directly (similarly f.apply()). This is an example of a functionality that goes beyond even interface injection. The code for linking these came out as naturally recursive, so even something monstrous like Function.call(Function.call, Function.call, f, this, args…) will link the outermost () operator directly to a CALL on “f” (with appropriately constructed guards, of course).

> As i said, or should, this JEP is great, it solves the problem of interropt between dynamically typed languages but it doesn't tackle the problem of interropt with statically typed languages, Java the language or others, that runs on the Java Platform.
> 
> I don't want to put this JEP on hold

Thank you; that’s great to hear.

> but just says that this JEP only solve a part of the interropt problem.

Yes, you’re right about that.

Best Regards,
  Attila.

> 
> regards,
> Rémi
> 
> Le 6 novembre 2015 11:58:20 CET, Attila Szegedi <attila.szegedi at oracle.com> a écrit :
>>> On Nov 6, 2015, at 12:47 AM, Remi Forax <forax at univ-mlv.fr> wrote:
>>> 
>>> Let me be the devil advocate.
>> 
>> Thank you. Let me address these concerns.
>> 
>>> One problem i see with JEP 276 is that it makes Java the Language a
>> second class citizen because unlike with the other dynamic languages,
>> javac will not emit the invokedyanmic calls.
>>> Obviously, given the fact that Java is the elephant in the room, the
>> picture is inversed, all dynamically typed language that run on the JVM
>> will still be second class citizens.
>> 
>> Only in the sense that programs written in Java language can’t call
>> into a dynamic language with any special Java syntax; emphasis on
>> special syntax. You can use Dynalink from Java by creating CallSite
>> objects explicitly, letting them be linked by Dynalink and invoking
>> their dynamicInvoker. Nashorn does it when its Java code needs to call
>> back into JavaScript, see the InvokeByName class[1] or
>> Bootstrap.createDynamicInvoker[2]. It’s certainly not less convenient
>> than directly programming against any language runtime’s own Java-side
>> API, and gives you interop with all Dynalink-using languages, not just
>> one. (It actually allows you dynamic POJO linking too from within
>> Java.)
>> 
>> The whole notion of “second class citizen language” is highly
>> debatable. This JEP significantly improves the support of non-Java and
>> specifically languages with dynamic types on the JVM. They will not be
>> worse off than before, and I argue that they will, in fact, be much
>> better off (see immediately below).
>> 
>>> It seems this JEP stops in the middle of the river, making this JEP,
>> in my opinion, not very useful.
>> 
>> There’s a pretty large sandbank in the river that’s worth getting to
>> first. It provides a way for a dynamic language to 
>> 1. conveniently link to its own object model, while at the same time
>> 2. link to Java object model with no additional work, and
>> 3. link to object models of other languages with no additional work,
>> and
>> 4. let other languages link its own object models with no additional
>> work.
>> 
>> For lots of language implementers points 1 and 2, the benefit of
>> handling their own object model *and Java* at the same call site is a
>> tremendous value proposition. Points 3 and 4, cross-language interop is
>> usually less prominently on their minds, but if it comes for free… As a
>> matter of fact, we were contacted on Nashorn mailing list in the past
>> by people saying they wanted to integrate their language with Nashorn
>> but couldn’t since Dynalink was in jdk.internal.* package, so at least
>> for some that’s important too.
>> 
>>> Dynamic languages will interoperate with the others but Java will not
>> interoperate with them.
>> 
>> That’s the only part that’s on the other side of your metaphorical
>> river. Except, see above, you can actually do it, just not with a
>> convenient syntax. Adding a “dynamic” type to Java would be a pretty
>> big language feature, with a lot of ripple effects (it affects the type
>> system, after all) and I believe it is better to do it as a separate
>> step, not in the least as it’s a JCP level change. It’s not a done deal
>> that it will actually happen. (It would be a perfectly valid JCP
>> consensus outcome that members would rather not have a dynamic type in
>> Java.)
>> 
>> I actually wrote a document some years ago with an initial speculation
>> on what would Java with dynamic type look like on top of Dynalink[3].
>> There’s several moving parts involved there, up to and including how do
>> you associate a javac-compiled .class with a DynamicLinker instance. 
>> 
>>> So for a dynamic language runtime, encoding callsites using the
>> proposed scheme is a constraint with not so much benefit
>> 
>> Purely as a technical sidenote, I dispensed with a mandatory encoding
>> scheme recently[4].
>> 
>>> JRuby can already calls Nashorn because both can use Java as a
>> bridge.
>> 
>> How can they use Java as a bridge? If you’re referring to writing code
>> in Nashorn to the JRuby object interfaces or vice versa, that’s hardly
>> more convenient than using Dynalink from Java with explicit CallSites.
>> (I’d argue the latter is actually more convenient.)
>> 
>>> Moreover, if you compare how dynamically typed languages that run on
>> the JVM are supported by Java compared to statically typed languages,
>> Fortran or C++ by example, they will soon have better support from Java
>> because they will be able to use the C bridge defined by project
>> Panama.
>> 
>> Progress being made in supporting natively compiled language runtimes
>> is hardly an argument against progress being made in supporting
>> JVM-hosted language runtimes.
>> 
>>> So instead of defining how dynamically typed languages can interop
>> with each others, i think it's a better to define how Java can leverage
>> invokedynamic to call any dynamically typed languages in a typesafe
>> way.
>> 
>> This strikes me as a false dichotomy as JEP 276 is not just about
>> dynamic languages cross-interop, as I enumerated above. (Also, what do
>> you mean by “typesafe way” in relation to dynamically typed languages?)
>> 
>>> All dynamically typed languages will be free to reuse the same
>> mechanism to interroperate with each others, the JEP 276 should be
>> defined on top of that mechanism.
>> 
>> I see your point. You argue that we should first have a
>> Java-to-dynamicLanguages solution in place and then express JEP 276 on
>> top of it. However, for this to work, you’d need to define the target
>> API of the dynamic languages that Java could be linking against, and
>> I’m saying it’d look very much like what JEP 276 defines.
>> 
>> More importantly, it hinges on Java actually getting a dynamic type,
>> which is a very big “if”.
>> 
>> On the other hand I say that JEP 276 provides a
>> dynamicLanguages-to-anything solution (exactly the opposite direction),
>> and that Java language can be made to be on the “anything” end *if*
>> dynamic type is introduced into Java. 
>> 
>> Either way, we'd end up with a bridge over the river, it’s just a
>> question what direction we start building it from. The part I propose
>> is already built internally and would be genuinely useful without being
>> dependent on Java also getting a dynamic type.
>> 
>> Attila.
>> 
>>> 
>>> cheers,
>>> Rémi
>> 
>> [1]
>> http://hg.openjdk.java.net/jdk9/dev/nashorn/file/34b77a618e98/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/InvokeByName.java
>> <http://hg.openjdk.java.net/jdk9/dev/nashorn/file/34b77a618e98/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/InvokeByName.java>
>> [2]
>> http://hg.openjdk.java.net/jdk9/dev/nashorn/file/34b77a618e98/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java#l262
>> <http://hg.openjdk.java.net/jdk9/dev/nashorn/file/34b77a618e98/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/linker/Bootstrap.java#l262>
>> [3]
>> https://github.com/szegedi/dynalink/wiki/What-if-Java-had-dynamic-type%3F
>> <https://github.com/szegedi/dynalink/wiki/What-if-Java-had-dynamic-type?>
>> [4] In the preliminary spec API I published for review two weeks ago[5]
>> as announced in an e-mail to core-libs[6], you can see that I dispensed
>> with a mandatory encoding scheme in favor of operations expressed as
>> objects (see Operation interface). Both the producer of the encoding
>> (.class emitter) and its consumer (the bootstrap method) are presumed
>> to be in the same language runtime, so it’s not necessary for a
>> specification to prescribe how do they pass information among
>> themselves. The bootstrap method is responsible to decode information
>> from its parameters into operation objects which then need to be
>> understood by all linkers. We switched to that in the internal code
>> version already, see the JIRA issue[7]).
>> [5] http://cr.openjdk.java.net/~attila/jep276/javadoc.20151022/
>> <http://cr.openjdk.java.net/~attila/jep276/javadoc.20151022/>
>> [6]
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-October/036052.html
>> <http://mail.openjdk.java.net/pipermail/core-libs-dev/2015-October/036052.html>
>> [7] https://bugs.openjdk.java.net/browse/JDK-8139931
>> <https://bugs.openjdk.java.net/browse/JDK-8139931>
>> 
>>> 
>>> ----- Mail original -----
>>>> De: "mark reinhold" <mark.reinhold at oracle.com>
>>>> À: jdk9-dev at openjdk.java.net
>>>> Envoyé: Jeudi 5 Novembre 2015 23:56:43
>>>> Objet: JEPs proposed to target JDK 9  (2015/11/5)
>>>> 
>>>> The following JEPs have been placed into the "Proposed to Target"
>>>> state by their owners after discussion and review:
>>>> 
>>>> 259: Stack-Walking API
>>>>      http://openjdk.java.net/jeps/259
>>>> 
>>>> 264: Platform Logging API and Service
>>>>      http://openjdk.java.net/jeps/264
>>>> 
>>>> 269: Convenience Factory Methods for Collections
>>>>      http://openjdk.java.net/jeps/269
>>>> 
>>>> 272: Platform-Specific Desktop Features
>>>>      http://openjdk.java.net/jeps/272
>>>> 
>>>> 276: Dynamic Linking of Language-Defined Object Models
>>>>      http://openjdk.java.net/jeps/276
>>>> 
>>>> Feedback on these proposals is more than welcome, as are reasoned
>>>> objections.  If no such objections are raised by 23:00 UTC next
>>>> Thursday, 12 November, or if they're raised and then satisfactorily
>>>> answered, then per the JEP 2.0 process proposal [1] I'll target
>> these
>>>> JEPs to JDK 9.
>>>> 
>>>> (This information is also available on the JDK 9 Project Page [2]).
>>>> 
>>>> - Mark
>>>> 
>>>> 
>>>> [1] http://cr.openjdk.java.net/~mr/jep/jep-2.0-02.html
>>>> [2] http://openjdk.java.net/projects/jdk9/
>>>> 
> 



More information about the jdk9-dev mailing list