I love it when I can get the computer to hold my hand and limit my actions. Personally I feel the limits of my cognition and enjoy when the computer assists in proofing the correctness of my programs.
That way I can be more sure I don't do anything that breaks the program logic and that developers that come after me remain within the boundaries of correctness when modifying my code. Types don't help in design but they help in forming a coherent whole.
I've figured out there are two constraint systems I can use to effectively write correct programs. One of them is a typesystem and the second is set theory.
Granted, the most mainstream statically typed languages come with so much syntactical baggage and lack type hinting (C++, Java, C#) that they can effectively hide the elegance of types as a problem modeling tool.
Types can be used just as a non-value adding anal-retentive bureaucratic baggage but that's not how they should be used.
I'm professionally mostly a C++ programmer but did not really 'get it' until I familiarized myself with functional languages (Ocaml, F#) which helped me understand how to actually leverage a typesystem to help me write correct code instead of 'just using typedeclarations because the compiler is too stupid to figure out what I want to do'. To be precise, the languages themselves did not really teach me that much but the learning materials I used with those language did.
When I need to do something small data processing in a jiffy I usually pick Python. For small programs few-liners in dynamic languages are usually a win.
What do you mean with set theory? I'm asking because languages like Ceylon and Whiley have union and intersection types which are basicially set theory.
What I mean that I first model a particular problem on pen and paper as a group of set operations and identities and then implement that using container operations. I.e. a set as a container, or a particular subset of the elements in the container. I totally depends on the program whether that simplifies things or not.
But for instance, I usually find that rather than adding lots of state variables to entities I model state as those objects belonging to various sets. I.e. store object Id in a list pertaining to a particular property.
This way subsystems can be implemented in a non-invasive, and extensible way. The set operators (union, difference etc.) do not need to be implemented explicitly, rather just figure out what is the most simple isomorphic routine to compute the output for that particular operation.