The function() method is a great technique, it's now in Functions and FailableFunction (git master).
I'll see later if it can be used within Lang. I know I can use it in other projects. Wrt an API for a vararg of functions that implements chaining internally, I'm not so sure. I've though I needed something like that in past, but I've always ended up with other coding patterns I found better at the time for whatever reason.. Gary Gary On Fri, Aug 4, 2023, 3:24 PM Gary Gregory <garydgreg...@gmail.com> wrote: > 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 >> >>