DEV Community

Discussion on: You Either Have It Or You Don't

Collapse
 
kspeakman profile image
Kasey Speakman • Edited

So, I have a round-about answer. I write in F# and in a simplified manner which mostly avoids the type puzzles created by Haskell. Instead the types are used more as validation (Option is very valuable to identify which fields are usable but not required when deserializing from JSON, for example) or to have assistance from tooling (exhaustive pattern match, autocompletion, etc). For writing business code, the clarity that types bring and the questions they force me to ask is very valuable.

However when writing infrastructure code, I sometimes think "this would be easier in Clojure". Because infrastructure code is often more general, so it needs more flexibility. I might not know exactly which settings I can pull from the environment vs a config file vs the command line. And then I may be able to run with modified functionality (or defaults) depending on which config values are present. The kind of typed code you have to write for this is very tedious. One of his statements to the effect of "if you used Maybes, then everything is a Maybe" fits really well in describing this scenario.

Another infrastructure example is the "context" object for APIs. It gives you the particulars about the request you are handling. It can be hard to create a single type that covers all the different resources or special situations you might have in your API.

And in both of these cases, things may get added or removed over time to support new features. And since they are infrastructure, structural type changes are breaking to everyone using it. In fact, many libraries for typed languages include a less-typed data structure for this kind of information. For example ASP.NET has a Configuration feature which keeps the data as a (string) key-value collection. Also in ASP.NET the HttpRequest type (a context object) is capable of storing arbitrary dynamic object values in its internal key-value collection. Both of which are to cover unforeseen cases that you may have in a non-breaking way. The difference here is that Clojure is designed to work with this kind of data. But in .NET it is not encouraged nor as well-supported. It can be a downright pain.

For us, using F# is well worth it since we mainly want to focus on the business use cases. And the types are, on average, a huge help there. But I definitely feel the other side of the trade-off in certain kinds of code.

Collapse
 
deciduously profile image
Ben Lovy

Wow, what a complete answer! It makes a lot of sense to think about "business" vs "infrastructure" code - and I think I've only ever personally written the former. I don't think I've had that experience you're talking about - I've always either been grateful for my type system or wished I had one. But reading this anecdote it makes perfect sense where that type of flexibility fits.

Thanks for your response!