On Mon, 26 Oct 2020 18:33:11 GMT, Rémi Forax <github.com+828220+fo...@openjdk.org> wrote:
>>> …`dropReturn` seemed like a good choice since we already have >>> `dropArguments`. WRT changing to `MethodHandle::changeReturnType`... >> >> That's a very reasonable point. People might look for `dropRT` after they >> find `dropAs`. And `MHs` is designed as a large-ish set of utility methods. >> >> I agree that adding `MH::changeRT` is a slippery slope; it tends to lift >> more of the MT API onto MH, and it starts to put new stuff into the smaller >> MH API; that was my bad. >> >> But (in the spirit of brainstorming, and agreeing with your present >> proposal), I'll suggest a separate idea to think about. Use a HOFP API to >> give easy access to the entire `MT` API all in one go, by reifying the >> `MH.type` property as a temporary (lambda argument): >> >> MethodHandle mapType(MethodHandle mh, UnaryOperator<MethodType> fn) { >> return mh.asType(fn.apply(mh.type())); >> } >> >> This also suggests a possible argument transform utility, a sort of >> mini-version of Charlie Nutter's MH builder API: >> >> MethodHandle mapArguments(MethodHandle mh, >> UnaryOperator<List<ArgumentValue<?>>> fn) { >> var args = mh.type().argumentList().stream().map(t -> makeArg(t)).asList(); >> args = fn.apply(args); >> … do stuff to re-weave mh with the resulting argument transforms … >> } >> public sealed interface ArgumentValue<T> { >> Class<T> type(); >> <U> ArgumentValue<U> asType(Class<U> newType); >> … other stuff for pre-applying MHs … >> } > > instead of mapArguments(), i believe it's better to have a method map on a > MethodType that takes two mapping functions, one for the return type and one > for the prameter types. > > so one can write: > MHs.mapType(mh, mt -> mt.map(Function.identity(), t-> t.isPrimitive? t: > Object.class)) > to not change the return type and erase the parameter type to Object if they > are not primitives > > With that, changing the return type to void can be done that way too > MHs.mapType(mh, mt -> mt.map(__ -> void.class, Function.identity()) It's an interesting idea. It turns something like: target = target.asType(target.type().changeReturnType(void.class)); Into target = target.asType(mt -> mt.changeReturnType(void.class)); I.e. it removes the need to reference the target handle/type twice, which prevents them from potentially going out of sync (which seems more likely when you have multiple MethodTypes and MethodHandles flying around). Also, it feels unnecessary that, I have to re-specify `target`'s type as a base, when I'm asking `target` to change it's type. This also solves that. ------------- PR: https://git.openjdk.java.net/jdk/pull/866