CodeSOD: Crank the Volume
When using generic types in a language like Java, nesting generics is a code smell. That is to say, a type like List<Map<String, T>> is probably a sign that you've gone off the path and should rethink how you're structuring your program. Similarly, types that depend on more than one or two generic type parameters are probably a code smell as well.
If those are a "code smell" this code Adam S found is a "code sewage treatment plan in dire need of a visit from the Environmental Protection Agency".
public interface VolumeStream<V extends Volume, I> extends BaseVolumeStream<VolumeStream<V, I>, V, I>{ default <M extends MutableVolume, M2 extends M, U extends UnmodifiableVolume> M2 merge(V second, VolumeMerger<I, ? super U> merger, M2 destination, VolumeFiller<? extends M, ? extends I> applier) { return merge(VolumeReducer.of(() -> second, () -> (U) getVolume().asUnmodifiableVolume(), () -> destination, merger, applier)); } <M extends MutableVolume, M2 extends M, U extends UnmodifiableVolume> M2 merge(VolumeReducer<V, I, M, M2, U> reducer);}public interface VolumeReducer<V extends Volume, T, M extends MutableVolume, M2 extends M, U extends UnmodifiableVolume> { Supplier<V> getSecond(); Supplier<U> getReference(); Supplier<M2> getAccumilator(); VolumeMerger<T, U> GetReducer(); VolumeFiller<M2, T> getFinisher(); public static <NV extends Volume, NT, NM extends MutableVolume, NM2 extends NM, NU extends UnmodifiableVolume> VolumeReducer<NV, NT, NM, NM2, NU> of(final Supplier<NV> second, final Supplier<NU> reference, final Supplier<NM2> accumilator, final VolumeMerger<NT, ? super NU> reducer, final VolumeFiller<? extends NM, ? extends NT> finisher) { return new Impl<>(second, reference, accumilator, reducer, finisher); }}
Not only is that a nest of types which is impossible to understand, it doesn't even manage to get full type safety- VolumeStream presumably inherits the method getVolume through BaseVolumeStream, but getVolume doesn't have a signature of type U (anything which extends UnmodifiableVolume, presumably)- so there's actually a cast required: (U) getVolume().asUnmodifiableVolume().
But hey, even if the code is ugly, that hopefully gives us a clean, readable calling convention, right? We're gonna call this code more often that we're gonna write it. How do they call this?
stream.<MutableBlockVolume<? extends MutableBlockVolume<?>>, GenerationRegion, UnmodifiableBlockVolume<?>>merge(this, merger, region, VolumeFiller.BLOCK_APPLIER);
Oh.
Adam adds:
[Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out!This code tries to express a transformation pipeline for streaming game data, and instead expresses how much I'd like to be writing in literally anything else.