In fact, <T> T walk(Function<Stream<StackFrame>, T> function, …) - without ? extends T change,
You can do: Function<Stream<StackWalker.StackFrame>, String> funct; CharSequence chars = sw.walk(funct, i -> i); I think it’s right to declare the return type of the function is "? extends T”. Mandy > On Oct 31, 2015, at 5:01 PM, Timo Kinnunen <timo.kinnu...@gmail.com> wrote: > > Hi, > > Regarding “ > I was pondering it and that’s why not changed in the last update. I agree > with the upper bounded wildcard "? extends T” for the return type of the > function. > “ > > How does changing the type from “T” to “? extends T” aid the method caller in > any way? If the caller has a Function like this: > > Function<Stream<StackWalker.StackFrame>, String> funct; > > but they wished they could have walk use T=CharSequence instead, then they > can simply assign the value returned from walk to a CharSequence variable: > > String result = sw.walk(funct, i -> i); > CharSequence chars = result; > > > Isn’t “? extends T” pointless here? > > > > > > Sent from Mail for Windows 10 > > > > From: Mandy Chung > Sent: Saturday, October 31, 2015 23:59 > To: Remi Forax > Cc: core-libs-dev@openjdk.java.net > Subject: Re: Proposed API for JEP 259: Stack-Walking API > > > > > On Oct 31, 2015, at 11:29 AM, Remi Forax <fo...@univ-mlv.fr> wrote: > > > > Hi Mandy, > > I've crawled the code and the documentation again. > > > > In the doc and in the code, a lambda with one parameter doesn't require > > parenthesis around the parameter, > > (s) -> s.doSomething() > > should be > > s -> s.doSomething(). > > > > Oh right. (It didn’t look right to me but didn’t pay attention to it). > > > > > In the doc of StackWalker, > > in the first example, the local variable 'frame' should be named > > ‘callerClass' > > > > Fixed > > > > In the doc of getCallerClass(), > > the first example do a skip(2) which i believe is not necessary anymore, > > It has to skip two frames. Use the second example, the stack looks like this: > > StackWalk::getCallerClass > Util::getResourceBundle > Foo::init > : > : > > > also instead of Optional.orElse, orElseGet is better because it avoids to > > evaluate > > Thread.currentThread().getClass() if not necessary. > > > > So the example should be: > > walk(s -> s.map(StackFrame::getDeclaringClass) > > .findFirst()).orElseGet(() -> > > Thread.currentThread().getClass()); > > > > This would return Util.class instead of Foo.class > > > In the second example, the field walker should be declared 'final’. > > Sure. Fixed. > > > > > And as i said earlier, the signature of walk() is: > > <T> T walk(Function<? super Stream<StackWalker.StackFrame>, ? extends T> > > function, IntUnaryOperator batchSizeMapper) > > > > I was pondering it and that’s why not changed in the last update. I agree > with the upper bounded wildcard "? extends T” for the return type of the > function. > > But for the function’s input argument, can you help me understand why it > should take "? super Stream<StackWalker.StackFrame>”? Is it useful to have > function accepting supertype of Stream<StackFrame> rather than > Stream<StackFrame>? VM should be the only source producing this StackFrame > stream. > > On the other hand, I wonder if the stream argument should be Stream<? extends > StackFrame> that may allow future implementation change. > > <T> T walk(Function<Stream<? extends StackWalker.StackFrame>, ? extends T> > function, …) > > Mandy