Which is so much easier, for so many reasons. And it’s easier to maintain, too. If I decide that I want to also return the GM’s name, I can make that change here in one place, by just also returning that. In the Java version, I have to update that class to put in a new field and a new getter, update the constructor, and then update where I call the constructor.
So your argument is generally falling back onto the “it takes less lines of code to do X”.
While is is an extremely common argument, it’s really not valid in practice.
For instance, let’s take your Java code, and analyze it.
public class LocationContactInfo {
private int storeId;
private string phoneNumber;
private string email;
public int getStoreId() { return storeId; }
public string getPhoneNumber() { return phoneNumber; }
public string getEmail() { return email; }
public LocationContactInfo(int storeId, string phoneNumber, string email) {
this.storeId = storeId;
this.phoneNumber = phoneNumber;
this.email = email;
}
}
This is pure boiler plate code. The IDE will generate this entire section for you, other than perhaps the three lines specifying the actual members you want. The getters/setters and constructor can be generated through 3 mouse clicks. So, I don’t see this as being “hard”.
Ultimately, it comes down to this section:
public List<LocationContactInfo> getContactInfo(string searchState) {
List<LocationContactInfo> returnList = new ArrayList<LocationContactInfo>();
for (Location l : this.locations) {
if (l.state.equals(searchState)) {
returnList.add(l);
}
}
return returnList;
I cleaned it up a bit… for instance, you were constructing new location objects for no reason. And really, this isn’t (at least to me) any “harder” than your Javascript code:
var getContactInfo = function(retailer, searchState) {
return retailer.locations.filter(function(n) { return n.state === searchState }).map(function(n) {
return { storeId: n.storeId, phoneNumber: n.phoneNumber, email: n.email }
});
}
But I realize that this is a matter of preference. I’ve used all of these languages, and the languages they evolved from… And I’ve seen many folks who totally cling to one vs the other, simply because it’s what they know.
But at the same time, I’ve seen the big difference between a community like the Java development community and the Lisp development community… Java tackles large problems… Most of these other languages just can’t. They don’t scale well. The trivial time savings in not having to write an extra line of code or two ends up costing you far, far, far more time in practice down the line when stuff starts breaking and it’s much harder to figure out why.
In my mind, a lot of the advantages of languages like this are illusions. Certainly, in specific situations, comparison code can be written to make it look like you are able to write less code to solve a job… but those jobs are specifically focused on areas the language provides mechanisms for. And don’t get me wrong, this is why we should be able to use more than one language… because different languages can sometimes be useful. But at the same time, some of those perceived advantages are actually just deficiencies that have yet to be realized. Dynamic typing (and even if you don’t think that this is one of the “interesting” differences here, it’s certainly one of the most fundamental) can offer a temptation of not having to worry about certain things. But in practice you DO have to worry about all of those things for any non-trivial system… it’s just that the language isn’t helping you with those jobs. This isn’t actually a benefit.
Some of your criticisms are kind of silly, too… I mean, suggesting that an interpreted language is better than a compiled language because you don’t need to spend time compiling? Compiling stuff, during a real development cycle, isn’t sucking up a large chunk of your time… I mean, sure, if I take a source tree of 2 million lines and compile it from scratch it’s gonna take a few hours maybe. But I’m not doing that every time I change the code. If I’m changing code, then the compilation time is likely to be a few seconds.
The bigger reason for an interpretted language, is that it makes self modifying code easier to develop… at least in my experience. I’ve done this in Java too, but it’s infinitely harder than in a language like Lisp or Scheme. But I’ve literally never sat down and said, “Oh man, I wish I could just run this immediately without compiling it, because I can’t wait for it to compile.” Because 90% of the time, having the compiler find an error is going to save me some truckload of time compared to actually just running it and finding the errors then.
Perhaps in small systems these problems melt away… but for large ones they become serious issues. You want the computer to shoulder some of that work for you.