5 ms·
I'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.
by bitwalker 9y ago
I'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 :)
- wellpast 9y ago> 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 This is the usual general claim from one arguing for using static type verification in a given situation, but this is pretty fuzzy statement, no? "Keep things sane." We need to have more clear reasons than that, don't we? In my view, the end goal in business is to optimize productivity throughput over time (i.e., make sure that we can deliver business value as quickly as possible.) But I realize this is not as simple as today's immediate throughput at tomorrow's throughput's expense. So there is this goal of keeping things maintainable (probably what you mean by "sane") -- but to be even more clear: it's productivity/delivery throughput we are talking about, no? And if that's the case then we have to really justify that the static type dance is truly giving us that overall throughput. How do you do that? What is your general decision process about when to introduce type verification and when not? To be specific, let's say I need to ensure that the value for my "title" doesn't ever exceed 80 characters. I imagine that even in Haskell you would make this a String, no? So you would defer that length constraint to dynamic validation/logic? (Correct me if I'm wrong.) Well, then why are you choosing dynamic verification in that case but for other cases like "publication-date" choosing to have the type checker verify that it is a proper date value? What is your criteria? In my experience programmers usually just do what is idiomatic or most convenient in their programming language. Okay there is a Date primitive, I will use that. There is no Title or MaxString<Length> primitive, so I will just use an unbounded String. In other words, it's not a like a reasoned choice. Which makes me think, in general, the reasoning behind using a static type language is more fuzzy than usual. But if you have even a loose criteria for why you pick static typing for a value versus doing the value's verification dynamically, what is that criteria?
- tome 9y ago> But if you have even a loose criteria for why you pick static typing for a value versus doing the value's verification dynamically, what is that criteria? The same as with the choice of anything: what feature to work on this week, whether to automate a process or keep it manual, whether to use JSON or BSON or Protocol Buffers ... It's a judgement call and it's not really possible to give a good answer in a Hacker News comment.