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
>
>

Reply via email to