Really, quite a few of these hold outside of Haskell as well.<p>* "reduce the interactions between components by relying on pure interfaces"<p>* use purely functional data structures to model key parts of the world you're talking to. Model-driven design with easy to verify logic<p>* Avoid partial functions<p>Pure interfaces require you to declare <i>all</i> context, and it's arguably
all the context implicit in typical OO software that kills reusability.
As Joe Armstrong put it, "...the problem with object-oriented languages
is they've got all this implicit environment that they carry around with
them. You wanted a banana but what you got was a gorilla holding the
banana and the entire jungle."<p>* use types to encode the design into a machine checkable form<p>* picking a good data type (like a zipper) will make hundreds of unit tests meaningless -- improving productivity.<p>The point of static typing is to structure code in a
way that more assumptions can be expressed and <i>automatically checked</i>. A well-chosen
data structure brings with it all of its expected behavior.<p>* ensure components have 'axiomatic' interfaces -- reduce complexity by avoiding redundancy<p>* if at all possible ensure your core algorithms and logic are referentially transparent -- this will dramatically simplify maintainanace and QA effort<p>"Declarative programming clears the mind." - Sterling & Shapiro, _The Art of Prolog_