New method on java.util.function.Function -- ternary method

David Alayachew davidalayachew at gmail.com
Thu Nov 9 06:19:44 UTC 2023


Oh, I will also add a specialized version of this method to
java.util.function.UnaryOperator. That is because UnaryOperator is a
subinterface of Function. Function goes T -> R, but UnaryOperator just goes
T -> T. We do not want UnaryOperator to have the T -> R static function
included due to inheritance, so it will get its own version that has the
same method name and parameters, but the type parameters will be different.

Here is another mockup - this time for UnaryOperator2's version of the same
method.

> interface UnaryOperator2<T> extends Function2<T,T>, UnaryOperator<T>
> {
>
>     public static <T> UnaryOperator2<T> ternaryApply
>     (
>         Predicate<? super T> test,
>         Function<? super T, ? extends T> trueFunction,
>         Function<? super T, ? extends T> falseFunction
>     )
>     {
>
>         return
>             (T input) ->
>                 test.test(input)
>                     ? trueFunction.apply(input)
>                     : falseFunction.apply(input)
>                     ;
>
>     }
>
> }

On Thu, Nov 9, 2023 at 12:12 AM David Alayachew <davidalayachew at gmail.com>
wrote:

> It has been a month since I sent this proposal. Since no one has told me
> that this is a terrible idea, I will submit this as an enhancement to JBS,
> and once the ticket is made, start work on creating a pull request.
>
> On Tue, Oct 3, 2023 at 3:13 AM David Alayachew <davidalayachew at gmail.com>
> wrote:
>
>> Whoops, bad import.
>>
>> Please replace the following line with the one after it.
>>
>> > import java.util.function.Function;
>>
>> > import java.util.function.*;
>>
>> On Tue, Oct 3, 2023 at 3:09 AM David Alayachew <davidalayachew at gmail.com>
>> wrote:
>>
>>> Hello all,
>>>
>>> I have an idea that I want to run by you all -- a new method on
>>> java.util.function.Function to capture ternary operations.
>>>
>>> Here is a mockup of what I wanted to do.
>>>
>>> >
>>> > import java.util.function.Function;
>>> >
>>> > @FunctionalInterface
>>> > public interface Function2<I, O> extends Function<I, O>
>>> > {
>>> >
>>> >    public static <I, O> Function<I, O> ternary
>>> >    (
>>> >        Predicate<I> test,
>>> >        Function<I, O> trueOutput,
>>> >        Function<I, O> falseOutput
>>> >    )
>>> >    {
>>> >
>>> >       return
>>> >           (I input) ->
>>> >               test.test(input)
>>> >               ? trueOutput.apply(input)
>>> >               : falseOutput.apply(input)
>>> >               ;
>>> >
>>> >    }
>>> >
>>> > }
>>> >
>>>
>>> I think this is useful for a few reasons.
>>>
>>>  * This composes, just like the ternary operator itself.
>>>
>>>  * It pairs well with Function.identity() and method references to
>>> clearly (but concisely) communicate intent.
>>>
>>>  * Ternary operations are common, so this will find great use by
>>> developers of all sorts.
>>>
>>> There is at least one part I don't quite like about this design - what
>>> if one (or both!) of your outputs is not a functional transformation of the
>>> input?
>>>
>>> For example, String username = id.isBlank() ? "UNKNOWN" : lookup(id);
>>>
>>> Obviously, this is easy to work around - simply ignore the input of the
>>> function. But you lose clarity and simplicity that way. I would put a note
>>> in the javadoc that says that this method should only be used in instances
>>> where both outputs are a functional transformation of the input. That way,
>>> intent is clarified. But if we go that route, maybe this function should
>>> get a better name to capture that? testThenApply? ternaryTransform?
>>> ternaryApply?
>>>
>>> Thank you for your time and help!
>>> David Alayachew
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/discuss/attachments/20231109/0e9ae419/attachment.htm>


More information about the discuss mailing list