5 ms·
Did you perhaps jump into the water too quickly? I'm currently learning a couple of functional languages (including Haskell) and using it in production environm
by MatthewPhillips 15y ago
Did you perhaps jump into the water too quickly? I'm currently learning a couple of functional languages (including Haskell) and using it in production environments but my current use is restricted to "I have an input that will always produce a certain output. There are no database or environmental dependencies, this is straight computation. I want to never have to worry about this function ever again". And so far, knock on wood, haskell has been killer for that scenario. I'll probably eventually transition a lot more of my code to functional languages, but will do so slowly (using Go otherwise).
- substack 15y agoHaskell is great for pure algorithms like that. As for jumping in too quickly? I was a pretty heavy haskell user for about 3 years.
- danieldk 15y agoHaskell is beautiful, I love it, but I can easily see his points. There are a few traps one can easily fall in: - Reach a point in a complex application where it becomes hard to reason what laziness will do to performance. - End up in type-hell. E.g. some libraries extensively use existential quantification of type variables. Before you know it, you are chasing "type variable x would escape its scope"-type or error messages, in perfectly fine looking code. - Pattern matching is nice, but if you extensively use it, adding a constructor argument is a lot of work. - No-one uses the same data type for common things. For instance, for textual data, there is String, Data.Text, Data.Text.Lazy, Data.ByteSting, and Data.ByteString.Lazy. These days there is more or less consensus on when to use which type, but you are often converting things a lot. There are also types of data for which no consensus is yet reached (e.g. lenses). - Artificially pure packages. There are some packages that link to C libraries, but (forcefully) provide a pure interface. (Or in other words: purity is just convention). - For a lot of code you end up using monads plus 'do' notation, making your programs look practically imperative, but an oddball variation of it. - Using functions with worse time or space complexity, to maintain purity. - I/O looks simple, but for predictable and safe I/O you'd usually end up using a library for enumerators. Writing enumerators, enumeratees, and iteratees is unintuitive and weird, especially compared to (less powerful) iterators/generators in other languages. Learning Haskell is something I'd certainly recommend. It provides a glimpse of how beautifully mathematical programs could be in a perfect world. Unfortunately, the world is not perfect, and even Haskell needs a lot of patchwork to deal with it.
- anothermachine 15y ago> Artificially pure packages. There are some packages that link to C libraries, but (forcefully) provide a pure interface. (Or in other words: purity is just convention) Explain? What would the alternative be? > Using functions with worse time or space complexity, to maintain purity. This seems like the opposite of your previous complaint. > For a lot of code you end up using monads plus 'do' notation, making your programs look practically imperative, but an oddball variation of it. This seems to be a "psychological problem" with Haskell: the idea that because Haskell supports declarative, it's not OK to be imperative. It makes beginners tear their hair out looking for 'do'-free solutions when they could just use 'do'. C.f., "Lambda: the Ultimate Imperative" (and the rest of that series of LtU papers) http://dspace.mit.edu/handle/1721.1/5790 http://dspace.mit.edu/handle/1721.1/5790
- danieldk 15y agoExplain? What would the alternative be? Box the value that is the result of evaluation an expression that calls impure code in IO? This is what I'd expect for calling impure code in third-party libraries.
- jrockway 15y agoIf the library developer can prove that a C operation is pure, why shouldn't he tell Haskell about that?
- jrockway 15y agoAnd if you don't trust the developer, it's easy to fix his mistake: unUnsafePerformIO :: a -> IO a unUnsafePerformIO = return
- ezyang 15y agoSorry, that doesn't actually work. ezyang@ezyang:~$ cat Test.hs import System.IO.Unsafe unUnsafePerformIO = return main = do let a = unUnsafePerformIO (unsafePerformIO (putStrLn "boom")) a a ezyang@ezyang:~$ runghc Test.hs ezyang@ezyang:~$