Article 4W9T5 CodeSOD: Crank the Volume

CodeSOD: Crank the Volume

by
Remy Porter
from The Daily WTF on (#4W9T5)

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:

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.

proget-icon.png [Advertisement] ProGet can centralize your organization's software applications and components to provide uniform access to developers and servers. Check it out! TheDailyWtf?d=yIl2AUoC8zAz7i3CuDxCZw
External Content
Source RSS or Atom Feed
Feed Location http://syndication.thedailywtf.com/TheDailyWtf
Feed Title The Daily WTF
Feed Link http://thedailywtf.com/
Reply 0 comments