2 ms·
> Initially, you're spending a lot of time prototyping, fumbling around trying to find the right abstractions. Here Haskell mostly gets in the way The opposite
by pka 10y ago
> Initially, you're spending a lot of time prototyping, fumbling around trying to find the right abstractions. Here Haskell mostly gets in the way
The opposite is true: here Haskell helps to find the right data structures/abstractions incredibly fast. The ability to quickly construct and reconstruct a high-level skeleton of your program without actually having to implement anything makes prototyping much easier and faster than in comparable dynamic languages.
> But then you hit a wall. Laziness makes for brutal debugging.
Laziness can sometimes surprise you in bad ways, but it's not like it's impossible to debug.
> Singly linked lists actually suck.
Just replace them with the right data structure then? Even for big codebases and fundamental program abstractions that's a 15min job, because of types.
> Performance optimization is a black art.
I agree. But then again - you don't have to write everything in Haskell. Writing the critical 1% in C, testing the shit out of it and calling it from Haskell is absolutely fine.
- jstimpfle 10y agoWhy, in your opinion, is it faster to construct a "high-level skeleton" than in dynamic languages? > Laziness can sometimes surprise you in bad ways, but it's not like it's impossible to debug. The last message I get was something like "Array.Array: Index out of bounds". Program crashed. No idea where the error originated. The answer I got was "yeah, in GHC 8 there will be some support for stack traces".
- pka 10y agoBecause of types, basically. You can construct the core data structures of your program and the types of the functions operating on those data structures without having to actually implement said functions. When the types fit together, i.e. your program is logically consistent, you can start filling in the actual code. This is much faster than writing a large chunk of code, playing around in the REPL thinking everything is ok, only to realize one week later that you didn't think through some core aspect of your design and then having to refactor a sizeable piece of your codebase. > The last message I get was something like "Array.Array: Index out of bounds". Program crashed. No idea where the error originated. It is an unfortunate historical artefact that there are still partial functions (i.e. functions that may crash) in the Haskell base libraries. It is generally advised to avoid such functions, but this is not very clearly communicated to newcomers to Haskell. For example, Elm, a language largely inspired by Haskell, doesn't have partial functions. This is why it prides itself in "not having any runtime errors in production" (excluding things like compiler bugs or unsafe JavaScript libraries, of course).
- jstimpfle 10y agoThe error was my own. Only I couldn't figure out where exactly. Such errors can't be avoided. I need arrays for performance. If performance is no concern I can use Maps, but I still need indexing ("partial functions") for architectural reasons: separation of concerns - can't make "safe" graphs where everything holds a reference to everything "related". I just don't buy the idea that partial functions can be avoided.
- pka 10y agoI.e. look at how PureScript does it [0]. Haskell could do the same. [0] https://pursuit.purescript.org/packages/purescript-arrays/3.0.1/docs/Data.Array#v:index https://pursuit.purescript.org/packages/purescript-arrays/3....
- jstimpfle 10y agoSure, I can use a Maybe variant, but the consequence would be that I wrap the whole program in a layer of maybes for cases that I "know" shouldn't happen but happened -- because I do make mistakes. Or in other words, an "AssertionMonad". No thanks, I'm perfectly fine with assertion errors (i.e. "Index out of bounds"). I just need help with finding my own errors. Stacktraces are a good thing.
- pka 10y agoI agree, stack traces are a good thing. For the time being, make a helper function: ixWithString :: String -> Int -> Array a -> a check the bounds inside and error out with a custom message when the index is outside the array bounds.
- natec425 10y ago> For example, Elm, a language largely inspired by Haskell, doesn't have partial functions. I may be wrong, but I don't think this is technically true. I don't think Elm has only total functions, but it does avoid a lot of common, error-prone partial functions (e.g. accessing elements from a collection).
- Ixiaus 10y agoIt is faster for large programs. For small programs, I think Python is great but you also have to consider that there is no such thing as prototype code and a small script (usually but not always) balloons into something more involved than was originally intended. THAT is where Haskell shines, the ability to refactor and expand fearlessly and aggressively. I think for large or complex programs Haskell is much faster for constructing a skeleton because it's usually not the logical operations that trip us programmers up, it's the data flow and correct alignment of types, which are implicit in a dynamically typed language and explicit in Haskell. So, it's kinda-sorta like writing your ideas down in a structured language which enables you to "see" the abstractions in a rigorous light, then the ability to refactor aggressively and safely kicks in so once you can see your abstractions you can quickly adapt for better ones. So I think the initial work is made quicker in that it forces you to excogitate then because it's in some concrete form you can see it clearly and take advantage of quick turnaround time in refactoring.