Hacker News new | ask | show | jobs
by mattdw 5240 days ago
Particularly I'm thinking of the inescapable async-all-the-way down, which necessitates endless lambdas. In other languages it's possible to pick a point at which to invert control back to blocking-style; JS's single-thread model makes that impossible. So for instance all calls to the server API have to be callback style; if you have to make serial calls, you can't avoid nested callbacks.

I miss a set type, I miss solid iteration (although coffescript mitigates that), and immutable datatypes would be nice (I've got used to them in Clojure.) I miss a solid FP stdlib, although jQuery has map and filter, which goes a long way.

That's the ones I can immediately think of :).

5 comments

> So for instance all calls to the server API have to be callback style; if you have to make serial calls, you can't avoid nested callbacks.

I hear this over and over again but I frankly do not get it. I write JavaScript every day and got over the nested callback problem ages ago. I don't say this to refute the point; I legitimately don't get it and feel like maybe I'm doing something wrong because I don't encounter the problem. Here's how I write stuff that requires several callbacks:

  function TakesAWhile() {
 
  }
 
  TakesAWhile.prototype = {
 	start: function() {
 		var xhr = new XMLHttpRequest();
 		xhr.open('POST', 'api/foo', true);
 		xhr.onreadystatechange = this.posted.bind(this);
 		xhr.send('bar');
 	},
 	
 	posted: function(e) {
 		if(!(e.target.readyState !== 4)) {
 			this.complete('error :-(');
 			return;
 		}
 		
 		db.saveSomething(someObject, this.saved.bind(this));
 	},
 	
 	saved: function(e) {
 		db.getFreshCopy('foo', this.got.bind(this));
 	},
	
 	got: function(e) {
 		var foo = e.target.result;
 		this.complete(foo);
 	}
 };
Then I consume it like this:

  var stuff = new TakesAWhile();
  stuff.complete = function(foo) {
  	console.log('All complete!');
  };
  stuff.start();
> inescapable async-all-the-way down, which necessitates endless lambdas. In other languages it's possible to pick a point at which to invert control back to blocking-style

I hear you. Have you heard of iced coffee script ?(http://maxtaco.github.com/coffee-script/) I didn't sleep well the night after I read that.

Looks much like http://tamejs.org/ in the semantics. I guess if you're pre-processing anyway, you may as well pre-process all the way.
Oh, same guy. That'd be why.
I was bummed `await` and `defer` was not merged in. However, after thinking about it, the same result can be had using a good async library. The code is self-documenting if you choose good property names.

.

follow = (from, to, cb) ->

  # Invokes four async operations in a series, which requires 4 `await`, `defer` 
  # using iced. Note how error handling is handled 
  # in one place rather than each step.
  # That's a big drawback for me with await/defer.

  async.series
    user: (cb) -> User.find name:from, cb

    addFollowing: (cb, results) ->
      results.user.following.push to
      User.save results.user, cb

    followee: (cb) ->
      User.find name:to, cb

    addFollower: (cb, results) ->
      results.followee.followers.push from
      User.update results.followee, cb
    
  , (err, results)
    cb err, results
After finally getting over my fear of client-side programming, I finally built a project in JS last week.

I feel exactly the same as you: Javascript, as a language, just does nothing to help you. You've done a better elucidation of it than I could, I just always felt JS was being unhelpful; be it getting the value of an object, be it the inheritance syntax (I have no issues with the prototypal aspect, just the way you express it), lack of good ways to move through a list, the somewhat difficult to understand scoping of 'this'...

It's not that any one thing is especially broken, it's just that all added up I feel like it's not finished, and I'm not Getting Stuff Done as I do with Python.

Google Closure seems to go some of the way there, but I get the feeling that's probably just adding some syntactic sugar to make swallowing the bitterness a bit easier.

This is why I've been dismayed to see JS taking off on the server side. Maybe there's some clever engineering behind Node and maybe taking a free ride on V8 is a lot less work than building a similarly robust VM for Ruby or Python but it just seems wrong to build the next generation of apps on such a flawed language.

The explosion of the web opened the doors to new languages after a long stagnation of client-side code. Why let an accident of browser development history dictate the tools we use for the next 5-10 years?

Node probably will end up like both the JVM and client-side JS have become - a compile targets for better languages. Not ideal, but good enough I expect.
FWIW, JavaScript is getting a Set type (and a Map as well). You can try them in Firefox Nightly.

JavaScript is also getting the ability to change property lookup behavior on objects using Proxy (available since Firefox 4).

Browsers are moving faster, which helps here... and for people using Node, you can use these features as soon as Node gets them.

You should checkout underscore.js for a functional lib. Made by the same guy who did coffeescript and backbobe.js.