Ah, now I see what you mean! Thank you 👍

The reason for the signature of `Gatherer.of` was to mirror as much as possible 
of `Collector.of`[1] so I would argue that if we tweak the variance of one then 
we should consider tweaking it for both.

1:https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/stream/Collector.java#L264

Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle
________________________________
From: fo...@univ-mlv.fr <fo...@univ-mlv.fr>
Sent: Wednesday, 17 January 2024 20:49
To: Viktor Klang <viktor.kl...@oracle.com>
Cc: core-libs-dev <core-libs-...@openjdk.java.net>
Subject: [External] : Re: Gatherer API : wildcards complaint



________________________________
From: "Viktor Klang" <viktor.kl...@oracle.com>
To: "Remi Forax" <fo...@univ-mlv.fr>, "core-libs-dev" 
<core-libs-...@openjdk.java.net>
Sent: Wednesday, January 17, 2024 5:49:01 PM
Subject: Re: Gatherer API : wildcards complaint
Hi RĂ©mi,

Thank you for the feedback—examples would be much appreciated!

Here is an example with an interface and a class,


interface Counter {
  void increment();
  int value();
}

Gatherer<String, Counter, Integer> count() {
  class CounterImpl implements Counter {
    int counter;

    @Override
    public void increment() {
      counter++;
    }

    @Override
    public int value() {
      return counter;
    }
  }
  Supplier<CounterImpl> initializer = CounterImpl::new;
  Gatherer.Integrator<Counter, String, Gatherer.Downstream<? super Integer>> 
integrator = (counter, _, _) -> {
    counter.increment();
    return true;
  };
  BiConsumer<Counter, Gatherer.Downstream<? super Integer>> finisher = 
(counter, downstream) -> {
    downstream.push(counter.value());
  };
  return Gatherer.ofSequential(initializer, integrator, finisher);    // does 
not compile :(
}

void main() {
  
System.out.println(Stream.of("foo").gather(count()).findFirst().orElseThrow());
}

if instead of explicitly typing each functions, we directly call ofSequential, 
it works


return Gatherer.ofSequential(
    CounterImpl::new,
    (Counter counter, String _, Gatherer.Downstream<? super Integer> _) -> {
      counter.increment();
      return true;
    },
    (Counter counter, Gatherer.Downstream<? super Integer> downstream) -> {
      downstream.push(counter.value());
    }
);

because here, CounterImpl::new is inferred as Supplier<Counter>.


Cheers,
√


Viktor Klang
Software Architect, Java Platform Group
Oracle
________________________________
From: core-libs-dev <core-libs-dev-r...@openjdk.org> on behalf of Remi Forax 
<fo...@univ-mlv.fr>
Sent: Wednesday, 17 January 2024 16:55
To: core-libs-dev <core-libs-...@openjdk.java.net>
Subject: Gatherer API : wildcards complaint

Hello,
this is a minor complaint but I do not see a raison to not getting this right.

Currently the Gatherer API does not use the wildcard correctly, which is not 
fully an issue because there is "enough" wildcards that if you rely on the 
inference, it will work.

The problem is that when you write code, you make mistakes and usually when you 
have a typing issue, a way to debug it is to fix the type arguments 
de-activating the inference.
But because there are some missing wildcards, this debugging strategy just fail 
flat with more typing errors.

I think that fixing the missing wildcards will hep users (or a least me) to 
have a better experience when using the Gatherer API.

I can help and propose a PR if you want.

regards,
RĂ©mi

Reply via email to