4 ms·
From the bit of Haskell I've managed to learn, it's a great language, and I can see how an awful lot of the errors that you can make in other languages will pro
by prof_hobart 15y ago
From the bit of Haskell I've managed to learn, it's a great language, and I can see how an awful lot of the errors that you can make in other languages will probably be avoided in Haskell, but I've never understood the (frequently repeated) claim that
"If your program compile it will be very close to what the programmer intended".
There's nothing I've seen in Haskell, or any other language, that will prevent you implementing the wrong algorithm, or the wrong business rules etc. If you're doing a phsyics simulator (to take an example I've played around with), Haskell is not going to stop you badly miscalculating the gravitational effect of multiple objects, or calculating the mass of an object incorrectly.
- jiggy2011 15y agoI think if someone made a language where it was categorically impossible to do something dumb they'd be very rich indeed. :)
- Peaker 15y agoThat's the difference between an "intentional bug" and an "unintentional bug". The former is when you want the program to do X, and X itself is wrong. Sure, defending against this is rarely possible. The latter is in my experience far more common. When you want the program to do X, but you actually told it to do Y. Haskell catches most of the latter cases. One of the main reasons is the functional purity. Because return values are the only result of a function, and these values are type-checked against a specification, it is much harder to do the wrong thing. For example, an imperative program will idiomatically have methods whose sole effect is mutating their arguments or the objects. Even with a type system -- if you just omit the effects, the compiler really has no way to know that you meant the effects to happen, and you will simply have a bug. A purely functional program will idiomatically use a different style. Instead of mutating arguments and objects, it will return a new value. If you forget to return a new value, the compiler will catch that. Additionally, the types in Haskell are generic by default. The more generic the type of a function, the more restricted is what that function can do. The restrictions narrow the space of wrong things you can do. Another interesting property of Haskell is where it chooses to be on the "restrictiveness+guarantess vs. powerful+unguaranteed" trade-off. It seems many don't even notice that the other side of the "power" coin is "guarantees". The more powerful a construct is -- the less you can say about what it will do. In Haskell, the purity and generic types of functions are two things that heavily restrict code. But there are many other mechanisms to restrict rather than empower code. In many contexts, restrictiveness is considered a bad thing, but in Haskell, this restrictiveness is very useful for reasoning about code. For example, the function of type: (forall a. a -> a) in Haskell can only be the identity function. It cannot print "hello world", and it cannot mutate variables. These restrictions are useful because we now can have useful laws. For example: id . f = f . id = f. And we can derive these useful laws from the type itself, without even looking at the code! By helping us find the most restrictive sub-language that can express the solution, we rule out even more bugs.
- prof_hobart 15y agoDefining them as "intentional bugs" doesn't seem particularly accurate or useful. Some of them may class as "design" rather than "coding" bugs but they still aren't usually what the programmer intended, and I would say that the majority of production defects that I see in our systems these days would fall into this category.
- rmcclellan 15y agoThe power/guarantee trade off isn't a fundamental one, even though in current languages you often have to choose between the two. Creating languages that combine the power of untyped languages with the guarantees of static languages is an active field of research. For example, dependently typed languages, while currently too unwieldy for everyday use, show promise of having both power and guarantees much stronger than Haskell. Now a third, ill-defined axis of "usability" comes into play.
- jerf 15y ago"The power/guarantee trade off isn't a fundamental one, even though in current languages you often have to choose between the two." It is on the Pareto frontier of the two. Which verges on tautological, but it's still a useful observation. If you can trivially extend the power of a construct while maintaining the same guarantees, the construct was simply broken, and extending the guarantees of a construct without affecting its power means simply that the guarantees were excessively conservative in the first place. (This can almost be copied and pasted any time anybody claims two properties of a program aren't in conflict, the most common probably being security and ease of programming.) We may be wrong about where the frontier is... but I doubt we've very wrong.
- nightski 15y agoI may be alone, but I actually feel like I lose power when using say dynamic languages. There is less power of expression. Sure I can do whatever I want, but in reality programming is communication, and I find them much less powerful in that respect. So using an untyped language only to run an analysis on it later doesn't really seem all that appealing to me, even if it could somehow provide the guarantees of Haskell or dependently typed languages.
- yogsototh 15y agoIn my experience the programmer workflow is (mostly): 1. You think about an algorithm 2. You (try to) code it 3. A first time to discover an error: compilation and/or syntax verification. 4. Then you test your code Depending of the task and the fail, if 3 or 4 fail you go to 2 or 1. With a standard language (C/C++/Java/Python/Ruby/Javascript...) The probability of 3 to fail is very small when you are used to your language. But the probability to fail at step 4 is High. In haskell this is exactly the opposite, with many advantages: Compiler error in Haskell gives you a meaningful and informative message. Most of the time, it even gives you a hint on how to solve the problem. In the end, most of the time, once the compilation phase passed, my program worked as I expected. Furthermore, with Haskell you can use quickcheck, which most of the time will make better test than yours. I know there is some quickcheck equivalent in other languages but I believe this is not standard.
- Symmetry 15y agoThe expression I had heard was "If your program compiles, it probably does something useful - though maybe not the thing you wanted".
- jberryman 15y agoI love Peaker's answer. To elaborate with a sort of concrete example of how haskell can help you avoid logic bugs as in your physics simulation example: In code where the types start to to tell you less, e.g. when doing a bunch of number crunching, and you have a signature that looks like: func :: Int -> Int -> Int -> Int It's common for the programmer to use a "newtype wrapper" to bring some of the logic into the type system like: newtype Velocity = Velocity Int newtype Force = Force Int newtype Iteration = Iteration Int Then the type system will catch if you accidentally use the Velocity when what you want is Force, etc.
- gtani 15y agoYeah, there's Dimensional package, and I've seen people using algebraic data types, or (RWH) a Units type http://necrobious.blogspot.com/2009/03/fun-example-of-haskells-newtype.html http://necrobious.blogspot.com/2009/03/fun-example-of-haskel... http://flygdynamikern.blogspot.com/2011/04/announce-dimensional-09.html http://flygdynamikern.blogspot.com/2011/04/announce-dimensio... http://book.realworldhaskell.org/read/data-structures.html#x_xF1 http://book.realworldhaskell.org/read/data-structures.html#x...
- prof_hobart 15y agoMost languages can help you avoid using the wrong one through the use of variable names. The problems you might run into are more (for example) using the wrong algorithm for calculating gravity, adjusting the position of one planet before using it to evaluate its impacts on other planets, failing in collision detection etc. I don't see anything in Haskell that would prevent me from doing any of those.
- SomeOtherGuy 15y ago>Most languages can help you avoid using the wrong one through the use of variable names. That doesn't help at all, are you serious? Cause you genuinely sound like you are trolling. Especially when you say things like "if a language can't prevent every possible bug then there's no poing having it prevent any bugs".