| > However, the rendering or parsing in a dynamic language like JavaScript or Python typically takes one line of code. The equivalent in something like Java can be horrible. [...] you still have the problems of how to describe that format. I'm not familiar with Java, but in the scenario I illustrated it took 0 lines of your own code to receive a JSON structure, and one line to return one. That's outside of defining the structure itself (creating the class; what I think you mean by "the problem of describing the format"), but generally you'd want to do the exact same thing in a dynamic language to make working with the structure easier. Example: you still define model classes in a Django app. > ... and how to handle errors where the incoming JSON doesn't match your expected format in some way. I don't see how you wouldn't have the same exact problem in a dynamic language. You can't just receive input and know magically what to do with it, you need to have the input be in a defined/expected form in order to process it. This to me is outside of dilemma of dynamic vs static because it is a problem in both approaches. > I suppose you could simplify common cases by determining the expected format using reflection if your language supports it, but that's not going to be powerful enough to cope with the general case without providing some sort of metadata as well. Right, in the scenario I gave the framework looked at the signature of the controller, saw that it expected to receive an object of such and such type, and told the serializer to use the JSON data to create an instance of that type. I'm not sure what more metadata would be needed to make that work? I suppose if you get a parsing error you can just use the exception handler in your client code because the client submitted data in the wrong format, etc. > In short, I'm still waiting to find a library that can parse arbitrary incoming JSON within a statically typed language without at best requiring the programmer to repeat structural information that is already implicit in the code that uses the resulting object. Defining a class once and saying you expect to receive an instance of it is not "repeating structural information" in my opinion. I can only see it as being "repeated" if you look at the initial JSON data structure as sort of the type itself. I personally look at the role of JSON to be a "data container" and not a "structure descriptor", but if that's the way you like looking at it, well then yeah, dynamic typing is going to be your best bet right now. The closest I can think of is Haskell's type inference which constrains types based on how they're used in the function, but even then the types have to be defined at compile time, and it will not just create one for you that matches what you're trying to do at run time -- it just accepts already defined ones based on whether they meet the constraints gathered from the code. |
I think the most awkward thing about working with freeform data in a statically typed language is a timing issue. It's not that you don't need to do things like error handling in a dynamic language but you do in a static system; it's that in the dynamic language, you can typically choose when and where to do it, while static typing effectively forces you to do some of the heavy lifting up-front to convert the freeform data into types within your design in the first place.
You seem to be considering as your main example the serialisation of data between two sides of an app where you maintain both sides. Fair enough, that's one use case for something like JSON. But consider what happens if you want to use it as a simple interchange format so that your code on one side of an HTTP link can communicate with someone else's code on the other side using a well-specified protocol.
Maybe part of the incoming JSON says
but what you really want internally is to look up something from a database using those values as key.In a dynamic language, you can typically just pull out the strings when you want them, plug them straight into your database API, and get the result you care about. If the values were missing or invalid, this is going to fail, but maybe it was going to fail anyway if the database didn't contain a matching record and so you've already got all the error recovery code you need in place.
With a static type system, in contrast, you probably need to parse the JSON into some type within your system as soon as it arrives. You can basically do that in one of two ways. One is to convert the JSON into some sort of general JSONObject/JSONArray/etc. classes, as for example the basic Java JSON library from json.org does. In that case, you retain the structural flexibility, but you also haven't really gained anything from using a static type system because you still have the hassle of manually navigating the resulting tree and doing all your type-checking later, which is a chore. The alternative is to parse the JSON into a more semantically meaningful type right from the start:
That's nice, it gets the data into a format we understand, and if the parser can use reflection to figure out what kinds of fields to look for and what types they should be, so much the better. But now I'm stuck with this other class to maintain, tied to the external interface of my code rather than however I model things internally. If I want to handle errors gracefully, such as receiving text data where I expected an integer, I have to specify how to do it at that stage (which is where the metadata issue comes in if you're trying to use reflection to generate your parsers automatically). If I later change my external JSON protocol definition to add another field or (worse) change the structure a bit, I have to reconfigure my corresponding set of classes to match.Now, I'm not saying this is necessarily a bad design. As I mentioned before, I think as a general principle it is usually best to validate and convert data as soon as it comes into a system anyway. However, for the kind of rapid prototyping development process that is widespread in web development, that kind of formality can get in the way in the early stages, and I think that is one reason that dynamic languages are popular for this type of work.