@jasongorman I’ve found that when working in languages with very expressive type systems, writing the types themselves also plays this role a bit.
Top-level
@jasongorman I’ve found that when working in languages with very expressive type systems, writing the types themselves also plays this role a bit. 18 comments
@jasongorman For me, it’s just like what you said about how tests force you to think carefully about behavior before you write the code. In the case of writing expressive model types, you’re forced to think carefully about the concepts/entities you’re trying to represent. @jasongorman For me, getting the model types right makes it easier to think through the behavior properly. The simplest example is nullability. If your type system can express that and enforce null handling, then that forces you to think about stuff like “how should this operation behave when property A is null”? I’d say sum types (e.g. sealed classes) where the compiler can check that you’ve exhaustively handled all scenarios is the next level of that beyond nullability. @jjoelson @jasongorman Or even better, replace nullability with Optional types and the API itself forces you to deal with those cases, you don't need a fancy schmancy null-checking systems 😉 @jasongorman This is like asking a TDD practitioner “how do you know what tests to write?” and the answer is the same. @jjoelson We write tests for end user outcomes. How do you know what types the model needs? @jasongorman By the same token, how do you write tests if there are no types defined anywhere? @jasongorman My original point is writing model types can sit alongside writing tests as an activity that clarifies what your system actually *is* and *does*. It sounds like you prefer to think in terms of *behaviors*, hence your focus on tests as the starting point. For me, modeling the problem data domain is a more helpful starting point because it’s difficult for me to think about overall system behaviors in such an abstract way without having types to organize and guide. @jasongorman This is interesting, because you seem to agree that writing the types and method signatures is a necessary prerequisite to writing complete tests, but of course if you stopped after writing the types and never actually finished the tests then you’ve already done a chunk of the thinking about the system’s behavior. My original point is that the more expressive the type system, the more you’ve achieved in terms of understanding what your code will do just by writing the types. @jjoelson In TDD, we work backwards from the test code. It tells us what types and methods we need, and we declare those types *only* when a failing test requires it. We don't write a single line of source code that isn't required for the test. The tests drive the design. The clue's in the name, really 🙂 @jasongorman @jjoelson @jjoelson @jasongorman IME that has as much of the discovery / improvisation aspect as shell pipelines @jasongorman @jjoelson |
@jjoelson I guess the question then is how do we know we need those types?