5 ms·
Are there known real-world examples of miscalculations (as opposed to crash or something like "None" printed) that would be prevented by Haskell but not Python
by owl57 7y ago
Are there known real-world examples of miscalculations (as opposed to crash or something like "None" printed) that would be prevented by Haskell but not Python 3?
(Why "3"? Because the one thing that has bitten me is the old division operator. They were right to kill it with fire. The new "/", just like Haskell's one, always gives floats, which is good for estimates and consistently and obviously bad for money.)
- buckminster 7y ago> The new "/", just like Haskell's one, always gives floats, which is good for estimates and consistently and obviously bad for money. Doesn't Haskell's operate on the Fractional type class? Which includes Rational. Or some money type you wrote yourself.
- owl57 7y agoYes. I wrongly remembered (and even checked the out-of-the-box output of ":i Fractional"!) that it doesn't include Rational, but only different flavours of floats. The original point stands: Python's Fraction defines arithmetical operators in the same sane way, and the bespoke money type is about as free as in Haskell to define them in whatever way seems useful, like throwing exceptions on adding dollars to euros. (And also throwing exceptions on adding dollars to generic ints — that one would be a compile-time error in Haskell, which is of course a good thing. Is this not only a good thing but a critical one in financial context?)
- jolmg 7y ago> (as opposed to crash or something like "None" printed) Stuff like that could also cause data corruption. I don't think xvilka was referring to just miscalculations from less strict typing around numbers. Also, buckminster is right about /. ghci> :i (/) class Num a => Fractional a where (/) :: a -> a -> a ... ghci> :m + Data.Ratio ghci> :i Fractional ... instance Integral a => Fractional (Ratio a) instance Fractional Float instance Fractional Double You can make your own Fractionals by making whatever type and defining an instance for it. Ratio, for instance, is made of a pair of integers (or rather Integrals, which could be Int, Integer, Word, or some type you make up) representing fractions. Here's a comment I did in the past about Haskell's treatment of numbers: https://news.ycombinator.com/item?id=18565234 https://news.ycombinator.com/item?id=18565234
- owl57 7y agothe lack of explicitness about casting exact types (Integer, Rational) to inexact types (Int, Float) has led to many bugs and confusions for me Matches my limited experience with Haskell. You get some bad bugs that you don't get in Python because all the stuff like len([1,2,3]) gives int (≡ Haskell's Integer), and 0.1 + 0.2 means the same thing every time. But I'm really interested in the opposite direction: bad bugs you get in Python but not in Haskell.
- jolmg 7y agoWell, like I had responded to that comment back then, casting is very explicit in Haskell, but I think they were confusing casting with type inference. Most of the time, 0.1 + 0.2 is the same thing every time, but you do have the option of it being different types, depending on what you need.
- tome 7y agoCan you explain how that leads to a bug?
- owl57 7y agoimport qualified Data.ByteString as B import qualified Data.ByteString.Char8 as C main = do let x = 100 print (x * x) let y:_ = B.unpack (C.pack "foo") --let z = x * y return () If we uncomment that line, the output of this program changes from 10000 to 16. Yes, I learned this by triggering similar action "in the past" accidentally. Don't remember details, but that program also involved ByteStrings. The convention of explicitly type-annotating top-level declarations is there for a reason: it limits the scope of damage.