Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

To clarify the sibling, a signature of `Int -> Int -> Bool` can't do any IO (so no connecting to databases, reading/writing files, network requests), so it does tell you a lot about a function.

It can manipulate strings, decode JSON, but both of these are either (immutable) values from enclosing scope, or created within the function. But since they can't be output anywhere (because no IO) then they don't matter.

EDIT:

I'll just add a few more counterpoints.

Agreed that DSLs are difficult, and often not worth the trouble. But if you do want to create a DSL, then haskell is a good fit because of monads and monad transformer stacks - i.e you can make the statement mean whatever you want it to mean, and keep the effects in check with types.

The synergy between higher order functions with typed IO is great, better than in other languages.

Agreed that IDE refactoring is convenient, and also refactoring in other languages with static type checking the process is similar to what they describe in the article, so no immediate "pro" there.



> To clarify the sibling, a signature of `Int -> Int -> Bool` can't do any IO (so no connecting to databases, reading/writing files, network requests), so it does tell you a lot about a function.

It doesn't help if it's `Int -> Int -> IO Bool`, for example. Well, it does do IO, but other than that, who knows. Perhaps it reformats the disc while CPU is idle :)

My main point though is that the article does a very poor job of showing why Haskell is good at, well, anything, compared to, well, anything.


It's the fact that it is `Int -> Int -> Bool` that ensures you that the function doesn't do any random thing (like doing something on the database). Combining non-IO capable functions is quite helpful in reasoning about programs. I.e if the function has `IO` in the result type then exactly - "who knows". But with the fact that it doesn't, you do know that it doesn't do anything other than return the bool.


I mean. Really. That's what people hang up on?

The point for that particular gripe was this: "this allows a programmer reading Haskell code to look only at type signatures when getting a sense of what a certain piece of code does."

Yes, IO tells that ... the function does some side effects. And that's it. If your type signature is `Int -> Int -> IO Bool`, it's just as useless as `Int -> Int -> Bool`, and requires you to read the function to understand what it actually does.

Is it helpful to see at a glance which functions produce side effects and which don't? Yes, it is. Does it automagically "allow a programmer reading Haskell code to look only at type signatures when getting a sense of what a certain piece of code does"? No, no, it doesn't. `... -> IO Bool` may be launching nukes for all the information you glean from its type signature.


You don't get any information from `IO _` functions, but that's the case with every mainstream language, where you have an implicit `IO` on every single function.

The benefit is not in `IO` -- its that its absence on a function tells you that it is heavily restricted in what it can do.

If you want to go the other way, you can concretely model the kinds of effects you need parts of your programs to do, and use that model instead of `IO`. Even if you end up implementing it using `IO`, you know it can't use more than what your model exposes.

Both of these possibilities, while not truly unique (see Agda, etc.), are absolutely rare-to-nonexistent in mainstream languages. Effect modeling is a real shift in perspective.


> You don't get any information from `IO _` functions, but that's the case with every mainstream language, where you have an implicit `IO` on every single function.

Indeed. And that's why I picked up on that particular point in the article that I'm criticising. The article chose to use those examples and those words and they don't show anything beyond what other mainstream languages have.

> If you want to go the other way, you can concretely model the kinds of effects you need parts of your programs to do, and use that model instead

Yes, you can. No, the article doesn't show that in any way. Just to remind you how I started my comment:

--- start quote ---

But this article goes out of its way to make the worst possible case for Haskell imaginable.

--- end quote ---

Does the article show "other models"? No. Does it even try and show how to reason about a function by looking at its type signature alone? Also, no. Would this article be laughed into oblivion had it been about any other language but Haskell? Yes, most likely.

> Effect modeling is a real shift in perspective.

Ah yes. Does the article talk about this? Does it show a single example of this? No.


Having a distinction of if something does IO or not is quite important, and the fact that haskell has the ability to encode it in types is what other languages don't have.

Secondly, IO is just one monad. You can build a more granular one where you can separate filesystem, network etc, and encode this into types (so you know at a glance). You can't do this in most other languages.

What are the types of things that are worth being hung up on for a language for you?


Answered in a sibling comment: https://news.ycombinator.com/item?id=25729423




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: