> I don't hear a lot of complaints from the Python or Ruby camps about how much they desperately miss static typing. It would have to be via a seriously 'get out of my way' type-inference for me to want to allow all that ugly back into the language.
I can't speak for anyone else, but I do miss static typing when I'm using languages like Python and JavaScript for web work. However, I think it would take more than just type inference to make a strongly/statically typed language that was good for the same jobs. You also need powerful tools for parsing freeform input such as JSON or XML, both to bring valid input into your static type system with little effort and to give as much control as you need to recover from unexpected input.
The first problem is solved by many languages; the second one, not so much. I think that is part of why dynamic languages are so popular for web development today.
As an aside, there is also a design/architectural question here. The theoretician in me says of course I should parse and validate all incoming data as close to the point where it comes into my server-side code as possible, so everything internal is clean. This fits nicely with the whole static typing thing. On the other hand, the pragmatist in me says that sometimes, particularly while prototyping, it's useful to keep the parsing and error recovery logic close to where the data will be used. That's much easier if you can just dump all the input into a nested array of hashes of objects of dictionaries of widgets when it arrives and worry about the details if and when you get to the code that cares.
With regards to you saying we're not there when it comes to tools for parsing JSON/XML:
Perhaps I'm not sure what you mean exactly, but I've been using frameworks and tools that handle JSON de/serialization for years now. For example, whenever building applications in ASP.NET MVC and ExtJS on the client side, I would use a project called Ext.Direct.MVC. All that does is set up a handler that automatically grabs specific types of requests, converts the JSON data in the request to an instance of a model, or any data structure that you expect to receive, and passes that created instance over to your controller automatically for you. So on the client you just call the controller with some JSON, and on the server you declare a controller that receives an instance of one of your defined models. That's it, you're done. The only time you'd have to so much as interact with the JSON serializer is when you wanted to return some data like a model -- but all this means is wrapping the model you're returning in a call to the JSON serializer and you're done.
Also, if your selection of languages/frameworks does not offer a tool like this, it likely does offer enough sub-components for you to be able to create a system like that in a day or two. EDIT: (or perhaps I am just making a bold claim here assuming that all language communities have at least one JSON serializer/parser as awesome as Json.NET).
In my personal opinion I'd actually say the opposite of you and claim that often times a language's type inferencing could be better. It's certainly not perfect in C# (not when compared to Haskell, or even F#), and I'm not even sure if it exists for Java.
Of course just about every language has a freely available library for working with JSON, and that is one of the main reasons to use JSON in the first place. 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.
Even if you have a library that can parse JSON according to some known format and give you back a nice object of some known type in your static type system, you still have the problems of how to describe that format and how to handle errors where the incoming JSON doesn't match your expected format in some way. 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.
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. It's just that architectural issue I mentioned before, where converting from a freeform format to a known object type in a static language essentially requires you to do all the parsing and error recovery up-front whether you want to or not. Perhaps someone has come up with a clever approach I haven't yet encountered, but I don't see any sign of it in the documentation I looked up quickly for the libraries you mentioned; they look downright painful to use compared to dynamic languages from the code snippets I saw!
> 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.
Sorry, I think we're talking across each other slightly here. I'll try to explain again.
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
{ "forename": "Chris", "surname": "Newton" }
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:
public class Person
{
String forename;
String surname;
}
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.
I don't want to start (continue?) another static-vs-dynamic-typing war, but I feel like I need to add my 2 cents.
For me the biggest pragmatic gain from using static typing is that your programs contain less bugs right from the start -- simply because many types of errors are detected by the compiler based on type information. Just to clarify, I'm talking real strong, static typing like in Ocaml, Haskell and the likes and not Java-style typing, which is not very powerful and imposes the cost of adding type information on the developer, whereas in the aforementioned languages the type inference pretty much does away with this problem.
This having said, I'd suggest taking a look at the new programming language: Opa (http://opalang.org). It complies with most of the requests of the author of the article. It's compiled (#2) and statically typed (#1). It allows easy interfacing with JS, C and Ocaml (#3). First class XML elements: yup (#4); case sensitivity: check (#7) and JS is automatically generated from Opa sources (#8). I happen to be writing a blog about Opa (http://blog.opalang.org) and would be very interested to hear what you think about it.
I can't speak for anyone else, but I do miss static typing when I'm using languages like Python and JavaScript for web work. However, I think it would take more than just type inference to make a strongly/statically typed language that was good for the same jobs. You also need powerful tools for parsing freeform input such as JSON or XML, both to bring valid input into your static type system with little effort and to give as much control as you need to recover from unexpected input.
The first problem is solved by many languages; the second one, not so much. I think that is part of why dynamic languages are so popular for web development today.
As an aside, there is also a design/architectural question here. The theoretician in me says of course I should parse and validate all incoming data as close to the point where it comes into my server-side code as possible, so everything internal is clean. This fits nicely with the whole static typing thing. On the other hand, the pragmatist in me says that sometimes, particularly while prototyping, it's useful to keep the parsing and error recovery logic close to where the data will be used. That's much easier if you can just dump all the input into a nested array of hashes of objects of dictionaries of widgets when it arrives and worry about the details if and when you get to the code that cares.