I'm not sure the "nested" example API is quite what it should be, because
the last argument is the default value, you cannot make the input functions
a vararg, which seems very limiting. I should be able to use the same API
whether I need to go 1, 2, or N functions deep. I'm saying the above
independently of whether this type of code should be in Lang.

Gary

On Sat, Aug 5, 2023, 9:27 AM Daniel Watson <dcwatso...@gmail.com> wrote:

> Nice.
>
> Sounds like everyone is leaning towards "no". Would it be worth submitting
> a PR to include more usage examples - which I assume could also serve as a
> place to collect more feedback? Or just keep it within this thread given
> the way it's leaning? (or unless that consensus changes)
>
> Ultimately in my web/UI project the reduction (after using function(...))
> is something like...
>
> Failable.asFunction(Parent::getChild)
> .andThen(Optional::ofNullable)
> .andThen(o -> o.map(Child::getGrandChild))
> .andThen(o-> o.map(GrandChild::getName).orElse(defaultValue));
>
> vs my util method
>
> FunctionUtils.nested(Parent::getChild, Child::getGrandChild,
> GrandChild::getName, defaultValue);
>
> So it's still a big difference in clarity for me, given how often its used.
> FWIW - My project is using Vaadin, and this util function is used to bind
> nested bean properties to Vaadin input fields. On that note - In addition
> to the bean "getter" binding, it also uses a similar util method to bind
> bean "setter" methods - because input fields obviously need access to both.
> The setter util call looks similar, with the last argument being
> a BiConsumer...
>
> FunctionUtils.nested(Parent::getChild, Child::getGrandChild,
> GrandChild::setName);
>
> Although in general this code does not reference any Vaadin specific
> functionality, the overall use case may be quite specific to those needs,
> so all of these utilities may be better suited to a utils class within a
> vaadin specific library.
>
> Dan
>
> On Fri, Aug 4, 2023 at 9:11 PM Gary Gregory <garydgreg...@gmail.com>
> wrote:
>
> > 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