Hacker News new | ask | show | jobs
by seanmcdirmid 4367 days ago
There is more to quick and dirty programming than refactoring. I would say refactoring even doesn't play much if a roll here. What is key is the ability to be in a broken state for long periods of time while still being able to test and executed pieces of the system. This doesn't work in Haskell since Haskell is not just statically typed, it is Statically Typed! Type inference and code generation are slaves to types, and don't handle errors very well. That could be fixed, but it doesn't seem to be a priority (generate code Forman incorrect program seems to be taboo).

More crucially, Haskell programmers tend live in their compiler and not their debugger. The adage "well typed programs don't go wrong" means you spend a lot of time just getting the code to compile, fitting types together, and not much time seeing how things work together. Much of this is because the community emphasizes the compiler, and in fact good graphical debuggers for Haskell aren't there yet (and even difficult to design given lazy evaluation). Bret victor didn't do his inventing in principle talk with Haskell for good reason!

Python and ruby. programmers live in the REPL and debugger, they don't get to observe type errors early like Haskell programmers do, but they immediately get to see real interactions. I can then see why going between Haskell and ruby would be a disaster.

2 comments

You can compile haskell programs with type errors (in GHC, anway) if you want. They crash when you attempt to execute code that has a type error, but if that's what you want, feel free to use it.

It's not something I've ever needed. It's got little to do with quickly exploring design space.

Edit:

I guess I should include a couple words about why it's not really necessary in real coding. A side effect of good module boundaries is that you can test breaking changes in isolation in the REPL. Change a few things that are tightly coupled at the same time, load their module, don't worry about fixing any other modules until the first one works the way you like. In practice, this means you almost never need the option to defer type errors to runtime.

"real interactions"? It is disingenuous to imply that all Haskell programmers do is see type errors while Python and Ruby programmers have 'real interactions'.

For instance, today I wrote tons of stuff in the IO Monad and had what you call 'real interactions'.

Also, more time spent in the debugger doesn't necessarily mean a faster working program. The psychology of it is more rewarding, but there's nothing necessarily more "real" about it.