News for hackers. Stuff that matters.
Re:Haskell’s Niche: Hard Problems by merijnv on Monday March 14, 2011 @11:45AM (#2322920)
> The type system gets in your way

I think that anyone saying this suffers from a fundamental misunderstanding of how to use a type system like Haskell's. I encounter it often with people coming from C/Python who start writing typeclasses, data types etc. and only afterwards start adding functions and then struggle trying to get the right types for their functions.

Fundamentally, programming is a search problem. We are searching for a sufficiently good solution (program) in the space of all possible solutions (all possible compiler inputs). I am of the opinion that the type system can significantly help in searching for such a "good solution". In the words of Conor McBride: "Sometimes it's easier to search for good programs in the space of well typed programs, rather than in the space of ascii turds."

Personally, I start by writing down type names (just names, no implementation or anything) and function names of what I want to do with said types and most importantly what the type of said functions should be (inventing new type names and functions as I discover I need them).

Say, for example, a game would start with GameWorld type and an update function of type "GameWorld -> some events -> GameWorld".

This way I start fleshing out the skeleton of WHAT I want to do, without any regards yet as to HOW I plan on accomplishing it. Once I think my skeleton is somewhat complete I define all my functions to be "undefined" (actually, I do this as I write them down, of course). undefined has all possible types in Haskell, so it always typechecks, but throws an exception when evaluated.

Then I start replacing the undefined's with actual code that matches the signature and start implementing typeclasses/datatypes as required while writing the functions. I will occasionally compile the code to see if everything so far actually type checks.

Re:Haskell’s Niche: Hard Problems by dododo on Monday March 14, 2011 @12:36PM (#2323166)
that's how you write haskell the first time. that's fine. easy, nice, simple. you've written a lot of code; it compiles, it works, no problem.

then you realise that you want to change a data structure or a function needs some information that you want to weave through it or you used the wrong abstraction. then it's a pain in the ass.

Re:Haskell’s Niche: Hard Problems by ezyang on Monday March 14, 2011 @02:28PM (#2323742)
There are two points to be made here:

1. With a static type system, you can make the key change at the data type declaration level, and then chase down the compiler type errors to figure out all the place you need to change it. You need to do extra legwork in dynamically typed languages to get the compiler to tell you this sort of info: how many times have you changed some variable name in Python and forgotten to update the reference somewhere obscure?

2. Yes, if you have some pure, functional code, and then you decide you want to have a feature that uses state, fixing things up can be a bit tedious. I think there's an interesting space here for refactoring tools that help take out the tedium. I will also note that this restriction is a good thing sometimes: you know how you add a global here and a global there and suddenly you have an unmaintainable blob of global state? Haskell asks you to "slow down" and re-think about what you actually want to do. It encourages you to use the minimum amount of language features to get the job done. This leads to more maintainable code.

Re:Haskell’s Niche: Hard Problems by tel on Monday March 14, 2011 @03:33PM (#2324030)
I think there's a space for partial compiles that Haskell doesn't take advantage of well. Correct me if I'm wrong.

Assume that you've got a simple dependency tree on defined names in a program and you want to refactor the type of one of the leafs. The type system is great here in that it'll track those mismatches straight up to the root.

The trouble appears if you want only an experimental type change at the leaf. It would be excellent to get successful partial compiles threaded up the tree. In other words, it should be possible to make a cut in the type dependence tree in order to test a functional subset of your program under more rapid experimental changes.

Once you've iterated enough to decide on a new formulation of that branch of the dependency tree, you can continue attempting typechecking up to the root node.

Re:Haskell’s Niche: Hard Problems by ezyang on Monday March 14, 2011 @05:17PM (#2324548)
One thing I've seen done here is copy paste the method into a new name (usually with a leading underscore) and then make the appropriate changes. It's not hooked up to the rest of the system (but that wouldn't have worked anyway), and you can still compile it and poke at it.
Re:Haskell’s Niche: Hard Problems by tel on Monday March 14, 2011 @05:42PM (#2324640)
That works as long as it's a simple dependency tree like I was talking about and there is a single cut with that property. It's pretty likely you'll have convergent nodes (like changing a datatype's interface late in the game) and there's no simple cut that can let the thing compile.

I mean, sure, this can all be manually avoided, but I still think that having GHCi "compile as much as typechecks" instead of stopping before loading any symbols would be nice.

Re:Haskell’s Niche: Hard Problems by tmorgan on Monday March 14, 2011 @05:18PM (#2324551)
I don't really see why you'd need that. In those sorts of circumstances I'd either add the new version of the function with a new name, or rename the function and add an oldFunc = undefined line to keep the type checker happy.
Re:Haskell’s Niche: Hard Problems by zohebv on Monday March 14, 2011 @07:20PM (#2324973)
I have bitten severely by 2. I think having parameterized modules can go a long way in eliminating the pain of refactoring.