Hacker News new | ask | show | jobs
by jjviana 3816 days ago
"default <T> Extension<T> contraMap(Function<T, S> f) { return (T src, Results results) -> Extension.this.apply(f.apply(src), results); }"

Java 8 Lambdas provide such an elegant syntax for anonymous classes... When lambdas were first introduced in Java , a lot of people were underwhelmed by them. It is hard to evaluate at first the impact they can have on a well designed API.

2 comments

Is this

    foldMap :: Monoid m => (a -> m) -> t a -> m

?
Interestingly, your comment can be read both as a naive "did I understand your code example", but also as "look how horrible this syntax is, and how much it obfuscates the underlying thought-process". It tells a lot about Java as a language.
Though the right comparison is

   default <T> Extension<T> contraMap(Function<T, S> f)
   foldMap :: Monoid m => (a -> m) -> t a -> m
I also prefer the Haskell syntax, but it looks like more of a difference because the implementation is inline.
To be fair, I afterwards thought that for some people, especially when taught with OOP, would see some functional abstractions as obfuscation. Each type of abstraction (objects, higher-order functions or continuations) work best with specifically designed syntax. I didn't like Scala too much for this reason, as it seemed a too bizarre combination (from a syntactic POV), as a contrast with Ocaml.

Anyway, tastes and education play a role there, but to me the arrow notation is way easier to read, as it is what I would write on paper.

I agree - I really had to deobfuscate / parse the signature first before even being able to start comprehending what it is about.

Not saying that there are no monster type signatures in Haskell (just recovering from one such instance in purescript-halogen), but it's really the most leightweight syntax for annotating types out there.

I often use Haskell signatures in comments when writing JS or whatever, just to keep the types straight.

It's just that OP quoted a multi-line function signature plus implementation in one line, which obfuscates things. Looking at just the comparable signature is pretty clear.

    <T> Extension<T> contraMap(Function<T, S> f);
It's this

  contramap :: (a -> b) -> f b -> f a

  http://hackage.haskell.org/package/contravariant-1.3.3/docs/Data-Functor-Contravariant.html#v:contramap
I thought "Extension" in this example is a Monoid. So maybe foldContramap? :)
That just seems broken?

If `f` is Function<T, S> then given `T src`, like we have, then f.apply(src) has type S. But Extension.this.apply is applied to values of S even though T is the thing qualified as an Extension.

Actually, I'm just entirely not sure I know how to read Java type signatures.

The part you're missing is the `this` in `Extension.this`. This method is a member of Extension<T>, and it returns an Extension<S>. So `this` (of type Extension<T>) is transformed by the method to Extension<S>.
Ah, thanks!