5 ms·
> It is a pain to align a whole Haskell project according to new requirements to make the whole system work again. I'll quote a recent tweet by Chris Done: "I
by rrradical 12y ago
> It is a pain to align a whole Haskell project according to new requirements to make the whole system work again.
I'll quote a recent tweet by Chris Done: "I feel like 80% of Haskell advocacy should involve screencasts of people refactoring large codebases."
In my experience, refactoring is easier with a strongly typed compiler, not harder. It may take more time and work to get your program to "run" again, but the end result will be more likely correct, and more likely to be a better design.
- dllthomas 12y agoVery much so. I do quite a bit of abuse to my C code to get similar (if weaker) assistance.
- doorhammer 12y agoThis has generally been my experience as well when I'm working with almost any reasonable type system. Every time I've focussed on leaning on the type system, it's made refactoring much quicker for me and left me feeling way more confident. Every time I encounter a bug I think "is there a way I could have encoded this into the type system so it would have never compiled with the bug?" The thing I like about Haskell is how often I can say "yes" to that question and implement it. From what I understand, that question would would "yes" even more often with dependent types, though I've yet to really learn much about them. I really dig lisp (especially clojure) but the thing I miss when I'm using lisp is a really solid type system.
- kazinator 12y agoIf it takes longer to refactor the program, that can kill the initiative to do so. When you do get the program to run, but it turns out that the refactoring is not wanted for whatever external reason, then you just wasted more time than was necessary. Without the bondage of static typing, you can just refactor a small enough fraction of the program, which can run now in some limited way. You can use that to motivate yourself, or to pitch the idea to other people. It is helpful to be able to play "what if" without committing a lot of unnecessary time and effort.
- the_af 12y agoI fully understand the idea about motivation (and my "let's muddle through"-oriented brain is always tempted by this), but I think it goes both ways: If it takes short to refactor the program but, because of the lack of safety checks, what seemed to be working "in some limited way" turns out to be a big ball of bug-ridden mud in the end, and maybe the whole approach wasn't sound, wouldn't that also kill motivation for future refactors? And what if keeping the motivation high for the more impulsive programmers leads to worse software? Doesn't this look like something analogous to the old carpenter's motto: measure twice and cut once? "But I don't want to measure, I want to cut it now, it'll be faster! Measuring kills my motivation!" :)
- klibertp 12y agoThere are other ways of making refactoring easy. I'm not trying to dismiss a powerful type system - which is a great help indeed - but pervasive unit tests and contracts work as well. Linters are a nice addition, and even gradual typing like in Erlang with Dialyzer is much better than nothing. The point being: problems solved by type systems are being solved with other tools, too. I don't want to argue about how well these tools work, because all of them (including static type systems) have relative strengths and weaknesses; it's just unfair to present refactorings or correctness guarantees as benefits reserved for type systems alone.
- codygman 12y agoI'd argue that you can rely more on powerful types because they lend more to the totality of your program. This is just a hunch/intuition though. If I'm wrong, I'd be glad to know why and how so I can correct that ;)
- latiera 12y agoI know CL, I know Haskell. Really what OP said has nothing to do with refactoring (which is indeed painless in Haskell) but more to do with interactive programming. Haskell is not terrible at interactive programming, but compared to Common Lisp and Smalltalk, it's garbage. And this is exactly why it feels so kludgy and awkward when one tries to do bottom-up programming and organically evolve his program, the standard way of programming in CL and Smalltalk since they are image-based languages that are designed for exactly this. This is one of the benefits that one with no prior experience in working in this way can quickly attempt to dismiss, but it's really THE most important reason for someone to use CL rather than Haskell. By having a language that allows you to program in a live environment, from the inside and keep the entire system running at all times, you become one with the machine. The feedback loop is kept extremely short, and you're in a constant state of flow. It's too bad when people dismiss CL (and Smalltalk) based on trivialities (type systems) that are completely irrelevant in the grand scheme of things. Writing code in Haskell to me feels like a sterile, boring process similar to working out mathematical proofs. That's not to say that Haskell doesn't have its place. When the domain is well-defined and I know exactly what I want to do and how I'm about to do it, I'm more inclined to reach for Haskell or Ocaml than Common Lisp. This is not the case for me most of the time however. When I program for myself, I find that I often have a general idea of what I want to do but no specifics in mind. It is then that I reach for Common Lisp in order to flesh things out and get inspired if you like. Or, similarly, when I'm doing a project that is hard, the domain uncertain, something with solutions that are not obvious ahead of time. Common Lisp and Smalltalk shine for these sort of problems, there is nothing else that comes close in my opinion. Common Lisp but not Scheme/Racket I hear you say? Yes, this is indeed the case. Racket is just bad at interactive development of the kind I just described, because its developers deemed image-based programming 'too confusing' and removed all support for it from the IDE. This should also explain why it's not mentioned at all in the original article. Moreover, I find that in order for someone to truly appreciate how empowering image-based development is, one needs years of writing code in traditional non-image based languages. Which is why the best feature of Lisp in my opinion is swept under the rug by most newbie programmers who try out Lisp. They lack the experience to realize what they are missing. Which is also why the original post author completely misses the point. The real power of Lisp comes from what I just described, not from 10 or 20 bullet points that one needs to side-by-side compare with other languages. By his admission he is a newbie programmer, and a newbie to Lisp too, made evident by his misunderstandings about the Common Lisp macro system vs Scheme "hygienic" macros. Hopefully he will grow and learn to appreciate Lisp for what it really is. Finally, writing code in Common Lisp or Smalltalk makes me feel like an architect of my own private universe. This is exactly what programming should feel like, an organic process, fusing mind and machine together if you like.