5 ms·
> For Rich's argument to resonate with me, I think I just need a good example of what he's talking about Let me go through some work I just went through. Scrap
by wellpast 9y ago
> For Rich's argument to resonate with me, I think I just need a good example of what he's talking about
Let me go through some work I just went through. Scrape web blog post, generate some semantic data about the post, send that data through some processing which perhaps infers some new facts, maybe discards some posts, then sends the data over the wire to be mapped and written to a searchable data repo. Which of course will be queried, read, and displayed in a web app.
This is pretty standard-fare programming in industry/web world.
I wrote this in Java, but here's my take: the easiest way to both implement and maintain this code is to model the web page data as a simple Map of facts -- properties with clear semantics ("author", "title", "content", etc.) and their values. The very minute that my scraper needs to introduce a new fact it does literally nothing from a code declaration point of view. It simply puts a new fact (say, "publication-date") into the Map. Absolutely no downstream code needs to be touched in order for me to do this. I just produce the fact/knowledge. That was just one use case.
Now to do this same thing with an ADT/class/record, I have to at minimum go declare that property in the ADT. But usually I also have to go update the ADT serialization code to make sure that it is writing this new property into the serial format -- the JSON, or what-have-you. Furthermore, on the other side of the wire, I have to make sure that guy is either using my ADT or map to his ADT, whatever.
Oh my gosh, this is just one use case and the non-ADT scenario asked me to do literally nothing to introduce some knowledge, some simple little fact, and the ADT scenario has me jumping through hoops to get my release out.
Mind you, this data-process-to-web-display architecture is very common in industry programming. And it is very common to find this jumping-through-hoops.
And we haven't even started talking about the webapp/display side of things.
Now I wrote this in Java, the whole way dodging ADTs and types where I didn't need them (ie, lean on Strings when in doubt), and using simple Maps. But even then the syntactic negotiation was quite large. Clojure embraces this map-centered/fact-centered view of the world at its core and this program would have been much much less lines of code and much much less cognitive overhead written in Clojure.
Now I know a static typer person is going to say, okay fine, but jumping through those hoops I've saved you a bunch of bugs. But I say no you haven't. Unless you go all the way with your types and have a Content type and a Title type ... because my bugs were to do with payload sizes and things like that. Things that even static typers will end up checking via some dynamic logic in their code.
- bitwalker 9y agoI'm not sure why one would ever use ADTs for the situation you described, I totally agree it's not a good fit, but it's not what they were designed for anyway. But based on what you've described either a plain StringMap, or if you need to store different data types, a GADT with different type constructors for each of the types which might be present in the data that you want to work with (i.e. String, Integer, StringMap, List, etc.). The StringMap is trivial, and the GADT requires declaration, but is straight-forward pattern matching/construction from that point onward, so I don't think either option impose any "real" additional cost here. Navigating/extracting datastructures via lenses or recursion/pattern-matching is clear and concise, definitely not onerous by any means. I'll gladly admit that my argument hinges on using a state of the art type system, but in my opinion, if we're going to debate the merits of static typing, then we should be looking at the best it has to offer. It seems like perhaps you haven't had an opportunity to work with Haskell or something like it (want to be clear that's not a judgment statement, and I'm solely basing this on your last comment, if you have, sorry about that!), which is fine, I mean, I only ended up learning some of it due to diving down the rabbit hole of type system research while designing my compiler - but if the first thing I had to compare a dynamic language to is Java, then yeah, it's no contest I would use Clojure instead. I think something important to remember is that I don't think one should be a "static typer" or a "dynamic typer" - dividing the world into right/wrong, good/bad, black/white is almost always the wrong point of view. If I'm automating something, or doing some exploratory programming, I'm probably going to reach for bash/python/etc.; if I'm writing a command line tool or simple service I'm probably going to use go; working on a concurrent system, I'm probably going to reach for erlang/elixir/go/pony/etc. - but if it's even remotely complex, I'm always going to favor the option with the best static type system, because I know it's going to help me (and anyone else working on the system, especially newbies) keep things sane. Over half of what I just listed do not have static type systems, but I still have a clear preference - it is possible to use the right tool for the job without compromising your ideals. Part of why I started working on my own compiler was that I wanted to design something that both provided the strong type system, while still functioning well as a "get shit done" language, something with the concision of Haskell, but the flexibility of ML (permitting both functional and imperative paradigms), a comfortable FFI, and good tooling, including the ability to run scripts interactively (for example, via shebang scripts). I haven't found a language that mixes all of that together in a way that satisfies me, which is why I still use a variety of languages for different tasks. So I guess what I'm saying is, try not to divide people into two camps - it's possible to live in both at different times, but still prefer one or the other :)