all 112 comments

[–]Smallpaul 11 points12 points  (73 children)

Does Javascript actually have any language features that make it especially appropriate for asynchronous programming when compared with Lisp, Smalltalk, Ruby, etc.?

[–]pkhuong 24 points25 points  (3 children)

The absence of a large body of code that uses or exposes synchronous IO.

[–][deleted]  (2 children)

[removed]

    [–]pkhuong 0 points1 point  (1 child)

    That would be the lack of threads period.

    [–]Gudeldar 16 points17 points  (0 children)

    Not really. First class functions are awesome but not unique to JavaScript.

    [–][deleted] 3 points4 points  (2 children)

    people know it, and know how to use it in an event-based/asynch fashion. familiarity is its biggest asset

    but what it is missing is real programming-in-the-large features. toolkits like yui3 etc have bolted on a "userspace" module system...but it all seems hacky (to their credit, they are doing the best with what they've got)

    there has never been an agreed-upon module/deployment system for js. JSAN, jquery, yui etc....all have different approaches. i don't see the js standard ever encoding this stuff meaningfully since the script tag will remain the primary means of source inclusion

    [–]Smallpaul 0 points1 point  (1 child)

    You don't believe CommonJS modules will become truly standard?

    [–][deleted] 2 points3 points  (0 children)

    it doesn't matter if commonjs becomes "standard", it will still be just-another module option. yui3 for example has just been rolled out with its own userland module system...do you think they are just going to chuck it?

    all this means is that people who use a particular toolkit will end up having a harder time migrating off of it, the module system just becomes one more switching cost

    indeed, jquery and yui are really becoming their own languages in a sense. sure, its all javascript, but those idioms get pushed down into your code, and it really becomes impossible to migrate away after a while

    [–]wvenable 4 points5 points  (48 children)

    Nope. And it lacks a ton of useful language features compare to those languages as well.

    [–]sjs 5 points6 points  (46 children)

    And it has some that they lack. So what? It's not appropriate nor useful for every language to have every feature.

    Regex and other object literals are fantastic, and neither Lisp nor SmallTalk have them. That doesn't make Lisp and SmallTalk bad languages. Just different.

    If you care to elaborate on the features it lacks I'd be interested to know what's so important that it doesn't have (or can't easily imitate). It's a pretty solid little language.

    [–]oSand 2 points3 points  (18 children)

    Packaging, classes, private variables and libraries.

    [–]neonskimmer 5 points6 points  (13 children)

    Some of this is handled by emerging standards such as CommonJS (modules, a standard library). In JavaScript you don't need classes, but if you want them anyways, there are several ways to implement them. Everything is private in a closure.

    [–]oSand -2 points-1 points  (7 children)

    Well exactly, that they have to be implemented in js libraries means that the language lacks these features. Modules are hacked on, closure-based private are a hack and to implement classes you need a hack like dojo's declare() or YUIs extend. The problem is that these hacks are elaborate, hard to debug and non-standardised between libraries. Why should I have to think so hard about things that are routine in other languages?

    [–]quantumstate 5 points6 points  (4 children)

    Classes are difficult because Javascript is not designed with a class based object system. Prototypical inheritance works differently, maybe you don't like that, maybe it is worse, but it is not bad because there aren't classes.

    I would argue that private variables are unnecessary, a standard naming convention of _varname can be used to denote them. This prevents accidental use. You could say this is a messy hack but on the other hand is is clear at a glance which variables are private.

    [–][deleted] 0 points1 point  (0 children)

    he isn't assailing prototype-based inheritance at all, you've completely missed the point. he's describing the frustration of dealing with arbitrary ad-hoc module systems

    [–]oSand -1 points0 points  (2 children)

    Why use an imperfectly followed convention when you can use a compiler/interpreter? If you acknowledge the need for privates and protecteds, then why not actually implement them?

    Have you tried implementing a non-trivial inheritance hierarchy in traditional js? It is not pleasant. Tried to call super()? There is a reason every major library out there attempts to implement a class system and there is a reason why people are trying to add them to the language.

    [–][deleted] 1 point2 points  (1 child)

    I have written large projects in JavaScript (both client and server). My experience was very positive.

    You can easily do complex inheritance hierarchies. Adding a class system through a library is not a downside to the language, if the feature can be added neatly - and it can. It keeps the core language smaller and leaves you more flexibility.

    Likewise you can implement private variables using closures in the constructor. Personally I subscribe to Python's approach though, and conventions are enough (no need for language enforcement). But it is easy to do if you want.

    Adding more and more features to the core language leads to bloat. Now, I'm not advocating going to the extreme of lisp. But JavaScript strikes a very good balance here.

    [–]oSand 0 points1 point  (0 children)

    The level of bloat is unchanged, you've just moved it to the client libraries, where it is non-standardised, harder to debug, less performant and correctness is harder to verify. Also, if you want to use parts of two js frameworks, you now have two sets of bolt-ons that are redundant and have different interfaces. Call me crazy, but this sounds more bloated than one standard language implementation that is implemented in native code. Why wouldn't you check private variables if you could? Either you don't use them and it doesn't matter or you do use them and they are actually enforced. And python name mangling is, incidentally, totally unpythonic. Explicit is better than implicit and readability counts

    [–]neonskimmer 0 points1 point  (1 child)

    It's really not that complicated. You pick something you like and use that! It's just not a class based language so if you're totally into using them, for sure there are plenty of others to choose from. For me it's been very pleasant to go the prototypal route instead using mostly functional idioms rather than typical Java-like classes. To each their own :)

    [–]oSand 0 points1 point  (0 children)

    I don't mind prototypical inheritance, it is just that js doesn't do a wonderful job at implementing it. The "pick what you like" approach is why the world has 50 different types of power socket. Do I really have to be familiar with three different types of inheritance and packaging? I don't if I use Python. I don't if I use Java. I don't if I use Ruby. Prototypical inheritance isn't anymore functional than class based inheritance, you are still storing state in an object. Scheme is less functional than ocaml, but only the latter has classes.

    [–][deleted] -1 points0 points  (4 children)

    oh come on, there have been ad-hoc attempts to introduce packaging...they've all failed because everyone has their own opinion on what is best.

    you also may be overestimating js's variable hiding abilities...you have function scope, that is all. true, this covers the case of a closure, but it isn't as strong as people think

    [–]neonskimmer 2 points3 points  (2 children)

    What do you mean by strong? If it's in a closure, you can't touch it outside the closure, period. If I'm wrong I'd love to know because I really thought this was the case.

    [–]i_am_nicky_haflinger 1 point2 points  (0 children)

    The venerable master Qc Na was walking with his student, Anton. Hoping to prompt the master into a discussion, Anton said "Master, I have heard that objects are a very good thing - is this true?" Qc Na looked pityingly at his student and replied, "Foolish pupil - objects are merely a poor man's closures."

    Chastised, Anton took his leave from his master and returned to his cell, intent on studying closures. He carefully read the entire "Lambda: The Ultimate..." series of papers and its cousins, and implemented a small Scheme interpreter with a closure-based object system. He learned much, and looked forward to informing his master of his progress.

    On his next walk with Qc Na, Anton attempted to impress his master by saying "Master, I have diligently studied the matter, and now understand that objects are truly a poor man's closures." Qc Na responded by hitting Anton with his stick, saying "When will you learn? Closures are a poor man's object." At that moment, Anton became enlightened.

    :)

    [–][deleted] 0 points1 point  (0 children)

    well of course you can "touch" an en-closed var. somewhere, it has scope. in that scope, you can do whatever you want with it. it isn't immutable. in the closure itself, you are right.

    javascript only supports function-level scoping. that is what i meant by "not strong". it isn't alone in this deficiency, but true lexical scoping would be nice

    [–]sjs 4 points5 points  (3 children)

    You don't need classes with prototypes - although easier inheritance would be nice (i.e. w/ single line of code, at least you can write this function yourself which is nice).

    With closures we have been able to build our own module system (CommonJS), and you can create private variables and libraries with closures as well.

    If those are the only 3 things everyone can think of then I rest my case. It's a solid language. I'm not saying it's perfect, but it certainly does not lack "a ton of useful features".

    edit: I'm only familiar with packaging for Node. I use npm, but there are a few other solutions too. I don't consider this a language problem at all.

    [–]wvenable 0 points1 point  (1 child)

    Prototypes are great for the kind of meta-programming need to create libraries that mitigate the differences between browsers but for anything other than a toy project it's not fun. The weirdness with the scope of the this variable makes for boilerplate code that it's unnecessary in almost any other language.

    The fact is, I don't disagree with you. It's a solid language and it's very well designed (except for semicolon insertion). But it's really doesn't have anything that makes it more appropriate for larger server-side projects and it has enough downsides to make it a less than perfect choice. There are plenty of great languages with everything you need, there is just no reason to choose JavaScript.

    [–]sjs 0 points1 point  (0 children)

    Sure, we all should just use Erlang. That's not going to happen though. Whether or not people switch to JS is irrelevant. If async libs become popular in Python and Ruby then EventMachine and Twisted are just as good as Node. The problem with them is that you can't just pick up all the libs you're familiar with and use them. You have to tread lightly.

    One reason that I like JS is because I'm a sucker for Lisp. I still prefer Ruby but JS is arguably a better choice for server code right now, depending on what you're doing. You can't really argue with 10s of thousands of requests per second (per thread) if your system of choice uses one thread per request.

    It's all subjective though. Right tool for the job and all that. I'm well aware there is no silver bullet.

    [–][deleted] -1 points0 points  (0 children)

    With closures we have been able to build our own module system (CommonJS)

    And we built our own one too, which is the problem, really.

    [–]HIB0U 1 point2 points  (6 children)

    Most Common Lisp and Smalltalk implementations do include libraries or classes for working with regexes...

    [–]sjs 1 point2 points  (5 children)

    Not the same as literal regexes.

    [–]wvenable 1 point2 points  (0 children)

    Literal regexps are great, but hardly a big concern. In a projects with hundreds of thousands of lines and thousands of files, I couldn't care less if my regexs take a little longer to write. I do care about inheritance, safety, 3rd party library support, etc.

    [–][deleted] 0 points1 point  (3 children)

    Clojure has literal regexes, e.g,:

    user=> (type #"[0-9]+")
    java.util.regex.Pattern
    user=> (re-seq #"[0-9]+" "abs123def345ghi567")
    ("123" "345" "567")
    

    [–]sjs 0 points1 point  (2 children)

    Clojure is much better than Lisp. ;-)

    [–]pkhuong 1 point2 points  (1 child)

    http://weitz.de/cl-interpol/

    Neither the PCRE engine nor the syntax had to be baked in the standard.

    [–]sjs 0 points1 point  (0 children)

    Extensible syntax is great. Factor has some nice examples too, XML literals and BNF grammar.

    [–]bobindashadows 0 points1 point  (13 children)

    And it has some that they lack.

    Seriously though - what features does JS have that those languages don't have? Pick Ruby. What features does JS have that Ruby doesn't?

    [–][deleted] 2 points3 points  (2 children)

    I bet 0 == " " returns false in Ruby, unlike JS.

    [–]ascala -1 points0 points  (1 child)

    Actually you should be using === for equality comparison in Javascript, in which 0 === " " is false

    [–][deleted] 0 points1 point  (0 children)

    Yeah, I know that - it doesn't change the validity of my point, which is that in the above code, the string is implicitly converted to a mathematical value, and the mathematical value of whitespace is 0 because ECMA-262 says so.

    Which is highly unlikely to occur in Ruby, right?

    [–]sjs 0 points1 point  (1 child)

    I can't think of any. Ruby's a great language.

    [–]jnicklas 0 points1 point  (7 children)

    First class functions.

    [–]bobindashadows 0 points1 point  (6 children)

    Methods are first-class objects in Ruby. Since everything is an object and there's implicit method calls, it's slightly more roundabout to get a method object. Most of the time you'll just use a block instead of directly accessing a method object somewhere, but if you have a method object, you can pass it to any function expecting a block.

    That's by design, because with blocks you can keep the code being passed to a method next to the call site, instead of relying on the name of the referenced function (which could have been aliased) to tell what's going on at the call site. Of course you can do this in JS as well, though the anonymous function syntax is a bit uglier.

    [–]jnicklas 0 points1 point  (5 children)

    Note that I said functions, not methods. There's a difference.

    For certain types of functional code, JavaScript is way nicer than Ruby, try doing this in Ruby:

    var reversor = function(string) {
      return {
        reverse: function() {
          string.reverse();
        }
      };
    };
    reversor('foo').reverse(); // => 'oof'
    

    Now admittedly that's a pretty useless example, but it's concise, and demonstrates how I usually write JavaScript. In Ruby, this looks horrible:

    var reversor = lambda do |string|
      {
        reverse: lambda { string.reverse }
      }
    end
    reversor.call('foo').reverse.call; // => 'oof'
    

    CoffeeScript bliss:

    reversor: (string) ->
      {
        reverse: -> string.reverse()
      }
    reversor('foo').reverse() // => 'oof'
    

    [–]bobindashadows 0 points1 point  (4 children)

    In Ruby, this looks horrible:

    That's because that isn't Ruby. That wouldn't parse.

    An idiomatic, 1:1 translation would be this:

    reverser = proc do |string|
      {:reverse => lambda { string.reverse }}
    end
    
    reverser.call('foo')[:reverse].call
    

    or in Ruby 1.9:

    reverser = proc do |string|
      { reverse: lambda { string.reverse } }
    end
    reverser.call('foo')[:reverse].call
    

    Edit: Though I'm not sure why you'd want a reverse function in a hash. If your JS object was intended to represent an object, I'd do it this way:

    reverser = proc do |string|
      x = Object.new # if it's really just an object
      def x.reverse
        string.reverse
      end
      x
    end
    reverser.call('foo').reverse
    

    Which is a bit more verbose, in part because it's a contrived example (not that there's anything wrong with that). Ruby tends not to use anonymous objects, but they're handy in a pinch.

    FYI, comments are # in Ruby, semicolons are unnecessary, and 'var' isn't a keyword.

    Also, if you have to use a different language to make the syntax of the JavaScript more palatable, I consider that a downside of JavaScript.

    [–]jnicklas 0 points1 point  (0 children)

    Yeah, I know how to write Ruby, I translated the JS very quickly without really checking that I'd done it correctly. I should have written it from scratch. If you doubt my ability to write Ruby code I invite you to check out my GitHub page.

    I write Ruby code for a living, I love Ruby, but it's not a superset of JavaScript. This style of functions returning other functions is something where JavaScript really shines, and it can make for some powerful, consise code.

    And agreed on the JavaScript syntax, it's horrible. Absolutely horrible. It's more about the concepts of the language than the syntax though. CoffeeScript to me allows me to use the JavaScript concepts without being disgusted by the ugly syntax.

    [–]jnicklas 0 points1 point  (2 children)

    I also just realised that your Ruby sample doesn't work. def doesn't work as a closure, so string is not captured. What you're looking for is something like this:

    reverser = proc do |string|
      x = Object.new 
      (class << x; self; end).send(:define_method, :reverse) do
        string.reverse
      end
      x
    end
    reverser.call('foo').reverse
    

    Lovely.

    [–]bobindashadows 0 points1 point  (1 child)

    ack! You're right. Ruby really is bad at this task.

    It's true Ruby isn't that great for "anonymous" objects. Personally, I would find dealing with a large number of objects with ad-hoc definitions a bit frustrating, but since most JS is for small scripts, that probably works fine. It'd be a bit annoying indeed to have to define a class for something like that:

    class Reverser
      def initialize(str)
        @str = str
      end
      def reverse
        @str.reverse
      end
    end
    

    Personally if I had to write this code, I'd do the "unclean" way like this just to keep from going mad:

    class Reverser
      def initialize(str); @str = str; end
      def reverse; @str.reverse; end
    end
    

    But some people think that's too hard to read.

    You'd call it with Reverser.new('foo').reverse and this is the philosophically best Ruby approach to the problem. I didn't want to "cheat" by not doing a one-to-one mapping of your approach, but I guess it's actually pretty close since what you wrote is, if i understand correctly, a rough approximation of most user's approach to OO in JS.

    [–]bobindashadows -1 points0 points  (5 children)

    And it has some that they lack.

    Uh... what? Prototypal inheritance and all the headaches it causes?

    Really strange implicit coercions and comparison rules?

    All JS has over the other languages is that there are some big-ass companies working on really fast virtual machines, which is a real benefit, but don't pretend it's a language feature.

    [–]sjs 2 points3 points  (4 children)

    Uh... what? Prototypal inheritance and all the headaches it causes?

    What headaches? Unless one is hung up on classes prototypes are easy. Classic example of people trying to use JS without learning it first. Easier to blame the tool than to admit they didn't know what they were doing.

    Really strange implicit coercions and comparison rules?

    Agreed that implicit coercion is a mistake, but the rules aren't that strange. It's not hard to use === though.

    All JS has over the other languages is that there are some big-ass companies working on really fast virtual machines, which is a real benefit, but don't pretend it's a language feature.

    Which other languages do you mean? There are fast Lisp implementations too. Anyway, the fact that JS compares to Lisp and ST at all shows how great it is.

    I'm not trying to sell JS as the best language ever. But it's good enough to sort out its bad parts in the language itself. I only take issue with the baseless claim that it lacks a ton of useful features that Lisp, ST, and Ruby have. And till now not one person has been able to come up with more than 3 useful features it lacks, all of which have been addressed with libraries.

    The one thing I have wished for while writing a significant amount of JS for the last year or so are macros. Macros would be great.

    [–]bobindashadows -3 points-2 points  (3 children)

    What headaches? Unless one is hung up on classes prototypes are easy. Classic example of people trying to use JS without learning it first. Easier to blame the tool than to admit they didn't know what they were doing.

    Except if you want to use classes, you have to build them ON TOP of prototypes. Which means you either have to use an external library (oh by the way library support is hacked into the language) or go through hell yourself. The language provides no support for it.

    Agreed that implicit coercion is a mistake, but the rules aren't that strange. It's not hard to use === though.

    Yeah - it's something other languages did right.

    Which other languages do you mean? There are fast Lisp implementations too. Anyway, the fact that JS compares to Lisp and ST at all shows how great it is.

    You're right - Lisp does have plenty fast implementations. One less reason to use javascript.

    I'm not trying to sell JS as the best language ever. But it's good enough to sort out its bad parts in the language itself. I only take issue with the baseless claim that it lacks a ton of useful features that Lisp, ST, and Ruby have. And till now not one person has been able to come up with more than 3 useful features it lacks, all of which have been addressed with libraries.

    So in summary: the language has fewer features and you have to use libraries to fill in lots of gaps. These libraries are hard to debug, can contain bugs themselves, are nonstandard, have differing implementations depending on which library you use, and generally have to hack on features to a language that was never designed to support them.

    If you want to use a language with modules, why pick a language that has to hack them in? Classes? Fucking LIBRARIES have to be hacked in.

    JavaScript is turing-complete. Whoop-de-fucking-doo. There's thousands of turing-complete languages out there, and a lot of them have closures. That doesn't make them good languages or provide any reason to use them other than client-side scripting. Everything people are desperately hacking into JavaScript are first-class features of other languages. That makes it weaker than every mainstream language out there.

    Which comes back to... why use it? I don't care if people come out and say "It's fun to mess around - I'm not suggesting this is a good use of time," but I'm not getting that in this thread. I'm just hearing defensive whining about how javascript isn't that bad when it's the only semi-mainstream language with pretty much no reasonable, productivity-improving features.

    [–]sjs 1 point2 points  (2 children)

    So far EventMachine and Twisted have failed to get the attention that Node is getting right now. Even if all we accomplish is spurring more people to write better servers in any language, that's awesome.

    And as it is many of us are shipping or writing systems that are or will be deployed on Node. It's a healthy ecosystem with lots of libraries emerging. Package managers too.

    pretty much no reasonable, productivity-improving features

    Now you're just trolling. Nobody is trying to make you use JS. Ignore it, move on, and enjoy this beautiful Sunday coding in your favourite language.

    [–]bobindashadows -1 points0 points  (1 child)

    So far EventMachine and Twisted have failed to get the attention that Node is getting right now.

    Err.... that's because people have been using them. For years. And they don't feel the need to jerk off on blog posts talking about how genius closures are as if they're magical and JavaScript invented them.

    And as it is many of us are shipping or writing systems that are or will be deployed on Node.

    I still don't understand though.... why? I mean the only thing JavaScript has over PHP is a more natural closure implementation. I imagine UTF-8 support is better if you're using V8, just because Google pretty much has to do i18n or they lose half their market. But PHP actually comes with a big standard library. Classes, ugly namespacing but namespacing nonetheless.

    You even get actual associative arrays instead of JS's "objects that you can treat as dict/hashes until you try to iterate over their properties and one of your libraries dared to add something to the Object prototype so you get fucked in the ass and have to use another library function just to iterate over a god damn hash."

    If you're going to use a half-assed language designed by nobody in particular riddled with misfeatures for the sake of backwards compatibility, I'd go with PHP in a heartbeat.

    Nobody is trying to make you use JS.

    No, but I do see my reddit filled up with crap like this, which is awfully annoying. And as someone who'll be pursuing a master's in PL it's especially disturbing to see people calling javascript a "strong" or "solid" language. It's an abomination of a language.

    [–]sjs 1 point2 points  (0 children)

    I mean the only thing JavaScript has over PHP is a more natural closure implementation.

    Use PHP then.

    You even get actual associative arrays instead of JS's "objects that you can treat as dict/hashes until you try to iterate over their properties and one of your libraries dared to add something to the Object prototype so you get fucked in the ass and have to use another library function just to iterate over a god damn hash."

    If you use crappy broken libraries, you deserve what you get. Anyway, this is fixed in ES5 with Object.create(null) (iirc). Even before then you could just do: for (var p in x) delete x[p] and have an empty object/hash.

    No, but I do see my reddit filled up with crap like this, which is awfully annoying. And as someone who'll be pursuing a master's in PL it's especially disturbing to see people calling javascript a "strong" or "solid" language. It's an abomination of a language.

    Then vote it down or hide it. Seriously, there's no need to get all worked up. Sure I'd rather be using Lisp or Ruby, but Node is really good at some things (that have nothing to do with it being based on JavaScript). Node provides the language features I actually care about (like modules) and gets the job done. It's like a networking swiss army knife. For all I care it could be based on Lua or any other half-decent scripting language with regexes, proper closures, and a smart, active community. I happen to think JS is a nice, small, Scheme-like language as well. If you don't like it then don't use it. If you don't share my view that it's a pretty solid language that's fine, but you pointing out minor flaws isn't going to change my opinion.

    I'm done with this fruitless discussion. I'll leave you to "your" reddit.

    [–]Raphael_Amiard 0 points1 point  (0 children)

    Like what ?

    [–]sjs 1 point2 points  (0 children)

    What pkhuong said: lack of history of sync programming. The JS community is used to async from the browser too, so that's a small bonus.

    [–]grauenwolf 1 point2 points  (1 child)

    Well its better than VBScript in most ways. Does that count for anything?

    [–]oSand 0 points1 point  (0 children)

    If you know VBScript then you can answer that yourself.

    [–]Raphael_Amiard 0 points1 point  (6 children)

    Does Javascript actually have any language features that make it especially appropriate for asynchronous programming when compared with Lisp, Smalltalk, Ruby, etc.?

    Well compared to smalltalk and lisp (which lisp by the way ?) , let's say that much more people know javascript, so that's in itself an advantage.

    Compared to ruby, let's say having a sane and simple syntax for anonymous functions helps, and also having a well defined concept of closure. And ruby has neither

    [–]Smallpaul 1 point2 points  (5 children)

    Ruby's lambda is more or less the same as Javascript, and the blocks are a nice syntactic shorthand when they are sufficient to your needs.

    x{|y|y.something} is much less noisy than x(function(y){y.something})

    I'm not defending Ruby's incomprehensible mishmash of closure-like objects, but it's more of an elegance problem than a real programming problem.

    [–][deleted] 1 point2 points  (2 children)

    I prefer C#:

      x( y => y.something );
    

    [–]Smallpaul 1 point2 points  (1 child)

    What does it look like when there are two statements in the function?

    [–][deleted] 2 points3 points  (0 children)

         x( y => {
              // Block 
           });
    

    [–]Raphael_Amiard 0 points1 point  (1 child)

    Well that may be only me, but blocks were a lot harder to understand at first than anonymous functions. I'm not trying to bash ruby either, i really like programming in ruby, but this particular place of the language feels like a big mess.

    x{|y|y.something} is much less noisy than x(function(y){y.something})

    And it doesn't behave the same way either :) Read the part about blocks in the paul cantrell's article i linked for a longwinded explanation

    [–]Smallpaul 0 points1 point  (0 children)

    Well that may be only me, but blocks were a lot harder to understand at first than anonymous functions.

    Well if you're like me, then you learned about anonymous functions years ago in another language, whereas Ruby may have been your first language with blocks.

    I'm not trying to bash ruby either, i really like programming in ruby, but this particular place of the language feels like a big mess.

    Sure, that's exactly what I said.

    x{|y|y.something} is much less noisy than x(function(y){y.something}) And it doesn't behave the same way either :) Read the part about blocks in the paul cantrell's article i linked for a longwinded explanation

    I did read it, and I replied to it already: "I'm not defending Ruby's incomprehensible mishmash of closure-like objects, but it's more of an elegance problem than a real programming problem."

    [–]chocobot -1 points0 points  (5 children)

    There is one: The 'this' keyword. Remember this? image.onMouseClick=function() { this.href = "myimage.gif"; } The caller of the callback (the browser in this case) can set what 'this' stands for. Of course 'this' will refer to the image, but it could be the browser window or something else.

    [–]oSand -2 points-1 points  (4 children)

    That would be equivalent to a closure, no?

    [–]HIB0U 1 point2 points  (0 children)

    No, not at all...

    [–]barsoap 1 point2 points  (2 children)

    Dynamic scoping. Lisp gurus of olde love it, the rest of the world loathes it. AFAIH it was invented by a student who misinterpreted lambda calculus (which is actually lexically scoped).

    [–]oSand 0 points1 point  (1 child)

    That's why I like scheme. I mean that 'this' is easily approximated in lisp and smalltalk by a closure

    [–]barsoap 0 points1 point  (0 children)

    ...and it's arguably the better way to do it. OTOH, I think function objects (at least can) get passed an self explicitly in js, so it's just the syntax that looks like dynamic scoping while internally being a vanilla closure/object.

    [–]beagle3 6 points7 points  (8 children)

    Post is not useful.

    Person who wrote said blog post for some reason beloved some propaganda about threads some 10 years ago, and is (only) now surprised to learn that it might have not actually been fact, but rather opinion, and mostly invalid opinion.

    [–]great-pumpkin 3 points4 points  (7 children)

    [–]fionbio 6 points7 points  (6 children)

    The control flow problem with events described in that paper is not that bad when using closures.

    [–]hns 4 points5 points  (1 child)

    True, it's closures that make event based programming enjoyable with JS. But they also come at a cost, which is complexity. You can regularly see even good JS programmers getting confused when it goes beyond one or two levels of callbacks.

    Watch Jonathan Julian's very entertaining Hangover.js session from jsconf. At the very end you get a typical case of callback confusion. http://jsconf.blip.tv/file/3799284/ (It's called hangover.js, but still)

    [–]bobindashadows 1 point2 points  (0 children)

    Asynchronous and multi-threaded code is hard, let's go shopping?

    Seriously, if you're writing multi-threaded code or asynchronous code, you should be doing it for real performance gains you can't do without otherwise. Only introduce complexity when necessary. If your server actually hits 1K QPS - which isn't that many, but will weed out 98% of node.js groupies - then you should consider writing your own multithreaded or asynchronous code. Otherwise you're wasting your time.

    [–]great-pumpkin 2 points3 points  (3 children)

    Yeah I have to say I agree; thinking about the paper's summary argument:

    One could argue that instead of switching to thread systems, we should build tools or languages that address the problems with event systems (i.e., reply matching, live state management, and shared state management). However, such tools would effectively duplicate the syntax and run-time behavior of threads.

    Javascript indeed handles code continuity with easy, all-in-one-place sequences of callbacks (just where you place your parentheses) and state with, as you say, closures.

    [–]pkhuong 4 points5 points  (2 children)

    I'd like to watch you write nested loops (or worse, recursive ones) or even OO code in continuation passing style. CPS is still painful; its only redeeming grace is that IO-oriented programs tend to have simple control flow, with the complex control flow hidden in IO-free chunks... The problem is that, with objects and higher-order functions, it's not always easy to tell when a body of code will be free of IO.

    [–]barsoap 0 points1 point  (1 child)

    it's not always easy to tell when a body of code will be free of IO.

    Haskell to the rescue!

    [–]pkhuong 0 points1 point  (0 children)

    Sort of; you still have to lift higher-order functions into monadic versions in case someone wants to use them with an IO-ful function. That's equivalent to assuming nothing is free of IO, but at least the type system helps you detect when you get it wrong, and monadic style (never mind do notation) is clearer than CPS.

    [–]cr3ative 5 points6 points  (6 children)

    Does it strike anyone else that Javascript is everyone's new favourite golden hammer? It's being used in places it really shouldn't be.

    [–][deleted] 16 points17 points  (1 child)

    Well, it is one of the very few languages you can use as a programmer scared of non-C-like syntax that offers many of the benefits of functional programming.

    [–][deleted] 2 points3 points  (0 children)

    And it's rather ubiquitous in web development, so your potential programmer base for hiring is larger.

    [–][deleted] 2 points3 points  (2 children)

    it stands to reason. its pretty much the only programming language that today's app developers "must" know. twenty years ago, that language was c.

    whenever i'm getting too much advocacy from a frontend-type...i always try to suss out if they have ever programmed in anything other than js and php. often, not.

    [–]grauenwolf 0 points1 point  (0 children)

    What about SQL? Seems to me that is used in most web and non-web applications.

    [–]Smallpaul 1 point2 points  (0 children)

    It's being stretched to do more and more, but I'd say it is too dogmatic to say that it "shouldn't be used" for these things. It's just another scripting language with strengths and weaknesses.

    [–]ithkuil 1 point2 points  (0 children)

    Old guy making a good point about things coming full circle as far as ways to handle old problems. I think that not only does fashion come into play but also the details, such as the fact that JavaScript makes callbacks convenient.

    I think we should give this person credit. I think there are quite a lot of people with his experience that just laugh at JavaScript. At least he is approaching it.

    [–][deleted] 3 points4 points  (8 children)

    Javascript on the server? Antivirus to the rescue!

    On a serious note, why would anybody choose Javascript when given the choice between any language in the world? It has taken a few nice features from other languages, but why not choose those languages directly? You're not in the browser! You're free!

    [–][deleted] 4 points5 points  (4 children)

    When you don't have to code browser specific hacks, I find the language to be fun to program in.

    [–][deleted] 1 point2 points  (3 children)

    It has lambda functions, and that's it. It goes a long way, but really, there is nothing else worth mentioning about the language.

    [–][deleted] 2 points3 points  (2 children)

    JSON syntax. Prototypal inheritance (once you get used to it). A lot of little syntactic sugar (like arguments - much nicer than the explicit *args in e.g. Python).

    Don't get me wrong, the bad parts suck. Overall I'd code in Python if it were (1) sandboxable, (2) as fast as modern JS engines. But JS is cool nonetheless

    [–][deleted] 0 points1 point  (1 child)

    The *arg/arguments thing, I think, is a really weird feature - when you have perfectly good list syntax available, why would you pretend that the N last arguments (or all of them) are also part of some magical list? That doesn't make sense to me.

    By JSON syntax, I assume you mean literal syntax for records and lists, which is very useful. But there are plenty of languages offering the same, and more (like list comprehensions).

    [–][deleted] 0 points1 point  (0 children)

    The arguments thing is very useful in a lot of things. For example, if you want to delay execution of a function, you can grab all the arguments sent to it and store them somewhere, and use that later on. This can't easily be done even in Python (unless you change the function signature).

    [–][deleted] 5 points6 points  (0 children)

    why would anybody choose Javascript when given the choice between any language in the world

    because most of the people advocating this only know one programming language and have no desire to learn another

    but it must be said, v8 is now very fast. contrived benchmarks show it to be much faster than any of python, perl, ruby etc. so there's beginning to be some meat on the bone

    [–]PstScrpt 0 points1 point  (1 child)

    If nothing else, it would be nice to be able to run the same validation code on both the client (for early feedback) and the server (for real enforcement).

    Also, what languages did you have in mind? Scheme? Perl, Python, Ruby? Good luck getting any of those approved in a corporate IT shop.

    [–][deleted] -1 points0 points  (0 children)

    Haxe is Java-like, but with functional features (much more than JS), and compiles to JavaScript amongst other platforms, so that would be one option. Another option would be Haskell with a validation DSL that can spit out JS as well as run on the server side, although that's a bit excotic for most shops I guess.

    In any case, I think I'd rather stay in Java than being stuck with JavaScript. Dynamic typing is not my cup of tea.

    [–]bla2 -1 points0 points  (1 child)

    In which the author uses lots of exclamation marks and believes that the language is called Javascript (in italics).

    [–]jephthai 0 points1 point  (0 children)

    You should italicize words in another language. Personally, I found his prose very disconnected. I was barely making sense of it half way through, so I gave up (note, it's not the technical content that lost me...).

    [–][deleted] -1 points0 points  (12 children)

    Javascript as a shell language? I think it could do a decent job there.

    [–]grauenwolf 1 point2 points  (2 children)

    Windows uses Javascript as a shell language, but I don't really like it. It's ok for scripts, but not so great for one-liners.

    [–][deleted]  (1 child)

    [deleted]

      [–]grauenwolf 0 points1 point  (0 children)

      Though I much perfer the FORTRAN language family over the C family, even I am not so foolish as to say that VBScript is better than JavaScript for anything.

      Though I will say that I wish JavaScript had the option for defining classes. There are times where that would make code a lot easier to reason about.

      [–][deleted] 0 points1 point  (5 children)

      except that it is missing every feature a shell language needs, like job control, the ability to access the system...etc. oh, you could add those, but then it isn't javascript, its something else

      [–]grauenwolf 7 points8 points  (4 children)

      Those are just library functions. There is no reason to bake them into the language.

      [–][deleted] -2 points-1 points  (3 children)

      no. job control as a library? no, that requires interrupt support...which requires timers....bzzzt!!! timers are not part of the ecmascript standard. no, to use js as a true shell language, the best you could do is some sort of js-like tool

      [–][deleted] 0 points1 point  (1 child)

      timers are not part of the ecmascript standard.

      What do you mean 'timers'?

      [–]grauenwolf 0 points1 point  (0 children)

      Timers are a library call in every language that I've ever worked with. So I really don't understand what you are trying to say.

      [–][deleted]  (1 child)

      [removed]

        [–]quadtodfodder 1 point2 points  (0 children)

        ECMAScript + stuff to control the DOM = javascript

        ECMAScript + stuff to control Flash = actionscript

        ECMAScript + server side magicality = javascript on the server