[External] : Re: Casting gatherer

Viktor Klang viktor.klang at oracle.com
Mon Apr 28 15:58:53 UTC 2025


In this case, it is rather straight-forward to experiment—given Gatherers—and be able to make progress on ergonomics without waiting for the standard library to offer a built-in.


Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle
________________________________
From: Nir Lisker <nlisker at gmail.com>
Sent: Monday, 28 April 2025 13:21
To: Viktor Klang <viktor.klang at oracle.com>
Cc: core-libs-dev at openjdk.org <core-libs-dev at openjdk.org>
Subject: [External] : Re: Casting gatherer

Hi Viktor,

stream.filter(myClass:isInstance).map(myClass:cast)

is indeed the current way of doing it. I've written this code many times and I suspect others have too. An extracted version might reside in many utility classes. This is why I suggested having a Gatherer for it in Gatherers. I've written a naive implementation:

private static <T, R> Gatherer<T, ?, R> filterCast(Class<R> type) {
    return Gatherer.of(
        (_, element, downstream) -> {
            if (type.isInstance(element)) {
                return downstream.push(type.cast(element));
            }
            return true;
        }
    );
}

which we might start seeing in gatherer libraries.

We don't need to be able to write 'x instanceof T', although it would be useful in many cases. It's a discussion for Valhalla. Valhalla will also allow us to use this for "non-class based" elements when generics over primitives arrive, so this gatherer is no different than the others.

As noted above, Amber might offer solutions too. Obviously, lower-level solutions from Valhalla and Amber are preferable, but I don't know what the plans are. Maybe you can discuss this internally. Otherwise, do you think this is a good fit?

-- Nir

On Mon, Apr 28, 2025 at 12:02 PM Viktor Klang <viktor.klang at oracle.com<mailto:viktor.klang at oracle.com>> wrote:
The challenge here is that there is no, current, reification of a pattern application, so all it boils down to at this point is: given a Predicate for some type T, make a cast to some unrelated type R.

For Class-based retention of elements, it is possible to do the equivalent of testing Class::isInstance(element) and then push the element downstream after a Class::cast(element)

Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle
________________________________
From: core-libs-dev <core-libs-dev-retn at openjdk.org<mailto:core-libs-dev-retn at openjdk.org>> on behalf of Nir Lisker <nlisker at gmail.com<mailto:nlisker at gmail.com>>
Sent: Saturday, 26 April 2025 20:55
To: core-libs-dev at openjdk.org<mailto:core-libs-dev at openjdk.org> <core-libs-dev at openjdk.org<mailto:core-libs-dev at openjdk.org>>
Subject: Casting gatherer

Hi,

instanceof has been refitted to include an auto-cast ("pattern matching on instanceof"). Unfortunately, doing this as an intermediate operation on a stream requires first to filter via instanceof and then map via a cast. This is because

    x instanceof MyClass myClass

returns a boolean, not myClass.

I've asked for an easier way of doing it long ago directly on Stream and was declined, but now with Gatherers I'm bringing this up again. I think it would be reasonable to put such an operation in the Gatherers class. I imagine that many Gatherer libraries, or utility classes, will include it since it's a common operation, and having it in the JDK means that it'll be done the best way possible (you can optimize where others can't, if applicable here).

-- Nir
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/core-libs-dev/attachments/20250428/d618be10/attachment-0001.htm>


More information about the core-libs-dev mailing list