Hacker News new | ask | show | jobs
by imakesnowflakes 4073 days ago
>While fiddling around is still somewhat possible in Haskell, the language itself makes it quite difficult. Haskell kind of forces you right at the beginning to pause and think "Well, what is it that I'm actually trying to do here?"...

Wouldn't Scripting languages allows one to gradually build that understanding. Suppose you end up with a lot of complex code? Ditch it and build it from scratch. Usually takes around 1/10th the time it took first time with much better results.

So I think by the time one can think up and build the perfect abstractions in Haskell, one can write 3 or 4 iterations of the program in a dynamic language. Each time with better abstractions and neater organization....

7 comments

In my experience, to borrow seanmcdirmid's terminology below, one can use Haskell as a "program to think" language - and in fact Haskell brings some significant tools to the table that I miss when I'm using Python to feel around a problem, to the point that I often choose Haskell for this. In both languages, writing small pieces of code and examining their shape and their output can be helpful in growing my understanding of the solution space, but I find that Haskell tends to let me ask more complete questions with less complete code.
No. The debugging time, refactor/rewrite time of writing in scripting languages is substantially longer, harder work, and distinctly unpleasant compared to just thinking and using good tools to do it right in Haskell.

In Haskell, I'll often have a problem and just stare at my laptop and think for an hour. Then write a dozen lines of simple, straightforward code. The code is easy to test, and the problem is marked as "solved" instead of "seems to work" as happens in scripting languages.

Edit: auto complete fixes

Pausing for an hour to think about and understand your problem is important in any language. Probably more important than testing honestly.
Indeed. I'd argue that strongly typed languages represent many problems in the type system, often letting you know very quickly that you'll have to spend that hour.
I now do all of my logic and data structure design on paper. It usually ends up looking like a series of incomplete sketches, as I very quickly iterate over wrong ideas that would have taken hours to discover if I'd coded up all the alternatives.

The final few sketches almost always end up simpler than the original idea seemed!

I also try to follow ESR's paraphrasing of Fred Brooks:

"Show me your code and conceal your data structures, and I shall continue to be mystified. Show me your data structures, and I won't usually need your code; it'll be obvious."

I think this concept is actually more important than the choice of language.

The nice thing about Haskell is that the type system lets you work at a higher level of abstraction. One of the problems with dynamically typed languages is that even though they let you create abstractions they are bad at error detection. For example, if you have a function that expects non-null inputs and you pass null to it the error is only going to be caught when you try to call a method on the null. On the other hand, in a statically typed language you get an error message poining directly to the real source of the issue.

Another othing Haskell gets right is the support for parametric polymorphism (generics). You are forbidden from manipulating generic parameters other than passing them around so there is less room for error. This "theorems for free" is what makes things like monads "tick".

That said, one thing that is in vogue right now is adding optional type systems and runtime contracts to scripting languages. Its still a bit of a research area but I think it has a very promising future.

Different languages lead to different exploratory behaviors.

Haskell makes it very safe to change your code, but it adds some initial costs. Scripting languages make it very unsafe to change the code, unless you spend a lot of time writing tests, but then they stop being fast to iterate.

I think that's an interesting point, _if_ people actually do that. That said, I'm wary of the claim of 1/10th time and being able to iterate 3 or 4 times per every one iteration with Haskell. Sure, maybe when you're starting out, but once you become proficient I don't think that would be the case anymore. And, there's no guarantee that 3rd or 4th iteration will be as good as the well thought out Haskell code, since the first iterations may be prohibitively complex.
The point is that a scripting language is a "program to think" language, while haskell is often seen as a "think to program" language (at least when described as in the top level post). That you have to do more thinking and planning when using haskell (supposedly) doesn't help when the problem you are working on is not well understood and requires exploration (where you are forced to do exploration in your head...or on a whiteboard, rather than in code).
I strongly disagree. In Haskell the compiler helps me think a LOT more than other languages because it's checking more things for me. I don't have to explore things on the whiteboard, I can explore them in code and get very quick feedback about things I might have missed. I have built things in Haskell that I don't think I would have been able to build in other languages. The compiler is your friend, not your enemy. It's like having another developer there to bounce your ideas off of.

EDIT: Bottom line, I think Haskell also works well for people who "see programming as a cybernetic extension of their mind".

I didn't make a claim, especially that claim. If haskell requires a lot of up front thinking, then it might turn off those who see programming as a cybernetic extension of their mind (using the computer to help you think, vs. thinking to use the computer). I do not know if the premise was true, but was made by the top level post.
On your edit, I also didn't make that claim. All my premises are open.
I think part of it may be that it helps with thinking, but with a different kind of thinking than scripting languages?

There's that Perlis quote: "Show me your data structures, and I won't usually need your code; it'll be obvious". For me, a lot of thinking about programs involves thinking about the types of data involved, and there Haskell gives a language to talk about it. You can start writing down your datatypes, and the function types, directly in your emacs buffer (leaving the function bodies as just "undefined" at first). By contrast, if you are programming in some untyped language like Scheme, you have to do all that work inside comments---e.g. if you write a compiler you maybe start by writing a huge comment saying "this is the grammar I expect input expressions to follow". Having a type language around kind of helps by providing a notation.

I guess there is some other kind of exploratory thinking which untyped langauges provide a good notation for? But in my life I have mostly worked in typed languages, so I don't have any concrete idea of what it is.

The quote is from Fred Brooks (author of "The Mythical Man-Month"), and it goes like this:

> Show me your flowchart and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowchart; it'll be obvious.

I don't think it's about exploratory programming. It's more about reading other people's code.

Wow, I got that extremely wrong huh. Thanks for the correction.
> Wouldn't Scripting languages allows one to gradually build that understanding.

Lately I've reading this[1] academic paper about End-User Software Engineering. While not an easy read nor a good introduction if you've never read about End User Development, it delves precisely on methods for building tools that allow just that, while adding opportunistic checks to correct bugs.

[1]http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.360...

Haskell allow you to express algorithms in a more error-proof way.

For really complex things the implementation in scripting language can introduce errors that are catchable in typed language.

So you code your complex things, it fails to perform to expectations (but somehow performs, not just stack dumps). Where the source of fault lies, in the complex idea itself or in the almost whole source code?

My rule of thumb is that I write in Tcl/Python/Bash something that is not longer than 200-300 lines.