Worth adding adding function(Function)? Seems low cost to add it FailableFunction.
Gary On Fri, Aug 4, 2023, 2:04 PM Rob Spoor <apa...@icemanx.nl> wrote: > With just one simple utility method you can get all the chaining you want: > > public static <T, R> Function<T, R> function(Function<T, R> func) { > return func; > } > > This doesn't look very useful, but it allows you to turn a method > reference or lambda into a typed Function without needing a cast. After > that it's really simple using what's provided in the Java API: > > Function<MyBean, String> func = function(MyBean::getChild) > .andThen(Child::getName); > > You want a default value? Almost just as easy: > > someFrameworkThing.setProperty(function(ParentBean::getChild) > .andThen(ChildBean::getName) > .andThen(Optional::ofNullable) > .andThen(o -> o.orElse("defaultName")); > > > On 04/08/2023 16:04, Daniel Watson wrote: > > Asking for comments and thoughts on a potential new feature. Already > > developed in a commons-like style, but dont want to submit PR without > > discussion as it may be considered out of scope or too use case specific. > > > > Justification and details... > > > > I've run into a scenario a few times where nested lamba functions would > be > > incredibly useful. e.g. > > > > MyBean::getChild::getName > > > > Obviously this is not a language feature, but can be simulated in a > useful > > way. So far my use has mostly been related to code that works with POJO > > beans, and frameworks that use function references to understand those > > beans and properties. Specifically useful where the context of the code > > block is the parent entity, but you need to reference a child, and > without > > nested lambdas you end up with things like the below... > > > > ParentBean parentBean = new ParentBean(); > > parentBean.setChild(new ChildBean("name")); > > //imagine that FrameworkThing is a generic class, and thus the generic > type > > is ParentBean > > FrameworkThing someFrameworkThing = new FrameworkThing (ParentBean.class) > > //but we need to get to a property of a child bean > > someFrameworkThing.setProperty((parentBean) -> { > > > > return parentBean.getChild().getName(); > > > > }); > > > > Obviously this could be handled with a getChildName() method on the > parent > > bean, but that has pitfalls as well (e.g. bean class cannot be changed, > or > > adding of properties interferes with other usage of the class e.g. JPA, > > JAX). However with a util class the second call can be reduced to > > something like below, leaving the bean API untouched. > > > > > someFrameworkThing.setProperty(FunctionUtils.nested(ParentBean::getChild,ChildBean::getName)); > > > > Taken alone, that single reduction may seem trivial, but in a scenario > > where these nested references are commonly needed, the reduction makes > the > > code clearer (In my opinion), as it is immediately apparent on a single > > line of code that the reference is a simple nested property, rather than > > having to interpret an inline lambda function. It also discourages errant > > placement of code by avoiding the inline function (since the only purpose > > of the lambda was to retrieve a single nested value). In addition, If > > intermediate nulls need to be handled then the reduction becomes more > > apparent, as the null checks can be handled in the util class rather than > > cluttering the app code. e.g. > > > > > someFrameworkThing.setProperty(FunctionUtils.nested(ParentBean::getChild,ChildBean::getName,"defaultName")); > > //or... > > > someFrameworkThing.setProperty(FunctionUtils.nested(ParentBean::getChild,ChildBean::getName,null)); > > > > The third parameter here is a String (typed genetically based on the > return > > type of getName) and indicates the default value to be returned if the > > first call to getChild() returns null. e.g. it replaces something like... > > > > someFrameworkThing.setProperty((parentBean) -> { > > > > ChildBean cb = parentBean.getChild(); > > if(cb == null) return null; //or other default value > > else return cb.getName(); > > > > }); > > > > Given that commons-lang aims to extend existing language features, this > > seemed like a reasonable place for a nested lambda util class. So far my > > concerns are... > > > > 1. Does this feel too specific to an application to warrant > inclusion in > > commons? (For me it has been useful enough to place into a common > library, > > but commons-lang has a broader scope) > > 2. If not commons-lang, is there some other commons library that > this is > > more suited to? > > 3. There are still wrinkles that may prove complex and potentially > > overly specific e.g. exception handling. Does that potential > complexity > > make it not worth adding? > > 4. Assuming the features discussed here *are* valuable, Is handling > only > > java.util.Function a complete-enough feature? Or is it useless > unless it > > also attempts to handle BiFunctions - which become increasingly > complex > > (potentially unfeasible) to implement - i.e. is it too big a feature > to > > consider including? > > > > If folks feel like this is a solid "no" let me know. If the devil is in > the > > details and we need to see the PR first I can do that as well. > > > > Dan > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org > >