3 ms·
GHC is a bit of a pathological case, which doesn't make it less valid. I wouldn't really dare to estimate how much refactoring you need to do if you change, say
by ac 14y ago
GHC is a bit of a pathological case, which doesn't make it less valid. I wouldn't really dare to estimate how much refactoring you need to do if you change, say, one constructor of GenStgExpr, primarily, because I don't know the GHC codebase. In my work I have had instances when I had to change datatypes drastically and refactor the code accordingly. I'd say, in all cases the type system was helpful -- I just go to every error location (very easy with, e.g., ghc-mod), and it's invariably a pattern-matching case, so I fix a bit of code here and there (20 LoCs at most) and it all worked. But the thing is, of course, if you change your datatypes all the time even these kind of small changes will soon become tedious. But then if one programs in Haskell in a hacking mode ("meh, let's try throwing this thing in, maybe it will miraculously start working") -- it just won't work. Haskell requires one to think well, before programming -- that's why I love it. I think, in the end it saves time.
Another problem might be that the datatype you are refactoring is fundamental to your program and is used in most modules -- I think it's just short-sighted design. GHC, for example, has several different program representations (Haskell, STG, Core, maybe some others), so a change to one representation would only affect a part of the compilation pipeline (namely, the translation to and from that rep and the associated optimisations/analyses). But if you really need such a fundamental mega-type that will change during the lifetime of the program, why not write an easier to manage interface to it? Either use the record syntax or write setter/getter functions by hand. Just $ my $0.02 where my=id