9 ms·
This is interesting, and I'm curious and respectful of Haskell, but when I read a post like this, while I appreciate many of the strengths of static type checki
by hellofunk 10y ago
This is interesting, and I'm curious and respectful of Haskell, but when I read a post like this, while I appreciate many of the strengths of static type checking, it just makes my head hurt to see what this guy goes through to please the compiler, and I'm left thinking that I'd just rather stick to a dynamic functional language like Clojure or Erlang and sketch ideas out more quickly. Maybe I'm just not patient enough for Haskell.
- chongli 10y agoI think the approach taken by the author is simply the wrong one. Writing a huge amount of code without any clue what the types are going to be is just silly. Haskell makes it very easy for you if you work with it in a more interactive fashion, asking it to infer types for you as you go along. One of the best features for doing this is Typed Holes [0]. [0] https://wiki.haskell.org/GHC/Typed_holes https://wiki.haskell.org/GHC/Typed_holes
- Ericson2314 10y agoYeah I always use the type checker to help me refactor too.
- mightybyte 10y agoI think in this case it's a reasonable approach to writing the `dpll` function because that function doesn't actually care about the specifics of the types. This is a nice example of encapsulation and implementation hiding, a concept familiar to object-oriented and functional programmers alike. He could have easily gotten it to compile by stubbing things out as follows: data Clauses = Clauses data Symbols = Symbols data Model = Model isTrueIn = undefined isFalseIn = undefined findPureSymbol = undefined minus = undefined including = undefined findUnitClause = undefined I think it's more a question of personal preference than right or wrong.
- nimish 10y agoThe trick is to realize that the incremental incorrect output you get from the compiler is roughly equivalent to the incorrect output you'd get from the failed runtime. Personally I'd start from smaller functions up but it's not like there's no feedback.
- Ericson2314 10y agoOr rather, you're going to need to fix that code anyways, so might as well use the thing that tells you what to do. I personally find fixing type errors far more enjoyable than debugging, and even if I didn't, I think one can argue that fixing type errors is a more predictable workflow and therefore contributes less uncertainty for time budgeting.
- cle 10y agoIf you're prototyping and exploring, most likely you're not going to need to fix that code anyways, so it would be a waste of time (unless you're already efficient with Haskell dev). I'm a big believer in exploring problem spaces with loose, flexible tools that let you get to the point ASAP and ignore unrelated stuff. If you're then going to build a long-lived, high-availability production system, then take what you learned and harden your design using tools built for long-lived, high-availability production systems (e.g. static typing, formal methods, etc.).
- Ericson2314 10y agoYeah I just don't recall a type error where the low chance of hitting it outways the cost of fixing it. The joy of good languages is closing the gap between prototyping and production, research and practice.
- efnx 10y agoStarting with a large chunk of code that doesn't compile is pretty weird. I don't know why you'd ever have this naturally.
- deleted 10y ago[deleted]
- nilved 10y agoThat's pretty much how Haskell development works. It doesn't compile until it's what you want. TDD in Haskell and Ruby are similar, but in Haskell the T is types.
- dllthomas 10y agoThis doesn't match my Haskell workflow at all. Usually, it compiles every small change, with much stubbed out with `undefined` until I get to it. When it doesn't compile, it's surprising and I learn something about the assumptions I've made.
- nilved 10y agoUndefined and type holes are equally valid approaches
- dllthomas 10y agoTo be clear, I am certainly not saying that my approach is the only (or best) one. Just that when it builds (relative to completeness) is very much at the discretion of the programmer, and despite jokes about "if it builds, it works" not everyone has that dial set all the way to one extreme.
- efnx 10y agoI write Haskell for a living and that's never been the approach I've taken. For me writing Haskell is like a conversation with the compiler, you write a bit, you listen a bit - back and forth - unless you're refactoring you don't go too long without compiling.
- hota_mazi 10y agoYou're setting up a false dichotomy. You can find statically typed languages in-between Haskell and dynamic languages that are less demanding from the developer than Haskell is (my language of choice these days is Kotlin, which offers the best of both worlds in my opinion).
- mightybyte 10y agoI don't understand what you mean here. What in particular did you think he was going through just to please the compiler?
- hellofunk 10y agoIt's an expression, often used to refer to the static compilation development process.
- mightybyte 10y agoYes, I understand the expression. What I'm asking is precisely what things he did that example that he would not have had to do if he were using a dynamic language like Ruby or Python. In other words, I'd like to understand specifically what you think are the extra costs he paid for using a static language.
- runeks 10y agoGHC is there to please you, not the other way around. It enables you to practically turn any runtime error into a compile time error, if you choose your types carefully. I write a lot of Haskell these days, and whenever I'm faced with a compiler error I don't understand, it always ends with finding out that my data model was inaccurate. Two ends weren't fitting together, because I hadn't fully understood what those two ends actually were.