Wrestling Javascript with Love

Writting Java would be much more slower than program in Javascript, plus running a virtual machine is a huge burden to a webpage.

The Java culture is very uniform, and is influenced by the big iron, how people write code in corporations and the like, is the new COBOL language (read this in the most positive light possible). I mean, Java is the tool to write code in a big company with other 200 programmers, to create code that will still be in use 40 years from now… but I am not there, and the burdens to be there are huge.

For me to write in Java, I would need to practically reinvent the language to resemble more smart languages like Python or Ruby. True Java programmers would have a hearth attack just looking at my code.

Well, while Java is certainly widely used in huge enterprise environments, that doesn’t mean that it’s a hindrance in a more agile environment.

Hell, look at minecraft… That guy used Java to build his game in a team of just himself.

Some folks who come from a scripting language background look at things like typing as a weakness, but for any project of any appreciable size, it’s not a weakness at all. It’s an immense strength because it lets the compiler do the work for you… The lack of a lot of those features in languages like Ruby is exactly what has caused so muhc pain for so many folks who try to scale Ruby projects to large systems.

If you’re really addicted to that kind of stuff, you can always look at something like Scala… which is basically a set of Java libraries which enable practices from languages like Ruby or Lisp.

In terms of the burden the VM puts on the machine… you’re already running a VM. You’re running the browser’s Javascript interpreter. The chief difference is that you’re getting far, far worse performance compared to real compiled Java.

But hey, to each his own. Ultimately, for me, the answer to “What’s the best programming language” is “The one that lets me do my job best,” and I use a number of different languages for various tasks (although I do tend to use Java the most, by far).

Sometimes the answer to what’s the best programming language is “whatever one I’m being paid to use.”

Certain elements of Java, like Swing, have a fairly steep learning curve… but most of the language is extremely intuitive and easy to learn. I originally came from a C++ background and became competent in Java in maybe a week. It was trivially easy to use by comparison. Certainly, if you think C# is easy, then Java is easy, because C# is just a copy of Java with a few extra new toys thrown in.

I don’t think we’re saying Java is a bad language. If I had to code some random application, odds are I’d use Java, though thank god I’m not a professional programmer anymore.

But I do claim that applets are too heavyweight to use for most web usages that Javascript is good for. On the other hand, if I was coding a roguelike, that would be heavy enough that an applet wouldn’t be all that bad a thing to use.

Sometimes programming is like writing your diary in a very dark room, and a bit of light helps.

The problem with strong typing is that you have to dedicate a whole 50% of the effort to make the Typing Gods happy, It also make languages very slow to write for. And also may obscure what the programmer was tryiing to do.

But all of this is subjective, and probably is true that in big proyects you need strong typing. Like a big city you need traffic laws.

If you’re really addicted to that kind of stuff, you can always look at something like Scala… which is basically a set of Java libraries which enable practices from languages like Ruby or Lisp.

But… why? I already have Javascript, that sorts of already do all that for me, plus I don’t have to create something weird to run my code in a browser.

In terms of the burden the VM puts on the machine… you’re already running a VM. You’re running the browser’s Javascript interpreter. The chief difference is that you’re getting far, far worse performance compared to real compiled Java.

Javascript is really fast, and everything else you do in a browser is much slower. Javascript in a browser don’t have the burden of a virtual machine. Creating a “context” in Javascript is expensive, but is done in memory, probably cloning already instantiated objects. With Java, it probably need to move 200 MB of dll files, plus parse cfg files in different formats, like xml. Starting a java plugin seems some orders of magnitude slower than what it cost for a browser to create a Javascript context.

But hey, to each his own. Ultimately, for me, the answer to “What’s the best programming language” is “The one that lets me do my job best,” and I use a number of different languages for various tasks (although I do tend to use Java the most, by far).

Sometimes the answer to what’s the best programming language is “whatever one I’m being paid to use.”

Yep.

Certain elements of Java, like Swing, have a fairly steep learning curve… but most of the language is extremely intuitive and easy to learn. I originally came from a C++ background and became competent in Java in maybe a week. It was trivially easy to use by comparison. Certainly, if you think C# is easy, then Java is easy, because C# is just a copy of Java with a few extra new toys thrown in.

Java and C# are languages in my “TODO” list to learn. To be honest, I have written a middle size app in Java, but without really learning the language.

I’m sort of amazed to see people saying things like that in 2012, both due to the renewed appreciation of Javascript as a solid dynamic/functional language, and increased loathing of Java as a clunky, too-verbose COBOL-ish sort of thing.

The problem with strong typing is that you have to dedicate a whole 50% of the effort to make the Typing Gods happy, It also make languages very slow to write for. And also may obscure what the programmer was tryiing to do.

Eh, perhaps we may just not see eye to eye on this… To me, you gotta make the typing Gods happy in any language. The difference between a strongly typed language and a weakly typed one is not whether or not things break when you screw up the typing… The difference is whether it breaks at compile time, or runtime. And this is why languages without typing tend to have scaling problems.

But… why? I already have Javascript, that sorts of already do all that for me, plus I don’t have to create something weird to run my code in a browser.

Well, generally I’ve found that Java is just much nicer to work with than Javascript. It has a much larger set of built in capabilities.

But again, if you’re not running into such issues, and Javascript is able to do what you need to do, then this is moot.

Well, the reality is that there isn’t actually increased loathing of java across the entire industry. It’s just certain groups of people.

And in the 2000’s, you saw a rise of languages like Ruby… “Oh man, it’s so fast to code!”

But what you then saw in more recent years, is that folks tried to scale that stuff up to real systems… And they failed miserably. Horrific, colossal failures. And suddenly it wasn’t quick… That’s why you had groups like Twitter convert their backend from Ruby to Scala.

And really, the argument was always pretty freaking absurd anyway. “Oh man, you need to have all that boiler plate code around a class!” Who cares? The IDE creates that for me. It’s an absolute non-issue. Being forced to think about the types of objects is not a deficiency. It’s merely something that you need to do in any language… it just that a language like Java will tell you that you did it wrong, rather than just exploding at runtime.

In virtually all real-world cases, I prefer a statically typed language… Because it will help find errors sooner (which is always better), and because I have never, ever said, “Oh man, I am spending so much time typing my variables.” The only times I’ve found significant benefit in dynamically typed languages would be in Lisp development back in the day, for some kind of crazy runtime reflection and code modification stuff. But at the same time, I’ve since done similar operations in Java (using some aspects of the language which are admittedly not widely used, and certainly more difficult to do those certain specific tasks in compared to Lisp or Scheme).

Ultimately though, I appologize for the derailment. As much as I like talking about languages, Teiman’s description of his game development is more interesting.

I’ve been coding in primarily strongly-typed languages for many years, and it’s always annoying when I try to do something in javascript. Last week I made a simple little canvas thing (less than 100 lines) and it took me like 10 minutes to figure out why nothing was moving. I mistyped the name of a property and it was adding NaN to my velocity, making it 0. That would have never passed the compiler in C# or Java. I also realize that if I was more used to languages like javascript I’d probably be able to identify the problem much more quickly.

Using JSLint or JSHint or another pre-processing code analyzer helps a lot with those sorts of issues that actual JavaScript runtimes do a shitty job of detecting, though even these tools don’t solve the problem completely.

But, yeah, static typing is far superior, especially if the language is smart enough to do type inference. Anyone who prefers full dynamic typing is a fucking weirdo.

The least interesting difference between Javascript and Java is whether it’s statically typed.

I’ve been programming heavily in pure JavaScript for a few years and love it. Thriving dev community pumping out cool stuff every day.

A whole audio synth in pure JS & HTML5.

Well, that’s a psychological effect, right? You’ve been swimming in the flaws of your current language for so long that many of them are invisible to you, but the flaws of a new environment stick out sharply. Conversely, because the strengths of the new environment haven’t been available to you, you’re not used to them and aren’t taking advantage of them.

Could you point out some of what you consider to be the benefits?

Well, “compared to what” is certainly the question.

Compared to Java: A functional orientation, with all that implies. Hashes as a first-class language structure, including a nice syntax for object literals (and you’re thinking “I never use those” – well, no, of course not, which is my point). No compilation, which means faster iteration time between coding and testing. With Node/Express, a clean and elegant server-side framework with low conceptual overhead.

Compared to Lisp: A familiar C-style syntax. Much better libraries. Mindshare among developers.

Yes. I didn’t mean to try and say I was annoyed because JS in inferior or something. I meant because I am so used to C++, Java, C#. Having used C# every day for a year now, I would find it very difficult to go back to Java. But 2 years ago I would have told you that I loved Java. Java didn’t change, I did.

Not to further detour this awesome thread, but what is a better workflow for quick javascript projects? Currently I use something with syntax highlighting (notepad++ or whatever) and just run it in chrome. I use chrome’s console and breakpoints for debugging, but that’s it. I’d never heard about JSHint or anything like that which CCZ mentioned above. Anything else I should be aware of?

edit: oh and I’ve used jsfiddle a few times, but since moved to just using chrome.

But maybe it’d be better to be more concrete about what I mean. Let’s say you had, in Java, a class “Retailer” and it had, among other information, a “Locations” list that had a bunch of information about various store locations – address, phone number, store ID, avg daily revenue, general manager’s name, etc.

Now you’ve got a web page where you want to display contact information for locations in a selected state, and when the user selects “Missouri” from a drop down list, you want to return the phone number, email address, and store ID for each location where the state is “MO”. So your web page is going to make an AJAX call to your server and get some JSON back with that info. Let’s leave the JSON part out of it for now, and just talk about the method you’d write to do that logic.

In Java, how would you write this method? Maybe something like:


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;
  }
}

public class Retailer {
  // all the other code that was already there

  public List<LocationContactInfo> getContactInfo(string searchState) {
     List<LocationContactInfo> returnList = new ArrayList<LocationContactInfo>();
     for (Location l : this.locations) {
       if (l.state.equals(searchState)) {
         returnList.add(new LocationContactInfo(l.storeId, l.phoneNumber, l.email));
       }
     }
     return returnList;
  }       
}

Right? I mean, even if you wouldn’t write that exact code, it’d be something in that shape, yeah?

An idiomatic Javascript way of doing it would be:


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 }
  });
}

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.

And very little of this has to do with dynamic typing, though some does. It’s actually interesting to note that the C# version would be a lot closer to the Javascript than to the Java.


public class LocationContactInfo {
  public int StoreId { get; set; }
  public string PhoneNumber { get; set; }
  public string Email { get; set; }
}

public class Retailer {
// all the stuff that already existed

  public IList<LocationContactInfo> GetContactInfo(searchState) {
    return this.Locations.Where(n => n.State == searchState).Select(n => new LocationContactInfo() {
        StoreId = n.StoreId, PhoneNumber = n.PhoneNumber, Email = n.Email }).ToList<LocationContactInfo>();
  }
}

It’s clunkier than the Javascript because you still have to define the new type, even though it’s hardly a “real” type – that’s the downside of the static typing – but the functional stuff and the object initializers are there.

Basically, my belief, increasingly, is that one of the goals of a good programming language should be to get all the accidental cruft out of the way so that you can focus on the essential logic of what you’re doing. Javascript is generally good at doing that, in a lot of contexts; Java is phenomenally awful at doing that (though it’s better than C++).

You can get even closer to a javascript style in C# by using anonymous objects, implicit typing and the dynamic keyword. Though I wouldn’t do it as others have said, it doesn’t really play to the language’s strengths. Also it comes with some gotchas like no extension methods and lambdas. Well, I guess that means you’d lose .Where and .Select so maybe not closer afterall. heh. :)

You can do this, but most of the time it’s not a great idea. We sometimes send anonymous objects down to javascript in mvc, but for consumption in C# it would be crazy.


public object GetContactInfo(dynamic searchState)
{
  return this.Locations.Where(x => x.State == searchState).Select(x => new
  {
    StoreId = x.StoreId,
    PhoneNumber = x.PhoneNumber,
    Email = x.Email
  });
}

Yeah, I deliberately tried to write that the way that a sane developer writing idiomatically in the language would write it. C# has dynamic and anonymous types ‘n’ stuff, but if you were writing C# code, you wouldn’t use them for something like this – maybe you’d use an anonymous type if you were converting it to a JSON string right in that method and returning the string, but if you were returning the actual data structure, you’d almost certainly do it the way I did, even though defining that new class seems silly.

And leaving new types aside, there’s no reason you couldn’t return a hash of the values, either (which is essentially what that Javascript is doing), except that C# (like Java) doesn’t have any first-class syntax for hashes, and no libraries ever use them for anything, and they fit awkwardly with a bunch of stuff, and therefore it’s just not done.

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.

It’s not hard. It’s tedium. It’s code that you have to slog through reading, and every change that affects that requires you to write more boilerplate code, and modify piles of boilerplate code. It’s what makes Java programming feel like programming in mud – you have to churn out a ton of boilerplate for every bit of real coding you want to do.

I cleaned it up a bit… for instance, you were constructing new location objects for no reason.

I wasn’t returning location objects. The location objects have a bunch of other fields on them, and I was specifically returning a smaller object with only the three fields. (Remember, this is getting sent to the client via JSON, so there are bandwidth concerns, plus at least some of that information is information that shouldn’t be sent to random web clients.)

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.

You keep asserting this, but there’s little reason to believe it’s true. Yes, Twitter moved away from Ruby – for performance reasons, not code quality reasons, and Ruby is notoriously slow by the standards of dynamic languages. Node, on the other hand, is considered something of a speed demon, and is likely to be faster than a J2EE stack by a mile. (It’s worth noting that Twitter did not move to J2EE. J2EE is slow.) And anyway, you’re almost certainly not making Twitter.

As for the difficulty of finding bugs, it’s just not that bad. First, most people don’t tend to make type errors. There are reasons to like strong typing, but “catching my frequent mistakes” isn’t generally one of them. But most importantly, you write unit tests! You’re doing that in Java, too, if you have any sense at all, so the set of things that your compiler catches that your unit tests won’t is vanishingly small.

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 speed of your feedback loop is critical. Make a change, test. Make a change, test. The more delay there is in this, the more it feels like programming in mud. If you’re used to this and program in Java all the time, you’ll unconsciously work around this by making a ton of changes and not testing them out until you’ve done a large unit of work, because it’s too “heavy” to keep doing that. I’m sure to you the idea of making a two-line change, and then checking it to see if it works sounds crazy, but that’s a perfectly sensible way to work if you can get that instant feedback.

The bigger reason for an interpretted language, is that it makes self modifying code easier to develop

Um, yeah, no.