Hacker News new | ask | show | jobs
by digitalzombie 3959 days ago
> * hearing how difficult it is to learn, and

I thought it was pretty straight forward coming from Erlang.

The biggest thing for me was practice thinking in recursion.

1 comments

The person you are replying to, unawares of the difference between static typing and type inference, is not going to find Erlang any easier to learn.
My understanding is that type inferencing allows you to omit specifying types in many places (the compiler uses heuristics to figure out the types in those places out at compile-time), but that you still need to specify types when necessary. (Please correct me if I'm wrong.)

I think Rust does this, but looking at Rust code, there's still types specified all over the place, and it looks much more cluttered to me than dynamically typed languages I've used.

Here's a slightly longer example of Haskell's awesome type inference with some additional commentary to complement the example that elbenshira gave:

    >>> let showAdd x y = show (x + y)
    >>> :type showAdd
    showAdd :: (Num a, Show a) => a -> a -> String
The compiler infers:

* The two arguments, `x` and `y`, must be some type `a`

* They must be the same type `a`

* The type `a` must implement the `Num` interface (because we add them together using `(+)`

* The result of addition must also be the same type `a`

* The type `a` must also implement the `Show` interface (because we call `show` on the result of addition, which also has type `a`)

Notice how the compiler works backwards from the call to `show` on the result of addition to infer that the two original arguments must also implement the `Show` interface.

We didn't need to annotate any argument types or interfaces: the compiler did all the work for us. This is what people mean when they say that Haskell has "global" type inference.

A language like Rust has "local" type inference, meaning that you have to help a the compiler a little bit by providing the types and interfaces of function arguments, but then the compiler can infer the types of locally bound variables from that point forward.

Yes, read this part: https://github.com/Gabriel439/post-rfc/blob/master/sotu.md#t... and https://github.com/Gabriel439/post-rfc/blob/master/sotu.md#r...

From my (short) time with Haskell, I've found the type system to be the best I've ever used. It really does feel like it's helping you, instead of getting in the way. And so it feels more like a dynamic language than other strongly typed languages I've used (e.g. Scala, Java).

Below is a simple example, but look, no types to type!

    >> let plus1 = (+1)
    >> plus1 10
    11
    >> :t plus1
    plus1 :: Num a => a -> a
You can ask for the type by `:t plus1`.

I've also used Clojure, and I do really like Lisps, but I don't think untyped languages give enough benefit for all the problems it causes. I'm excited, however, about Typed Clojure (and Typed Racket).

We made a choice with Rust to force you to write type annotations in function signatures, because it prevents errors at a distance. Even in languages with full type inference, writing out signatures is still considered good style for this reason.