do Haskell programs have fewer bugs?

I was thinking about why it seems I can write Haskell code without bugs in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more. It's the potential for conciseness. I work hard when programming in Haskell to take advantage of language features that make my program concise. Somehow this leads me to think about it in a certain way. I know I'm on track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem. By the time I'm done with all that, I've analyzed my problem much more thoroughly than I would ever do in an imperative language. Dennis

Hello,
Il 19/mar/2014 18:09 "Dennis Raddle"
I was thinking about why it seems I can write Haskell code without bugs
in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more. As a beginner I find that the type system is my best friend. I spend most of the time in the repl trying function compositions until GHCi likes them. At that point, like I often read from expert haskellers' conversations, "if it typechecks it's most likely correct".
It's the potential for conciseness. I work hard when programming in
Haskell to take advantage of language features that make my program concise. As the saying goes, less code means less potential for bugs :)
Somehow this leads me to think about it in a certain way. I know I'm on
track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more
thoroughly than I would ever do in an imperative language.
Dennis
As someone who is still struggling to get past that learning phase where you only solve "simple" (usually one-liner) exercises, I'd like to ask you (and anyone reading this) how do you reason at a larger level? At the function level Haskell feels like piping shell commands (which I find nice): a chain of successive transformations. How do you work at a larger (module/project) level? Do you need to have mastered all the main monads (beyond list amd maybe) and monad transformers? Sorry for the long rant. And thanks for the interesting discussion. -- Nadir

For better or worse depending on your POV I find that I spend a lot of time
looking at the implementations of many libraries I employ in larger
projects.
There are certainly some surprises when a program doesn't execute in the
time or memory that I expected, and having the library source available can
be invaluable for determining why.
Cheers,
Darren
On Mar 19, 2014 11:21 AM, "Nadir Sampaoli"
Hello,
Il 19/mar/2014 18:09 "Dennis Raddle"
ha scritto: I was thinking about why it seems I can write Haskell code without bugs
in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more.
As a beginner I find that the type system is my best friend. I spend most of the time in the repl trying function compositions until GHCi likes them. At that point, like I often read from expert haskellers' conversations, "if it typechecks it's most likely correct".
It's the potential for conciseness. I work hard when programming in
Haskell to take advantage of language features that make my program concise.
As the saying goes, less code means less potential for bugs :)
Somehow this leads me to think about it in a certain way. I know I'm on
track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more
thoroughly than I would ever do in an imperative language.
Dennis
As someone who is still struggling to get past that learning phase where you only solve "simple" (usually one-liner) exercises, I'd like to ask you (and anyone reading this) how do you reason at a larger level? At the function level Haskell feels like piping shell commands (which I find nice): a chain of successive transformations. How do you work at a larger (module/project) level? Do you need to have mastered all the main monads (beyond list amd maybe) and monad transformers?
Sorry for the long rant. And thanks for the interesting discussion.
-- Nadir
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

From my experience so far it's largely the same, but you start to try to take advantage of some of the more advanced types to handle of lot of the plumbing type tasks. Things like Applicative and Monad make it simpler to shuffle data and context between (or around) functions. In general picking the right abstraction over your data goes a long way towards making your code easier to work with and more succinct. Aside from that it's really much like the case with individual functions, it's about composing larger operations from smaller ones until eventually you reach the program level where you're composing a handful of very coarse functions that comprise the totality of the program.
-R. Kyle Murphy
--
Curiosity was framed, Ignorance killed the cat.
On Wed, Mar 19, 2014 at 2:21 PM, Nadir Sampaoli
Hello,
Il 19/mar/2014 18:09 "Dennis Raddle"
ha scritto: I was thinking about why it seems I can write Haskell code without bugs
in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more.
As a beginner I find that the type system is my best friend. I spend most of the time in the repl trying function compositions until GHCi likes them. At that point, like I often read from expert haskellers' conversations, "if it typechecks it's most likely correct".
It's the potential for conciseness. I work hard when programming in
Haskell to take advantage of language features that make my program concise.
As the saying goes, less code means less potential for bugs :)
Somehow this leads me to think about it in a certain way. I know I'm on
track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more
thoroughly than I would ever do in an imperative language.
Dennis
As someone who is still struggling to get past that learning phase where you only solve "simple" (usually one-liner) exercises, I'd like to ask you (and anyone reading this) how do you reason at a larger level? At the function level Haskell feels like piping shell commands (which I find nice): a chain of successive transformations. How do you work at a larger (module/project) level? Do you need to have mastered all the main monads (beyond list amd maybe) and monad transformers?
Sorry for the long rant. And thanks for the interesting discussion.
-- Nadir
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

Perhaps a bit tangential to the general question of "fewer bugs", but I'll
tell you that Haskell really clicked for me when I made a very nuanced
refactor of code that, while it took me a half day to sort out the type
errors, worked perfectly the first time I ran it. And this was for audio
generation stuff, something that's rather hard to debug in a usual way, so
I'm grateful that I didn't have to. There's no way it would work so
smoothly in, say, C++. Granted, I threw a whole lot of types at it, because
I was working with transformations between and operations within different
sorts of domains that I didn't want to get mixed up. So, you sometimes have
to deliberately leverage the tools to get it to do the magic for you.
On Wed, Mar 19, 2014 at 11:47 AM, Kyle Murphy
From my experience so far it's largely the same, but you start to try to take advantage of some of the more advanced types to handle of lot of the plumbing type tasks. Things like Applicative and Monad make it simpler to shuffle data and context between (or around) functions. In general picking the right abstraction over your data goes a long way towards making your code easier to work with and more succinct. Aside from that it's really much like the case with individual functions, it's about composing larger operations from smaller ones until eventually you reach the program level where you're composing a handful of very coarse functions that comprise the totality of the program.
-R. Kyle Murphy -- Curiosity was framed, Ignorance killed the cat.
On Wed, Mar 19, 2014 at 2:21 PM, Nadir Sampaoli
wrote: Hello,
Il 19/mar/2014 18:09 "Dennis Raddle"
ha scritto: I was thinking about why it seems I can write Haskell code without bugs
in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more.
As a beginner I find that the type system is my best friend. I spend most of the time in the repl trying function compositions until GHCi likes them. At that point, like I often read from expert haskellers' conversations, "if it typechecks it's most likely correct".
It's the potential for conciseness. I work hard when programming in
Haskell to take advantage of language features that make my program concise.
As the saying goes, less code means less potential for bugs :)
Somehow this leads me to think about it in a certain way. I know I'm on
track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more
thoroughly than I would ever do in an imperative language.
Dennis
As someone who is still struggling to get past that learning phase where you only solve "simple" (usually one-liner) exercises, I'd like to ask you (and anyone reading this) how do you reason at a larger level? At the function level Haskell feels like piping shell commands (which I find nice): a chain of successive transformations. How do you work at a larger (module/project) level? Do you need to have mastered all the main monads (beyond list amd maybe) and monad transformers?
Sorry for the long rant. And thanks for the interesting discussion.
-- Nadir
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On Thu, Mar 20, 2014 at 1:21 AM, Nadir Sampaoli
As the saying goes, less code means less potential for bugs :)
But you should look out for code golf, which isn't helpful.
As someone who is still struggling to get past that learning phase where you only solve "simple" (usually one-liner) exercises, I'd like to ask you (and anyone reading this) how do you reason at a larger level?
How do you work at a larger (module/project) level? Do you need to have mastered all the main monads (beyond list amd maybe) and monad transformers?
Don't sweat them monads. The codebase for GHC doesn't even use monad
There's a lot of low-lying fruit that's easily plucked leveraging functional programming. I list the easiest ones that I know of here: http://www.atamo.com/blog/low-lying-fruits-of-fp-1/ Of course, you still have to grapple and understand your specific problem domain, whether it's web apps or auto music generation. transformers iirc. Sorry for the long rant.
Not at all. Haskell mailing lists used to have long, discursive discussions, but somehow this one turned into some kind of rapid-fire Q&A. Most of the interesting knowledge can't be unpacked in that format. -- Kim-Ee

Il 19/mar/2014 23:51 "Kim-Ee Yeoh"
There's a lot of low-lying fruit that's easily plucked leveraging
How do you work at a larger (module/project) level? Do you need to have
mastered all the main monads (beyond list amd maybe) and monad transformers?
Don't sweat them monads. The codebase for GHC doesn't even use monad
functional programming. Thanks for the insight. The "don't"s are most helpful. I have to constantly take myself from code golfing and overcomplicating things for the sake of cleverness (especially in a language that enables you so much). transformers iirc. My point was that when you're arranging new data types you'd probably benefit from understanding/recognizing behavioral patterns (e.g a Reader, a State-carrying data structure, etc.). Nonetheless I think I understand your point in which keeping things flat simple does come a long way to solving problems.
Not at all. Haskell mailing lists used to have long, discursive
discussions, but somehow this one turned into some kind of rapid-fire Q&A. Most of the interesting knowledge can't be unpacked in that format. Eh, that would imply a certain level of knowledge on both side. The fact that I'm stubborn and keep writing mails on a phone while train-commuting doesn't help either.
-- Kim-Ee
Thanks again, Regards Nadir

Hi Dennis,
At skedge.me, our platform is Haskell on the backend and JavaScript on the
frontend, and we've definitely found that we have far fewer bugs coming out
of the backend than the frontend. I think Haskell's language features
(including the type system and sum types, most prominently) are responsible
for much of this difference.
We've also been able to completely eliminate certain kinds of bugs, such as
accidentally performing side effects during a database transaction (which
might be rolled back), by using monads to enforce our application's layer
architecture.
It's certainly possible to write very buggy code in Haskell, but Haskell
gives you a lot of tools that you can use to prevent yourself from writing
bugs. In my experience, it is much more efficient than achieving the same
level of quality using only testing.
Ryan
On Wed, Mar 19, 2014 at 1:09 PM, Dennis Raddle
I was thinking about why it seems I can write Haskell code without bugs in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more. It's the potential for conciseness. I work hard when programming in Haskell to take advantage of language features that make my program concise. Somehow this leads me to think about it in a certain way. I know I'm on track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more thoroughly than I would ever do in an imperative language.
Dennis
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners

On the nail!
That's exactly how I feel about using Haskell and it is the same feeling I
had when I learned Lisp... for some reason you feel much more connected
with the nature of the problem and therefore more aware / focused /
cognisant of "what you are doing".
I found that part of the reason, at leat for me, was the need to write
"efficient" code, and that means taking time to read the libraries to see
what is already available and thus you come across more than one potential
way to solve your problem and thus have to think about it more.
I think that Lisp and Haskell (and other languages that promote higher
order programming) allow for powerful abstractions that result in functions
like "map, filter, reject, fold" etc and thus remove theneed for manually
writing loops in the code. That was part of the appeal for me, not coding
loops!
:)
Sean.
On 19 March 2014 17:09, Dennis Raddle
I was thinking about why it seems I can write Haskell code without bugs in a much easier way than imperative languages. Part of it is the strict type-checking, but I think there is something more. It's the potential for conciseness. I work hard when programming in Haskell to take advantage of language features that make my program concise. Somehow this leads me to think about it in a certain way. I know I'm on track as it gets smaller and smaller. And as it gets smaller, it leads me to think about my logic's cases and things like that. Certain patterns show up and I think about what those patterns mean for the structure of my problem.
By the time I'm done with all that, I've analyzed my problem much more thoroughly than I would ever do in an imperative language.
Dennis
_______________________________________________ Beginners mailing list Beginners@haskell.org http://www.haskell.org/mailman/listinfo/beginners
participants (8)
-
Dan Krol
-
Darren Grant
-
Dennis Raddle
-
emacstheviking
-
Kim-Ee Yeoh
-
Kyle Murphy
-
Nadir Sampaoli
-
Ryan Trinkle