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

David Alayachew davidalayachew at gmail.com
Mon Jan 15 18:19:13 UTC 2024


Hello Magnus,

Thank you for closing my bug! Terribly sorry to ask another favor, but
could you link the following link for traceability in the JBS submission?

https://mail.openjdk.org/pipermail/amber-dev/2024-January/008488.html

Thank you again for the time and help!
David Alayachew

On Mon, Jan 1, 2024 at 1:26 AM David Alayachew <davidalayachew at gmail.com>
wrote:

> Hello all,
>
> After reading through Brian Goetz's "Effect cases on Switch"
> (specifically, the "Other switch tricks" section), I have decided to not
> implement this feature after all. The fact is, switch expressions,
> especially with "when-clauses", does a better job of clarifying intent than
> this feature does. Sure, there is slightly more verbosity, but the intent
> of this feature was never to minimize the character count, it was to
> increase clarity. And as is, switch expressions with when clauses
> accomplish that better.
>
> Here is a link to the subsection of the abovementioned article --
> https://inside.java/2023/12/15/switch-case-effect/#other-switch-tricks
>
> Could someone help me close this on JBS? Or should it just not be closed
> at all?
>
> Here is a link to the JBS -- https://bugs.openjdk.org/browse/JDK-8319802
>
> Thank you for your time and help!
> David Alayachew
>
> On Thu, Nov 9, 2023 at 1:19 AM David Alayachew <davidalayachew at gmail.com>
> wrote:
>
>> 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/core-libs-dev/attachments/20240115/989be71c/attachment-0001.htm>


More information about the core-libs-dev mailing list