There are problems with this idea in that- every js engine will have a different AST structure for optimisation reasons, and making the AST a standard rather constrains optimisation efforts- or forces implementors to include two seperate parsers.
A bytecode standard is a decent idea, but I worry that it would be "good enough" for nearly everyone. What I think we really want is something more akin to what we have for native development: choice.
We should have things like JVMs for the browser (cached on the client-side, no doubt), but we should also have non-portable code for people who want to do things that cannot be done portably. A bytecode standard cannot be all things to all people, because some people need to do things that can't be done on some platforms.
If you really want everything to move to the web you need to expose vector math instructions for video encoding, you need to expose CUDA for scientific applications and so on. You need to be able to ship machine-code to the client where it can run (properly sandboxed, no doubt).
Of course, if you want everything to move to the web there are bigger problems to overcome - HTML and CSS aren't really suited to application development, the filesystem APIs are not sufficient, and there's still the problem of getting GUI applications to compose well...
No, there aren't. There is an entrenched bureaucracy and a load of fanboys who can't see past what is to what could easily be, all attempting to justify the current sorry state of affairs or ignorant of what's what.
Look, if javascript, with all it's insanity, can be standardized across browsers, for the love of pete, a simple stack-based VM can be too. And then everyone can go to hell in their own way.
Admittedly, people will stop using Javascript the second there is a viable alternative. I regard that as a feature.
Ignore reality if you want to. It's just never going to happen. Java had its chance. Java had every possible chance. Java had the advantage of making a deal with Netscape to purposefully cripple javascript to help promote Java. Sun tried for a decade, trying and trying to make Java the defacto web application language. Sun tried and tried to put its java VM in the browsers. And it lost. Java lost. Javascript won. End game. Being in denial about it won't change it. Trying it again isn't going to change the undeniable reasons that Java did in fact lose. Insisting that a VM is the best way to make web apps won't change the reality that we explored for years and years that it just simply isn't. It didn't work. It can't work.
"If I wanted a safe intermediate form, I would look at arithmetic
coding techniques that self-verify (so that you can't express other
than well-formed programs), not bytecode and not JS source. It's IMHO
very unlikely that TC39 will standardize a bytecode for JS. An AST
encoding has better chances and better properties including self-
verification and view-source-ry."
We need a standard wire format for code to be run on browsers. Fortunately we have one: it's called JavaScript. If you look at the internals of that format, it happens to be designed to be written directly by humans, but if you find that design suboptimal (and it would be surprising if it wasn't, considering it was put together on a ten day deadline with contradictory requirements) you can ignore it and just treat it as object code to which your favorite language can be compiled.
Doesn't Google make some internal use of a tool chain that compiles Java to JavaScript? And then of course there's Dart and CoffeeScript. I'm sure there'll be more.
You can compile anything into anything, but for the vast majority of languages, the easiest thing to target with sane semantics is a virtual machine, not a crazy half-baked language (that I end up coding in for about 40% of my day.) A bytecode standard would free us from the crazy design decisions of javascript, give us source-level debugging, etc. And it wouldn't be that hard, given all the fine examples of VMs sitting around.
My sense is that the people that suggest javascript as a compilation target really don't want competition for javascript in the browser.
> A bytecode standard would free us from the crazy design decisions of javascript
Not really, because most of the complication and mess is in the document object model, not the language syntax. How do you propose to solve that problem?
> My sense is that the people that suggest javascript as a compilation target really don't want competition for javascript in the browser.
You sense incorrectly. I'm not working in that area, I don't have a dog in that fight. I just think it's a good idea to point out problems with a proposed solution before somebody goes off and puts a lot of work into trying to implement it.
The problem with JavaScript is, somewhat paradoxically, too much flexibility. There are no standard language features for very basic things like namespaces and modules, also what it provides for OOP is so confusing that it makes people want to roll their own OO system from scratch. Objects as dictionaries and first-class functions make it possible to implement those features in hundreds of ways and almost every JavaScript program tends at least in some places to use some own, original solution for one of the very basic problems of structuring programs, because it is so easy to built one. It is good that this is possible, it is bad that people _have to_ do this (or choose one of the countless existing solutions) before they can actually write the program they want to write.
A lot of the problems would go away if the following was part of the language and present in every browser:
* namespaces/modules
* a sensible OO system people would actually enjoy using
* the ability to require/import/include a file/module
* the functionality Underscore.js provides
Then, at least the basic structure of the code would be consistent across programs from various people, and I wouldn't have to work out the details of yet another OO system, yet another way of just laying out the code across functions/objects each time I want to read another JavaScript program or yet another way of doing function () {}.bind that works across the browsers (here the problem is also the long time it takes for the majority of people to install a browser new enough to adopt the revised standards). And it's not only about reading code, how do you write an object-oriented refactoring tool if every program realizes OO in its own distinct way?
The situation is probably slightly better with server side JS where you are free to adapt the newest version of the language/runtime and also the server-side frameworks at least to some extend tend to encourage to use a common structure for all the modules.
Your 4 points are exactly why I always use Require.js, Backbone, and Underscore in all my large projects.
Require.js solves point #1 and point #3.
Backbone solves point #2.
Underscore solves, well, point #4.
In my experience, the other important thing to maintain coherence and sanity while creating large JS apps is to have a system that makes dependencies between modules very, very clear. Require.js basically also does that for me; it requires every module to define their dependency on other modules on top of its file.
I highly recommend people creating large JS apps to at least check it out : http://requirejs.org/
Let me explain to you the two large projects that I'm currently working on that are both using Require.js (it's hard to explain one without the other):
The first is basically a web framework that lets you compose a fully working website from a whole slew of independent, pre-built, unique components. Each component is made of Require.js modules (like its own HTML, CSS, JS). This isn't exactly the largest project, but Require.js really comes in handy with its ability to conditionally load modules (or components, in this context.) because you simply won't use all the components in the system, and also its ability to treat pure text file as regular modules (for HTML and CSS part of the components).
The second is a visual drag-and-drop web builder that lets you visually build a working end product of the first project that I mentioned. This is a large project simply because there's usually quite a lot of that you have to do in order to make a completely visual system work. I simply can't imagine building this system without explicit module dependency that require.js enables.
I think a better starting point is defining how large does something need to be to be significant. Otherwise we are nothing better than the guy in the back of the room shouting "Does it scale?", which given the amount of context in the question renders it impossible to answer.
The ability to enforce and optimize modular Javascript is one of the primary benefits of Google Closure Compiler, I've seen. I've only used it for one project so far but I can't envision writing another Javascript project without it.
I believe an underrated factor is the quality of tools (IDEs) available for the language. E.g. imagine refactoring a 50mb source code C# or Java application without the help of tools like Visual Studio/Resharper or Eclipse? I remember trying to write a java app in java 1.0 with just a text editor and the command line compiler - it was painful as hell, but things have progressed massively since then..
Being an OOP language, the interaction between modules is very explicit. This helps weed out bugs, since "what you wrote" may look close to "what you meant", but is ultimatly violating some rule of the system. This is one of the reasons why I find OOP languages good for large, complex systems, but not for small, hacky programs, since I can't hack around things to implement "just what I want". Javascript defintely fits into the latter category, and requires some good engeering for large projects.
I know what you mean and I agree that when used correctly OOP can achieve great modularity, but an OOP-capable language by itself can't protect you from spaghetti code just as horrible as any other non-OOP language could produce.
I wonder if we all agree what "large programs" are. Our team, for example, we are developing a "large program" in Java (Spring, JSF). It's 13'200+ .java files and total 54mb of source code + about 90mb of third party .jar (open source) library dependencies.
I don't think you could grow to that size codebase with Javascript.
Not that I disagree, but in my experience a lot of the code in a Java application is just a workaround for the poor expressiveness of the language. A lot of the stuff one has to do in Java to get halfway decent encapsulation/abstraction is just not necessary if you use a more expressive language and write code in a more functional way. Not that JavaScript makes that particularly easy or that it's even a nice language, but it is more expressive than Java. With first class functions and closures alone a lot of the Java boilerplate just vanishes. Not that I want to defend JavaScript, I personally think it's a horrible language, especially for large programs. But I think Java seriously suffers from lack of expressiveness which results in an explosion of classes to implement convoluted design patterns and such. I hope it gets better with Java 8.
I always found this argument lacking. In any language you can build the necessary abstractions for higher expressiveness. Sometimes these reach things like auto-generating code from a DSL, but in the long run if a good team is working on a large project, I can believe the amount of code can be 2-5x vs a more expressive language, but not 100x.
I agree with the 2-5x comment, but I don't think this is the right way to look at it.
Taking it to an extreme to demonstrate the point - a good team working on a large project could also just implement a new, more expressive programming language than Java and use that to implement their application.
The whole point of language selection is to begin with a more capable toolset.
Yes, if you include autogenerating code from a DSL, of course this is true. See Greenspun's tenth rule. But if you have to implement a custom DSL to achieve your goal obviously the language isn't expressive enough to do it. But I agree that the factor is probably not as high as 100x.
I don't HATE Javascript. It is a rather limited language. Especially if you're used to the standard Java/C#/C++ way of doing OO programming. Then again, sometimes I just want to instantiate a new object without having to say:
Dog dog = new Dog();
I'm lazy and I find that sometimes expressing myself in JS is just what the doctor ordered. But with the lack of a type system, I can get pretty frustrated.
As a couple others have said, you likely wouldn't need a codebase that size in JavaScript, even for an equivalent functionality, because of the type of programming the language allows.
A bit OT, but it might prove the point. I'm a Groovy enthusiast, and have done this exercise a few times. I'll give a presentation of Grails - basics of Grails, basics of Groovy, then demonstrate a Grails app. I'll walk through all the functionality of the app, then ask the Java developers in the audience for a guess as to how many lines of code they expect the app takes.
I clarify I'm asking for lines of code that I had to write, not necessarily in supporting libraries and such. I still get estimates from the Java devs of 25-30k LOC most of the time. Sometimes someone will be brave enough to estimate 15k. The real answer is closer to 6k.
I agree that JS code will generally be shorter than Java code because 1) you don't explicitly describe your types, and 2) JS is more expressive and there are things that you can just do more neatly.
However, there are many classes of code and #2 applies more to some than others. If you are writing something algorithmic like Peter Norvig's famous spell checker[1], the primitives of your language make a big difference. On the other hand, if you are writing something that is larger but of lower complexity where your code is more like configuration of a bunch of pages, this makes less of a difference.
Also, it's at least possible that the people who see your code assume a higher standard of maturity than your 6kloc has. We've all tried creating an apparently complete app rapidly, only to work on it for ages afterwards, implementing fault tolerance, graceful degradation etc. etc.
anyone has evidence of similar projects done in java and javascript showing how js is much more expressive?
Sure, the lines end up less wide, but while you gain something by using function() over inner classes, you also end up reinventing package declarations and visibility all the time, so I don't see a clear advantage of one over the other.
(notice: I do understand people will generally do things in Java that they won't in JS, such as adding setters and getters, but I have seen that done in plenty of "big" js libraries, so I doubt that counts.)
Good questions, and no. Anecdotally, talking to other Grails developers - ones who have switched from Java - they all acknowledge that they write fewer - often far fewer - lines of code.
I agree on the point that people may just be bad estimators, but I was assuming at least some of them have done approximate LOC counts on their own code from time to time to get estimates. I do.
Agreed. And given that he's just taught the basics of Groovy to the audience, the likelihood of them being able to accurately project how many LOCs it will save them seems pretty low.
That's part of the point, in a way. Not to prove to people how much they don't know in a negative way (but maybe it comes across that way), but to provide a hopefully fairly shocking number to get them to rethink some of their basic assumptions about development. Using even a moderately different toolset can yield dramatically different (and I'd argue usually better) results.
Is there any rigorous study more recent than Lutz Prechelt's "An Empirical Comparison of Programming Languages"? That estimates a factor of two difference in lines of code between Java/C/C++ and Python/Perl/Tcl, albeit for a rather small project.
So I've been using "factor of two" as a rough benchmark. Of course, this assumes appropriate library support; if most of the C code implements a priority queue while C++ has that as part of the standard library, then the comparison is invalid.
I don't know if for this Grails comparison if the extra factor of two comes from Groovy or from the effectiveness of Grails over whatever the Java programmers would use for web app development.
Yeah, I don't want to weigh in the JavaScript side of things but I've worked with a ton of "large" Java applications. All of them have been large because...
> Everything must be an interface/impl/dao/controller so you get 4 files + hibernate mapping (if not using annotation) + view files. Eventually you have 10 files for every object.
> Mid-stream decisions (we need to go from Struts to Spring) that effectively create two separate in-process branches of the code base.
> Java developers building their own castle. Some guys "owning" a side of the application and not communicating therefore creating solutions their own way instead of using common libraries.
Specifically to your description I would argue whatever you are doing must be in multiple projects or it has been poorly engineered. If it is in multiple projects why couldn't another language take it on?
> I don't think you could grow to that size codebase with Javascript.
I disagree. Any substantial JavaScript application can reach this size and more. It all depends on the level of abstraction you choose and the functionality frameworks and libraries provide out of the box.
I have written numerous mobile applications in JavaScript and they quickly sprouted to 10-30kloc. The majority of this being API functions to speak with our robust REST API, custom controls extending those provided by the Ext framework, and controller logic.
You wouldn't need that size of a codebase with JavaScript...
Java was created (or adapted to) for the benefit of consultants. Therefore it requires complicated frameworks and you can not manage coding Java without an IDE. All this makes it easy for consultants to get long paying gigs.
Edit: thanks, downvoters! You are incredibly naive...
Therefore it requires complicated frameworks and you can not manage coding Java without an IDE.
Nonsense. I write a lot of java in emacs and use no frameworks at all. It's a simple systems programming language with an excellent standard library and great concurrency support.
While many people do abuse Java by plugging AbstractFactoryFactory objects into their framework for procedural programming, that's an issue of bad programmers rather than the language itself (which Java has lots of).
Then I guess you use your own frameworks and have a very special use case that shields you from the typical pains.
Maybe it is possible to use Java in a sane way. But there are for example best practice guidelines by Sun/Oracle. If you try to follow all that stuff, it will be painful.
Also most libraries for Java were written other Java developers. For example the other day I tried to send a simple Twitter update with Twitter4J (I think that was the name, might mistake it with another one). After an eternity trying to figure out how to configure OAuth with the AbstractAuthenticationProviderAuthenticatorCredentialsMessUpperInterfaceImpl (which requires clicking through several levels of the API dopcs to get the hang of), I eventually gave up and just used a 10 lines Ruby script instead.
A twitter4j update, taken directly from their webpage:
Twitter twitter = (new TwitterFactory()).getInstance();
Status status = twitter.updateStatus("hello from Twitter4j");
You also need a 4 line twitter4j.properties file containing your assorted tokens and secrets. It's a bit longer than 10 lines, but still pretty straightforward, even with the use of a (probably unnecessary) TwitterFactory.
By the way, I said java is a simple systems programming language. It's not what I would reach for if I wanted to update twitter either.
I had a similar problem - also dismissed Twitter4J etc. as too complicated and wrote a 50 line Java method to send a tweet (signature: tweet(tweet, consumerKey, consumerSecret, accessToken, accessTokenSecret) ).
So presumably it's the culture you don't like, rather than the language.
Google and a few other companies manage to do this with Closure Library and Closure Compiler. Compiler's static analysis detects a large set of errors that you might introduce after a broken refactoring, or just during normal development. Among the most useful are the missing properties check, and the type mismatch check.
I watched the video. Just to clarify, his argument is that it's hard to refactor large programs in javascript. In other words, it's likely that large web-applications written in javascript will be having difficulties to innovate. Only time will tell though...
Definitely agree with this. I've re factored large C# apps, moving thousands of lines of code into different places and have had it up and running again very quickly with no bugs.
Contrast this to refactoring huge javascript or python programs because the compiler isn't going to check if what you refactored 'fits' into the place you put it. It's always very nerve racking for me when refactoring large pieces of javascript or python because even if it runs, often many bugs remain lurking that won't be found out until the unit tests are re-written.
In Java you have dependency injection, which is fancy name for calling constructors/methods with reflection, depending on some XML file or annotations.
Which makes Java more dynamic at the cost of making it as hard to refactor automatically, as any dynamical language.
The part of code that doesn't use reflection is the part of code, that would be easy to refactor, even if it was written in javascript.
There, I just did dependency injection without a trace of reflection. Additionally, since everything is statically typed in Java, refactoring is still vastly simpler than with a dynamically typed language. The few spots in the code where you might be trying an invalid type cast are just that - a few spots. Such problems don't permeate the entire codebase as they do with a dynamic language. And I'm saying this as a huge fan of Clojure and Groovy, preferring them over Java on the JVM.
If you write the IDE in the language itself, you can use reflection to access, query and manipulate the program's structure directly, while the program is running.
This is theoretically true and I am excited about LightTable but even then, there are many situations where automated refactoring simply isn't possible.
This is a hazard in pretty much any language though. At some point you're going to want to do something dynamic at run time just to get a particular feature to be possible- whether it's by using a built in feature of a language, or by importing an aircraft carrier to do it for you in Java. It's simply Godel's curse- every sufficiently powerful formal system has an escape port. Otherwise known as Greenspun's 10th rule.
Because refactoring has little link to innovation.
What about rapid prototyping? Perhaps the biggest strength of the lighter, more dynamic languages is that they require much less work to play around with ideas in the early days. On the other hand, if you can’t then tidy up the code that sticks, to make it into something that is more systematic and maintainable over the long term, you’re either going to waste effort rewriting it or you’re going to take on ever-increasing levels of technical debt, and either way your progress will be slower.
Refactoring really, truly and absolutely has nothing to do with rapid prototyping, nor does rapid prototyping has any use for refactoring.
> you’re either going to waste effort rewriting it
Throwing one away isn't "wasted effort", it good practices: you created a turd the first time around and learned a lot, polishing that turd would be wasting time.
JavaScript lacks a real library/module system, namespaces and OOP facilities. I usually spend more time maintaining a JavaScript program than a program written in Java/C# with equivalent size.
That being said, my skills in JavaScript are limited.
I especially like the fact, that "importing" module in node returns imported module, instead of putting it into namespace like it does in Java. It's much better design.
You can do OOP in any langage and there is nothing wrong with dojo. But from my limited experience, maintaining large programs written in JavaScript is a tedious job (each program reinvent it's own OOP semantics)
I think it's very good that javascript discourages writing large programs. Large programs are not a desirable goal, and it's rather a disadvantage of java that it allows and encourages such awful behaviour.
As for my reply to your deleted reply:I thought you were tongue-in-cheek.
As for my reply above: "you should not have that problems" does not make them go away: some problems solved by software are inherently complicated and cannot be reduced to some simple API calls or a 5kloc code base. Composition of 100 multiple 5-kloc code bases still makes them a 500-kloc code base with all mutual dependencies.
Just saying "you should not write so much code" might display inexperience with problems which fall outside of the currently common javascript apps ...
It perhaps depends on how those 100 multiple code bases were written. I won't lie and say I have experience with inventory systems. But I will take the position of the young upstart dipshit and suggest perhaps the reason you end up writing such huge tangled messes is you just haven't thought of a better way to do it. Javascript might not be the best tool for such jobs though, the way the number type works- on its own, makes it impractical for accounting tasks.
I'm completely with you that messiness is best tackled by loose-coupling parts early on. It's only that I found the combinatorics of many small systems not so much easier to tackle than their monolithic counterpart.
The worst is even that you (or somebody else) begins with good intentions ... and then , 4 software generations and law changes later, the complexity starts to smell.
Heijlsberg argues, that javascript will be harder to refactor in those cases. I can't really disagree with him.
So it find it's not so much lacking thought. The current thought for some is "let's use javascript", let's see what comes of that... :-)
I couldn't watch the video. I am starting to think though, that the sweet spot is to not just simply use javascript for everything and hope for the best- or to use java or something else and enjoy the sweet refactoring IDE glory, but a synthesis of making well tested components in a static language that you orchestrate with a scripting language- (if I have a choice, I actually would probably choose lua). In my experience so far, a lot of tangle often comes about by a confusion of library code and application code- the two styles of programming are very different. A module is very structured and regular, while application code seems to be ad hoc, specific, and irregular. There's nothing stopping both from being written in the same language, but if you decide that libraries go in one language, and application code goes in another, there's smaller risk of the two accidentally forming interdependencies. Then you set the goal that the dynamic portion of the program is to never exceed 2000 lines of code- and you have the basis for --- an experiment at least. Since really that's kind of what we are all doing. It's pretty well known by now I think that nobody has discovered a One True Way of doing this software stuff.
We haven't really figured out how to write large complicated applications- Static analysis is no magic bullet, and neither are dynamic languages. I think what we are seeing is just a kind of physics of the mind- reactions and re-reactions to unpleasant experiences we've all had, and are trying to avoid, which leads us to polarise on the static/dynamic divide.
Steer clear of "enterprise scale" ExtJS 3.x projects - tens of thousands of lines of javascript code that just duplicates server logic and absolutely positions text boxes and buttons on the page.
I downloaded the Flow app JavaScript to see how they handle relations and composed views etc. I swear I could be commiting fixes and new modules to that codebase a few hours later. With OO, TDD and established conventions you can achieve reasonable maintainability.
I'm not super familiar with OCaml but I have written a fair amount of code in F# which is supposedly based on / very similar to OCaml. In the end I had to convert it all to C# because none of the others developer at my company could grok it. I agree with you that the type inference is really neat but writing F# (and probably OCaml too) consistently in an imperative style is a bit of a pain in the back; it feels like the langauge is simply not meant to be used like that. And, as I said, functional programming is difficult and most programmers never even heard of it. (I wish I could use FP at work but jobs like that are really rare here in London.)
When writing code, sure. When reading and/or maintaining code, not so much. Especially when it stretches across function or method boundaries. Languages like C++ and C# have the right happy medium in my opinion: `auto`/`var` keywords for type-inferenced local variables, but explicit parameters and return types for all methods.
I think of type systems much more as a static analysis mechanism the compiler can use to identify programming mistakes rather than a concept that helps reading or maintaining code. In my opinion, in well written code the types of various symbols should be obvious due to the context, names, etc. without having to look at type names.
In theory, perhaps. But there is a lot more information in syntax than in names in my experience, such as the number of arguments to a function.
For example, suppose `f` is a function of type `int -> int -> int -> int`. In python, semantic differences are obvious between:
a = f(x, y, z)
b = functools.partial(f, x, y)
Where as in OCaml this difference is glossed over:
let a = f x y z;;
let b = f x y;;
Even though the names "f" and "x, y, z" are relatively evocative of their types, the two expressions are very different without any particular indication as to why.
That's why I think that there is a happy medium, where syntax is very helpful in determining types such that there is no need to give explicit types to "a" or "b" in these examples, but there is enough information explicitly available to declare that "f(x, y)" is an invalid function invocation, not a curried function of the type `int -> int`.
Different, not difficult. On the whole functional programming is no more difficult than imperative/OOP. It's just a big switch for programmers used to imperative programming (i.e., most programmers).
At some point you have to also consider why most programmers are used to imperative programming.
It could be you're rationalizing from a first principle ("it must be equally easy, so if it has not caught on it's because programmers are not used to it").
> why most programmers are used to imperative programming.
Probably because that's the paradigm of the most popular languages, the first paradigm everybody learns in college and university and likely the first language a person will encounter? Because most programmers are despite what they would say about themselves in public, actually stubborn language bigots? I would think about that because it puts functional programming (or logic programming (or proof-based programming (or stack-based programming))) at a disadvantage and a fair conclusion cannot be derived from uneven exposure.
Consider the actual research done in this area, classes have demonstrated that whatever the language, there is always the same distribution. Those that excel (small group), those that succeed through hard work and do good (most of the group) and those that just don't get it and fail (small group). This has been shown to be true for C, Visual Basic, Pascal, ML, LOGO, Scheme (SICP!) and even Coq!, which is a proof-assistant. Probably Prolog, too, but I haven't looked at that. You can easily google this, just search for things like "lecture/semester findings" and "student reactions/performance" and insert your language of interest.
>Probably because that's the paradigm of the most popular languages, the first paradigm everybody learns in college and university and likely the first language a person will encounter?
That is just a rephrasing of "they are used to imperative programming". The question is why.
>Consider the actual research done in this area, classes have demonstrated that whatever the language, there is always the same distribution. Those that excel (small group), those that succeed through hard work and do good (most of the group) and those that just don't get it and fail (small group). This has been shown to be true for C, Visual Basic, Pascal, ML, LOGO, Scheme (SICP!) and even Coq!, which is a proof-assistant. Probably Prolog, too, but I haven't looked at that. You can easily google this, just search for things like "lecture/semester findings" and "student reactions/performance" and insert your language of interest.
How does that work in real life though -- when pragmatic issues get into play that are absent from "implement this algorithm in whatever language".
Oh surely that's because it has too much static typing to be practical, it's not like there is much thought put in the argument or any desire to pursue the argument to its logical conclusion in these things.
I kinda feel strange when people tell me Python is bad because it does not have static typing but when I tell them about OCaml or whatever else I'm fine with, they try to find another excuse why Java is good.
The same has been said of almost every language in existence.
Let me maintain my larger program in JavaScript. It will require smarter staff, but the application will be more flexible and change more quickly than that same large program written in Java or C#.
If where you're working has a big company mentality, someone in the decision making process screwed the pooch when they decided on JavaScript as an application programming language.
My favorite thing about JS now coming into wider use is how it drives a certain class of older hackers bonkers.
It has 0 and -0! The default namespace is global! It has a === operator, for crying out loud!
For folks who spent a bunch of time writing AbstractPatternVisitorHandlerFactory classes, it probably looks like the end of the world at the hands of a bunch of freakin' degenerates.
It's not that at all. I use JS almost daily and the unfortunate conclusion is that it's just poorly designed.
The data structures are lacking and have bizarre corner cases. I don't know if what it features as OO can be called OO and I don't care much, but the abstraction mechanisms are inferior to what I'm used to. Performance is unpredictable and sometimes I'm forced to write less readable code.
Refactoring is a scary adventure, debugging is subpar, code navigation is cumbersome..
The things that I do like about it are availability and that it's cross-platform.
1. Understanding JavaScript type coercion correctly, including (emphasizing!) all of the corner cases that actually matter, is not an hour's task.
2. The fact that pathological-condition-X of a language is in theory understandable with sufficient study is a total red herring in a broad discussion of that language.
Understanding all the corner cases of how C deals with integers is a huge undertaking, as the C Integer Quiz thread showed us. But in practice, it's not actually a problem since you just learn to avoid using features of the language that involve type coercion. Just simply don't mix types. only use === and !==, use a templating library instead of the + operator to construct strings. jslint can catch the rest. If you truly find the way javascript behaves surprising- in the sense that you are trying to do something reasonable, and it surprises you, I have to wonder what on earth you are trying to do that would invoke type coercion to begin with, and why you need to do it that way.
I think there is a bit of an issue with _the code you don't write_ , because you rely on third parties.
Today, I spent five minutes tracking down a
SyntaxError: Unexpected token u
It was honestly hard to read this as "don't give an un-itialized value to this function or it will end up being passed to JSON.parse that will happily treat undefined as a string".
I'd take a NullPointerException with a proper stacktrace everyday.
in chrome, error objects have stack traces attached. All you would have needed to do is wrap the problem code in a try/catch, catch the error, and print out the stack trace, assuming you can't figure out how to find the stack trace just using chrome's web debugger. https://code.google.com/p/v8/wiki/JavaScriptStackTraceApi
You are missing my point, the issue is not that the error does not have a stacktrace, it's that it looks like:
SyntaxError: Unexpected token u foo.js:123
h foo.js:456
g foo.js:789
f
The issues are
* no reference to JSON.parse which is where the error occurred
* the error is not "object has no attribute toString", which would have made it clear what it's happening, but something else derived from having silently coerced "undefined" to string, which obscures what is happening.
As I wrote, it was a five minutes thing, not hours, but it's five minutes I would not have spent if it had been:
TypeError: Cannot read property 'toString' of undefined: [native code]
JSON.parse [native code]
h foo.js:456
g foo.js:789
f
While I share your "just sit down and learn something instead of complaining" sentiment, in this case I think it's pretty difficult to memorize all the different ways that javascript does type coercion. Sure you get to know the most common pitfalls, but it just feels like even experienced JS programmers get bitten every now and then.
These things, like default global namespace, aren't just bad to a particular class of gray-beard enterprise developers who build AbstractFactoryFactories and are correspondingly easy to ridicule. They're _bad_ bad, net-negative properties of a language. I'm not sure why you would (appear to) defend them. Can you please clarify?
Dynamic, weak typing makes writing static analysis/refactoring/etc tools extremely hard, but more importantly makes nearly any compile-time guarantees impossible. Having your app crash because of a small typo of a member name is impossible in C++/C#/Java. It happens to me almost once a day with Node/JS.
This rings very true to me too, as our entire application is written in Perl. As much as I do like the language, the lack of just about any static guarantees mean we regress an awful lot. Yes, we have unit tests, but until we have 100% coverage we have gaps for regressions that a compiler could have picked up.
Anyone doing a large project in an weakly-typed language will eventually spend more time writing unit tests than features.
No-one should even be thinking about unit tests if they are not already using a language in which all code paths can be evaluated and type-checked at compile time. Why get a dog and bark yourself?
Using a language with static typing means that there are a lot of tests you don't have to write. Do you remember the units trick from physics? If you forgot which equation you're supposed to use, keep on using identities until you're in the units you're supposed to be. Static typing checks that your units are correct for free.
Well, not entirely for "free", but I do agree that the price is much lower than what you end up paying eventually for the convenience of dynamic typing.
I don't ever have to write a test in OCaml to tell me what I need to fix if I change a function signature, or add another item to a struct or an enum, or change a function to return something else, or anything like that. The compiler does it all. Every code path is evaluated at compile time. 90% of unit testing is just not needed in OCaml or Haskell (and that which you do need, there's QuickCheck for).
I had the same experience when writing Haskell. I would start by inserting a function call at the top level referencing a function I hadn't written yet, and then start hacking on the function and all its helpers. Without fail, as soon as the program compiled it was basically correct. The only thing that could go wrong were legitimate algorithmic errors, such as using the wrong base cases for recursion or something.
Except that to work around the pesky types, Java people started moving everything into XML. Now they have a horrible solution to being able to work typeless.
Apparently you haven't looked at Java development in the last 5 years, so you may want to stop making statements about it that make you look like a fool.
I just did a three month enterprise Java project. I admit that I hadn't used it in a while, so I picked Spring like in the old days (+Hibernate at first, but had to kick it out eventually). And hell it turned out complicated (even with Spring). What is the new mantra that makes Java suddenly usable? Playframework?
It doesn't look like you're interesting in anything except following your own mantra of "Java suxx", but XML configuration files (which were never really about working around the type system) have been almost universally replaced by annotations.
How so? I've only ever seen them eliminate external configuration files. Hell, thanks to annotations and some simplifications to the standard, EJBs have turned from the epitome of overengineered bloat into a simple, lean service layer.
Could you elaborate(/give references) about your claim?
(I don't know anything about the GP, but I really haven't looked at Java development in 5++ years. (-: If nothing else, I might need to update my jokes :-) )
XML configuration files have pretty much disappeared/become optional. It's all done via annotations nowadays, which are much less verbose since their context is implicit, and which are actual language constructs known to the compiler.
Can I ask why you're rewriting code on your production server on the fly without the aid of the rest of your tool chain?
In any good development shop you make a change, your CI server picks it up, builds it, and creates a release candidate you deploy. Every change should be checked into source control and built by your automated build bot.
At that point the difference between changing an annotation and an XML configuration file should be moot. I'd think the annotation would be easier because you can still mess up the syntax of the XML file pretty easy (e.g. "Can you change the blahblah label to System & such?" That ampersand will hose your system when you get it to production).
Well, there's always some genuine configuration that contains the actual differences between environments, like DB connection and API keys, and which isn't going to be part of the automated build.
But that's a tiny subset of what architecture astronauts try to label "configuration".
So how about using a tool like jslint that will get you 90% of the static checking and will solve the kind of crash you mentioned ? Looks pretty good to me.
Does jslint handle imports? Which would be surprising, given the lack of a standard system in Javascript? If it doesn't, then this leaves you very far from your 90%.
On the other hand, pylint for Python is really good for static checking, even if it won't catch everything.
Maintaining a large PHP project written by idiots, in addition to a much smaller codebase in Javascript has convinced me of the importance of static typing for large-scale projects.
By the way, if all you need is classes, there are many many libraries that give you those in JS (not to talk about CoffeeScript).
What I really miss from a maintainability point of view with javascript, on the other hand, is better development tools (ie IDEs and testing tools). I'm pretty sure there is a big opportunity there.
> everything that does not have classes is unmaintable
Not that javascript doesn't. It doesn't have the sugar around it, and it doesn't statically check them. But javascript's OO is not "prototype-based" (that doesn't even make sense, prototypes are not a unit of reuse in Self) and it's not anything even remotely close to Self's.
Javascript's OO is single-inheritance class-based with no `class` sugar but at the end of the day it behaves pretty much the same way (and offers no more features — less if anything) Python's or Ruby's class-based OO work (sans metaclasses).
Was the argument really about classes? I would have expected this to be about the lack of namespaces. (I can't watch the video, it stops to buffer every second.)
Note that Go has no 'classes', and doesn't follow what many people consider mainstream OO principles (eg., inheritance), and many people would say this is one of the things that make it so great, specially in large projects (working out a good type hierarchy, and evolving it over time is extremely difficult and painful).
The problem with JavaScript is not lack of 'classes', but a not just dynamic but also very weak type system.
Add to that the callback-hell caused by the async model of things like Node.js, and you end up with something very hard to maintain quite fast.
You definitely can create classes in JavaScript, its just not especially convenient.
But to me its not really a critical issue, because OOP is very easy in CoffeeScript, which is my favorite language and happens to compile to JavaScript.
Yes, he's very afraid of Node.js, that's why he said those things. I mean who is this Anders Hejlsberg guy, criticizing the BEST work of language designer giants like Brendan Eich and framework masterminds like Ryan Dahl.
There is no reason to lock the browser in a cage half-designed and half-implemented by an engineer under a tight deadline over a decade ago.