Fwd: jsinterop: @JsFunction .length always 0

113 views
Skip to first unread message

Vassilis Virvilis

unread,
Jun 27, 2017, 4:09:34 AM6/27/17
to google-web-tool...@googlegroups.com
Ok guys this is the last one - I promise.

Originally posted in gwt-users.

Does this count as a bug or at least as a missing feature?

Thanks

---------- Forwarded message ----------
From: Vassilis Virvilis <vas...@gmail.com>
Date: Mon, Mar 6, 2017 at 4:08 PM
Subject: jsinterop: @JsFunction .length always 0
To: google-we...@googlegroups.com


Hi,

in D3 the bisect function takes a function that can be a comparator or an accessor.

D3 internall figures it out by counting provided function arguments length via f.length https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/length

Trying to pass a java @JsFunction fails because @JsFunction objects are lambda with zero arguments that wrap samMethod.apply() call

Any ideas? Should I file this as a bug?


--
Vassilis Virvilis



--
Vassilis Virvilis

Roberto Lublinerman

unread,
Jun 27, 2017, 12:41:03 PM6/27/17
to google-web-tool...@googlegroups.com
You can call it a missing feature. Clearly not a bug, not everything that can be done in JS is available from Java with interop. For these situations you probably want to have some JS stubs.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-web-toolkit-contributors/CAKbOjEx1_jOohikJ7nBAfpsE%3DJHtnD6M31PibMzjvcjLn7G1fw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Vassilis Virvilis

unread,
Jun 27, 2017, 5:28:56 PM6/27/17
to google-web-tool...@googlegroups.com
Do you want me to report it as issue? If so where?

Is it possible for @JsFunction magic to implement it some day? or it is impossible to be implemented with the current design?

Thanks again for all the answers so far.

    Vassilis

On Tue, Jun 27, 2017 at 7:40 PM, 'Roberto Lublinerman' via GWT Contributors <google-web-tool...@googlegroups.com> wrote:
You can call it a missing feature. Clearly not a bug, not everything that can be done in JS is available from Java with interop. For these situations you probably want to have some JS stubs.
On Tue, Jun 27, 2017 at 1:09 AM, Vassilis Virvilis <vas...@gmail.com> wrote:
Ok guys this is the last one - I promise.

Originally posted in gwt-users.

Does this count as a bug or at least as a missing feature?

Thanks

---------- Forwarded message ----------
From: Vassilis Virvilis <vas...@gmail.com>
Date: Mon, Mar 6, 2017 at 4:08 PM
Subject: jsinterop: @JsFunction .length always 0
To: google-web-toolkit@googlegroups.com


Hi,

in D3 the bisect function takes a function that can be a comparator or an accessor.

D3 internall figures it out by counting provided function arguments length via f.length https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/length

Trying to pass a java @JsFunction fails because @JsFunction objects are lambda with zero arguments that wrap samMethod.apply() call

Any ideas? Should I file this as a bug?


--
Vassilis Virvilis



--
Vassilis Virvilis

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsu...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis

Thomas Broyer

unread,
Jun 28, 2017, 3:51:56 AM6/28/17
to GWT Contributors
I suppose makeLambdaFunction could be "inlined" (possibly into a static factory, one per class), with the 'lambda' then generated with the proper number of formal arguments to "initialize" its 'length' property? Would that hurt "optimizability" a lot?
Or is that not worth it (too much of an edge case) and the static factory (of a wrapper function then) should rather be implemented with JSNI? (or the equivalent for j2cl)

Vassilis Virvilis

unread,
Jun 28, 2017, 8:21:16 AM6/28/17
to google-web-tool...@googlegroups.com
I am not following the implementation details and I cannot judge on the compromises front.

But from a user standpoint this should be implemented because a @JsFunction should generate a js function()  and a js function() happens to have a length member by specification (see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/length )

Otherwise @JsFunction is not a js function() but something callable instead.

Given the dynamic number of javascript I expect that these kind of checks to be common enough to warrant the effort.

Now if GWT generated script becomes 2x heavier and 4x slower you may forget the feature. It still needs to be posted as an issue to host the discussion though.

    Vassilis



To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsu...@googlegroups.com.

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis

Thomas Broyer

unread,
Jun 28, 2017, 9:12:09 AM6/28/17
to GWT Contributors


On Wednesday, June 28, 2017 at 2:21:16 PM UTC+2, Vassilis Virvilis wrote:
I am not following the implementation details and I cannot judge on the compromises front.

But from a user standpoint this should be implemented because a @JsFunction should generate a js function()  and a js function() happens to have a length member by specification (see https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Function/length )

Otherwise @JsFunction is not a js function() but something callable instead.

GWT generates a function, but a function with an empty formal parameter list (and as a result a length of 0), because it simply uses 'arguments': https://github.com/gwtproject/gwt/blob/2.8.1/dev/core/super/com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang/Runtime.java#L158-L169
 
Given the dynamic number of javascript I expect that these kind of checks to be common enough to warrant the effort.

One could argue the reverse: due to the dynamic nature of JS, 'length' of a function isn't reliable, and you'd be better off using distinct APIs rather than driving behavior by inferring things from inputs, or more precisely be explicit with your intent.
It easily fails you, as soon as you wrap a function to bind, curry, memoize it, whatever, using a generic factory (one that uses 'arguments' along with Function.prototype.apply or Function.prototype.call; one that specifically doesn't use Function.prototype.bind).
Have a look at the Function.prototype.bind polyfill from the MDN for example: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind#Polyfill
Any code targeting IE8 or older (that doesn't necessarily mean new code) would need this polyfill, and the returned function (fBound) has a length of 0, irrespective of the length of the function to bind.
There's a polyfill for Function.prototype.bind that returns a function with the correct 'length', but it uses new Function() with a string body: https://github.com/Raynos/function-bind/blob/83e639ff74e6cd6921285bccec22c1bcf72311bd/implementation.js#L38 so it'd break most CSP. While IE8 doesn't support CSP (so it's OK for this particular polyfill), that however means you cannot use such a trick for other things you'd like to do with a function (such as memoizing it: for example, https://github.com/caiogondim/fast-memoize.js returns a function with length 0 too).

Roberto Lublinerman

unread,
Jun 28, 2017, 12:57:23 PM6/28/17
to google-web-tool...@googlegroups.com
Not likely to be implemented in the foreseeable future; your best solution is to create two JavaScript methods (or JSNI)

function asAccessor(f) {
  return function (a) { return f(a); };
}

function asComparator(f) {
  return function (a, b) { return f(a, b); };
}

It would be possible to implement @JsFunction lambdas without a backing class and that would result in the function having the same number of parameters as the lambda. But as I said this is unlikely to be implemented in the foreseeable future as it would require a new Java AST node and thus changes throughout the code base.

On Tue, Jun 27, 2017 at 2:28 PM, Vassilis Virvilis <vas...@gmail.com> wrote:
Do you want me to report it as issue? If so where?

Is it possible for @JsFunction magic to implement it some day? or it is impossible to be implemented with the current design?

Thanks again for all the answers so far.

    Vassilis



--
Vassilis Virvilis

--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsu...@googlegroups.com.

Vassilis Virvilis

unread,
Jun 28, 2017, 4:22:51 PM6/28/17
to google-web-tool...@googlegroups.com
@thomas

all valid points and interesting links. Thanks for the insight.

To my defense however I want to state again that I have not devised this API.

It's the official API of D3

so it is not possible to change the API. If I take a step back (not realistic) and say that I won't use D3 at all because it has such a bad API (not true. Generally I enjoy the D3 very much.) I am sure I will hit similar snags in other js libraries.

So... better the devil you know....

     Vassilis


--
You received this message because you are subscribed to the Google Groups "GWT Contributors" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit-contributors+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis

Vassilis Virvilis

unread,
Jun 28, 2017, 5:05:29 PM6/28/17
to google-web-tool...@googlegroups.com
Yep I have done it like this exactly but this creates a JSNI dependency. My reports were assuming that JSNI is a soon to be deprecated thing or at least further investment on it is should be avoided.

However, thanks for the development insight.



For more options, visit https://groups.google.com/d/optout.



--
Vassilis Virvilis
Reply all
Reply to author
Forward
0 new messages