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

Reply via email to