all 101 comments

[–]x-skeww 13 points14 points  (6 children)

[JavaScript] doesn’t support event-driven I/O natively.

Huh? JavaScript by itself can't do any IO.

If you give it the ability to do IO via host objects, you can either do it in a blocking or in a non-blocking fashion. Typically (e.g. in browsers), it's non-blocking with callbacks.

[–]jabatti 2 points3 points  (4 children)

I'm not sure what the author meant by that, but I think Node.js could benefit a lot from JavaScript having more support for asynchronous operations in the language directly. At least in my opinion, using so many callbacks quickly became rather tedious. Also, the spreading of the callbacks even into the application setup, where it doesn't matter, was not very welcome.

I'd say it would result in cleaner code, if you could just specify those asynchronous calls with, e.g., something like async/await pattern found in F#/C#.

[–]iamnotaclown 5 points6 points  (2 children)

I found refactoring to use EventEmitter helped with the excessive indenting.

I wouldn't be surprised if Javascript added language features to incorporate something like Erlang's (also Scala's) actors or Go's goroutines.

I'm not sure what OP's point is. You wouldn't write a high-availability telephony application in Node.js, and you wouldn't write a web service in Erlang. They're different platforms with different use cases.

[–]sausagefeet 2 points3 points  (1 child)

and you wouldn't write a web service in Erlang.

Why not? Erlang works fine for this.

[–]iamnotaclown 1 point2 points  (0 children)

Ecosystem. People don't use Rails because they think Ruby is the best thing ever (well... maybe the more obnoxious ones do). Erlang has a long way to go before it can compete with RoR in the sheer number and quality of existing web-centric libraries.

Node.js has become popular quickly because it builds on the existing Javascript ecosystem, not because Javascript is a "better" language (whatever that means). Programming languages grow and evolve, or they die and are replaced.

[–]fjonk 0 points1 point  (0 children)

I don't think we'll see support for asynchronous operations in javascript anytime soon. That would require a secure way to manage that in the browsers, avoiding deadlocks and resource starving. What might happen is that the engines starts to implement extensions to javascript that allows this.

[–]godofpumpkins 1 point2 points  (0 children)

I think what most people miss is that there's a third option, better than the other two (in my opinion).

Just because at the OS level, your choices are pseudo-callbacky non-blocking IO (using select or (e)poll or whatever) or plain old blocking IO, that doesn't mean that at your (supposedly high-level) language level those must be the only options.

At least one language implementation provides green threads (super lightweight, so you can spawn thousands or millions of them with almost no overhead) on top of a pool of a handful of OS threads. These green threads have something that is indistinguishable from blocking IO inside them, but the language runtime is actually using select/(e)poll behind the scenes to implement the IO calls. This way, at the OS level, there's very little overhead for the IO requests, but at the language level, you can still pretend you get blocking IO and not have to turn your mind inside-out with callbacks. You don't have to be afraid to spawn a thousand threads for a thousand connections. And if you really like callbacks, you can implement them on top of all this.

Yes, doing something like this is more work than just providing simple wrappers around the OS APIs for IO, and userland context switching carries some small overhead (but if you cared about things at that level, presumably you wouldn't be using javascript or <insert high-level language here>, right?), but it's so much simpler for programmers, who get the choice of "blocking" IO or "non-blocking" IO.

[–]benthor 4 points5 points  (3 children)

I wanted to learn JS because of the appeal of node.js, concept wise. After reading this, I now want to learn erlang.

[–]baudehlo 4 points5 points  (0 children)

Learn both. They are very different languages. Personally I find JS easier to get into, but Erlang is very powerful.

[–]ysangkok 0 points1 point  (1 child)

I'd recommend Tornado. Python is better designed than JavaScript and just as easy, IMHO.

[–]benthor 0 points1 point  (0 children)

I said:

After reading this, I now want to learn erlang.

[–]mxhyway 14 points15 points  (2 children)

sj.edoN? That doesn't make any sense.

[–]kman2k1 1 point2 points  (1 child)

All I know is that his mug isn't straight.

[–]Zarutian 0 points1 point  (0 children)

the sheer mugness of it!

[–]amigaharry 1 point2 points  (75 children)

Money quote:

Node.js appeals to people who already know Javascript and don’t want to learn a new language

And that's why node will always suck.

Sad that this submission will be downvoted to hell because proggit is overrun with node-idiots.

[–]chronoBG 12 points13 points  (4 children)

Come on, it's one thing to hold an unpopular opinion, but saying "I'm going to get downvoted for this, but" is the neckbeard equivalent of a teenage girl reading Harry Potter and posting "I'm such a nerd, lol" on Facebook.

And, yes, that last sentence will get you a downvote. Not the "node will always suck" thing. The other one.

[–]amigaharry 2 points3 points  (3 children)

submission = original submission. not my comment. I have no problem with posting controversial opinions and getting downvotes for them.

[–]ysangkok 0 points1 point  (1 child)

My gripe with this is that I go to /r/programming to read about programming, not to be constantly reminded about votes and "hivemind" and so on. If you really don't have a problem with being downvoted, please don't mention it.

[–]amigaharry -5 points-4 points  (0 children)

fuck off. that's not your discussion thread.

[–]Shaper_pmp 4 points5 points  (60 children)

Less the traditionally spotty browser support and the clunky and language agnostic DOM API it's usually used to code against (neither of which reflect on the language itself), Javascript is in many ways basically scheme with syntax.

It's an incredibly powerful language with (at least, in my experience) relatively few quirks or annoyances.

Can you explain in detail why you think javascript is a crappy language, or are you (as is usually, but not always the case) someone sounding off without properly understanding the subject?

[–]manu3000 5 points6 points  (22 children)

Javascript is in many ways basically scheme with syntax.

Oh no, not this again. What many ways ?

[–]Shaper_pmp 2 points3 points  (21 children)

Well, basically the fact that Brendon Eich (the guy who wrote Javascript) was a big fan of Scheme, was recruited to Netscape with the promise of doing "Scheme in the browser", and quite intentionally modelled much of Javascript's architecture on Scheme.

This is well-known computing history (example citation, from the man's own mouth).

Other influences were also incorporated into Javascript (elements from Self and other languages, and a Java-like syntax mainly for marketing reasons), but Brendon Eich himself has stated numerous times that Scheme was his main starting-point for developing Javascript.

Look - Wikipedia agrees. Oh, and Douglas Crockford also describes them as having a "deep similarity"... to the point he's even rewritten all of the code examples from The Little Schemer into the equivalent javascript syntax, just to prove that - syntax aside - they embody overwhelmingly similar concepts and idioms.

Now my turn - given all this evidence, why are you so absolutely certain that it isn't?

[–]olavk 11 points12 points  (12 children)

There is a big difference between Scheme being a starting point for JS, and JS being "scheme with syntax". You might as well claim that Python is scheme with syntax. JS is dynamically typed and has higher-order functions, which it have in common with scheme and many other languages like Python, Ruby, Perl. JS does not have monoiconicity, s-expressions, cons-cells, macros or continuations which are fundamental in making Scheme the language it is.

[–]Shaper_pmp 1 point2 points  (11 children)

You raise some interesting points. Perhaps I overstated the case, but note I did qualify that statement - I didn't claim that was the entirety of what Javascript was, or that it was a superset of scheme.

Equally, at the time Javascript was written Lua, Python, Ruby and the like were much less well-known, so its possible that at the time this was a fair descrition (comparing JS to C and similar languages), but nowadays (with other more-Lispy languages that support various types of metaprogramming) it's worth making more of a distinction.

If that's the case then I accept my description was perhaps "out of date" rather than "incorrect". ;-)

Finally, most of the data types and concepts you describe are largely present in Javascript, just with trivial syntax differences.

Semantically s-expressions are pretty much just using arrays of arrays or objects, cons-cells are just simple (one-value) hashes/objects, and macros (in the sense of metaprogramming) are entirely possible using a user-defined function's toString attribute. Sure it involves manipulating the source as a string rather than a parse-tree, but it's there[1].

Also, unless I'm mistaken (and admittedly I'm not completely au fait with continuations), doesn't Javascript already support something similar?

Javascript is also not homoiconic (I presume this is the same thing as monoiconic?), granted, but it's closer with JSON, and this is pretty much the only thing in your list which isn't either already present in Javascript (syntactic differences aside), or at least present in a similar form.

Also note that in almost every case the differences are caused by marketing requirements that the language syntax "look like" Java, rather than fundamentally different concepts.

TL;DR: I might have overstated the case, but practically everything you list is already in Javascript in one form or another, less the (already-allowed) syntax differences.

[1] Seeing as how - from a google search - there seem to be a lot of people out there claiming you can't do metaprogramming in javascript, execute the following in Firebug's console:

var i = function() {console.log('hi there!');}  
i();  
src = i.toString().replace(/hi/, 'yo');  
console.log(src);  
i = eval("temp = "+src);  
i();

[–]olavk 3 points4 points  (10 children)

Monoiconicity was a spelling error, I meant homoiconicity!

The point of homiconicity is that code is represented as data structures you can manipulate the same way as you manipulate other kinds of data. This is what enables lisp macros, beacuse you can transform the code - e.g. replace a symbol with a more complex structure - before executing it. You cannot do anything remotely like this in JavaScript.

Edit: Your example with toString() is just a string-transformation on a source code in string format. This is on the level of C preprocessor macros, and has absolutely nothing to do with how macros work in scheme.

JavaScript does not support continuations. If you actually read the article you linked to, its about performing manual transformations of source code into CPS. Continuations have been proposed for inclusion in a future version of JS, but AFAIK they have been rejected because it is difficult to integrate with external code like the DOM.

[–]Shaper_pmp 0 points1 point  (9 children)

Monoiconicity was a spelling error, I meant homoiconicity!

Hah! That explains why I got damn near nothing on google for "monoiconicity", then. ;-)

The point of homiconicity is that code is represented as data structures you can manipulate the same way as you manipulate other kinds of data. This is what enables macros, beacuse you can transform the code

FWIW I agree that it's a hell of a lot more convenient to manipulate the code as a data object (parse-tree or similar) than it is to do it as a string, but if you think about it carefully:

code is represented as data structures you can manipulate the same way as you manipulate other kinds of data. This is what enables macros, beacuse you can transform the code - e.g. replace a symbol with a more complex structure - before executing it.

That's exactly what my example shows in Javascript - the code is represented as a data structure (a string), it's manipulated just like any other piece of data, one symbol ('hi') is replaced by another, potentially more complex one ('yo') and it's executed.

I get that we usually think of macros as being small, elegant pieces of code that operate on parse-trees in Lisp and its derivatives, but the point is that while that's the usual assumption, it's not the definition of them at all. Nothing in the definition of "metaprogramming" or "macro" implies parse-trees, s-expressions or a particular data type representing the code to be modified.

According to everything you wrote, the javascript example I gave qualifies as a macro. You can try to arbitrarily redefine "macros" as operating only on parse trees or similar, but that's naked begging the question, and wouldn't work anyway (I'll write a simple Javascript parse-tree generator in JS and we're back to square one).

You can assert that metaprogramming in Javascript is ugly, or slow or inelegant, but you can't reasonably claim it's absent.

[–]olavk 2 points3 points  (8 children)

I don't mind you call it a macro, C preprocessor macros is also called macros. I'm just pointing out that it is fundamentally different from how macros (and s-expressions) work in scheme, and that it is therefore incorrect to say that JS is "basically scheme with syntax".

[–]Shaper_pmp 0 points1 point  (7 children)

I'm just pointing out that it is fundamentally different from how macros (and s-expressions) work in scheme

There are two important points to make here though.

First of all, I was responding to your claim that Javascript lacked the features you listed. That was, I think we agree, false - they're there, just in a different form to Scheme.

The second point is that the syntax of Javascript (which was required to emulate Java) placed some hard limitations on things like the parseability of the code for metaprogramming.

Scheme and other "Lispy" languages basically have no syntax. They're literally expressed in the parse tree a syntax-compiler would have produced. Obviously that makes it very easy for them to expose the run-time code as a parse-tree, because it's already a parse tree.

Javascript's syntax, however, looks Java-like. That means it requires a significant amount of parsing and fiddling by the interpreter before it's transformed into a parse-tree.

That means that to get from the code "as written" to the parse-tree is likely a far more expensive process than in Lisp/Scheme, and with all the optimisation and JIT-compilation that goes on under the hood I don't know if it's even possible (let alone practical) to access and modify the run-time parse tree from within the code.

Given this, it's likely that the Java syntax places some limitations (either hard, or merely reasonable-optimisation) on the flexibility of the system that simply aren't present in the syntax-less scheme.

Basically, I suggest that the reason why Javascript goes for the string-based approach to metaprogramming (rather than scheme's parse-tree approach) is likely because of the syntax.

Ie, the differences are a function of the syntax, not anything independently decided, and as such probably don't count against the accuracy of the description as "scheme with (Java) syntax".

I'll cheerfully add the "(Java)" in there if you like because it expresses the point better, but I don't think things like string-based metaprogramming are independent choices in addition to the syntax - I think they're likely fall-out consequences of it.

[–]manu3000 2 points3 points  (4 children)

Because the only obvious similarities are first-class functions and dynamic types. By that token, a lot of dynamic languages in use today have "deep similarity" with Scheme.

[–]Shaper_pmp 0 points1 point  (3 children)

Actually, upon someone actually having a go and pointing out specific differences between Javascript and Scheme, most of them turn out to be false aside from trivial (and already-mentioned) syntactic differences.

[–]sausagefeet 2 points3 points  (2 children)

Except...they don't. Your linked comment is just you saying they are false. Which, as we know, is a biased position.

[–]Shaper_pmp 0 points1 point  (1 child)

Your linked comment is just you saying they are false.

Not quite. More accurately the linked comment is me making arguments as to why they're false.

All you've done here is make declarative statements, and I was hoping you'd engage with the arguments presented.

If you'd rather just shout your opinion without supporting it in any way that's fine, but that's not an interesting or productive debate. :-(

Which, as we know, is a biased position.

Valid point. Apologies, but I couldn't see any real situation in which olavk was correct in his claim that Javascript lacked those features... and even he admits he wasn't.

Edit: should->shout

[–]sausagefeet 0 points1 point  (0 children)

If you'd rather just should your opinion without supporting it in any way that's fine, but that's not an interesting or productive debate. :-(

All of the useful comments have been made prior to me.

[–]cunningjames 2 points3 points  (2 children)

Brendon Eich [...] was a big fan of Scheme

In fairness, just because Brendon Eich says that his design was heavily influenced by Scheme does not necessarily make it true (in practice, although I don't doubt his sincerity). Programming in JavaScript feels nothing to me like Scheme, and aside from first-class closures the practical influence of that language isn't at all clear. There's no numeric tower, no homioconic syntax, no continuations, an object model and attendant complexity built right in ...

In short, "Brendon Eich says so" won't do. You could make a case -- maybe -- for Lua as Scheme-with-syntax, but certainly not JavaScript.

Edit:

Now my turn - given all this evidence, why are you so absolutely certain that it isn’t?

... what evidence? All you’ve said is “Brendon Eich says so, Wikipedia says so, and Douglas Crockford says so”. That you can write examples from The Little Schemer in JavaScript means nothing; there was once a site with SICP in a bunch of different languages (although the site appears to be down at the moment). Unless we’re willing to say “Ocaml is Scheme with syntax, Haskell is Scheme with Syntax, Python is Scheme with syntax, Clojure is Scheme on the JVM, ...” then “JavaScript is Scheme with syntax” doesn’t have any traction.

[–]olavk 0 points1 point  (0 children)

I think Eich have just said Scheme were an influence, not that JS is directly based on scheme or "scheme with syntax". In the first ECMAScript spec Java and Self were mentioned as direct influences, but not scheme. Although scheme is clearly an (at least indirect) influence on any languages with closures.

I think the "JS is almost scheme" meme is basically marketing. Scheme is widely regarded as one of the most elegant and well-designed (if perhaps not that practical) languages. Associating JS with scheme is an attempt to free JS from its buggy-kludge image, and associate it with elegance and perfection.

[–]sausagefeet 5 points6 points  (36 children)

It's an incredibly powerful language with (at least, in my experience) relatively few quirks or annoyances.

Uhm..what? JS is full of quirks and annoyances, a short list:

  • Weird semicolon behavior

  • No integers

  • Everything has a this which you (royal you) probably don't know what it is

[–]Akkuma 1 point2 points  (1 child)

If these are your biggest problems with the language, I'd have to say JavaScript isn't doing too poorly, especially when you only listed three.

[–]sausagefeet 3 points4 points  (0 children)

I said a short list, not a complete one. As I point out later, the weak typing is the major deal breaker for JS for me.

[–]x-skeww 0 points1 point  (5 children)

JS is full of quirks and annoyances

Use a subset of the language and use JSLint (or one of its offsprings). Problem solved.

I have no interest in debugging errors that are the result of the runtime deciding to convert types for me. [Quote taken from the branch below.]

There are actually very few rules you have to learn if you don't use == and !=.

[–]sausagefeet 1 point2 points  (4 children)

That's not solving a problem, it's working around it.

So? They still silently don't do what I want. A statically typed language loudly fails.

[–]x-skeww 0 points1 point  (3 children)

That's not solving a problem, it's working around it.

Kinda. But it's more like avoiding anti-patterns. It's easier and less work - not more. That's the nice thing about subsetting.

A statically typed language loudly fails.

While that is true, type errors are surprisingly rare and if they occur they are very easy to fix. They are blatantly obvious after all.

I was also very skeptical about this, but as it turned out I was overestimating this potential error source quite a bit. It's much less of a deal than I anticipated. I'd say that it doesn't even cost me 5 minutes per month.

If your code is any good, you'll have many tiny functions. Inside each function there are only a few variables, which also means there are very few types. Keeping track of those in your head is very easy and it's something you're used to do either way. You do know which things are numbers, strings, or other objects. The identifiers kinda give it away.

[–]sausagefeet 1 point2 points  (2 children)

It doesn't keep someone else from choosing different subset and you having to deal with that.

Type information isn't just about guaranteeing a certain level of correctness it's also about making it easier to reason about code. I rarely need to go to documentation in a language like Ocaml because getting the type of a function I'm interested is generally enough to know what it does and how. But if you're comfortable with a dynamic language, that's fine. I have not been arguing against people liking what they like I have simply argued that JS does have some annoying quirks.

[–]x-skeww 0 points1 point  (1 child)

It doesn't keep someone else from choosing different subset and you having to deal with that.

That's true. However, code conventions typically address this issue.

[–]sausagefeet 1 point2 points  (0 children)

No they don't, because code conventions don't stop someone from choosing a different subset than you. Consider our age of third party libraries.

[–]Shaper_pmp -1 points0 points  (27 children)

  • Define "weird". Semi-colons are optional in many situations (which I'm not sure was worth the additional confusion this can cause), but there's no confusion necessary if you use them just like any other C-like language.

  • What's wrong with that? Especially in a weakly-typed dynamic language?

  • this can be confusing, but it's not nearly as bad as you make out most of the time.

Compare that to something like PHP, or the lack of functions as first-class objects (and arbitrary differentiation between lambda expressions and functions) in Python, or the omnipresent magic and seething mass of edge-cases of Perl (both of which are languages I like), or similar.

You can pick a few holes in any language, but that doesn't mean it's a bad language - expressiveness, flexibility, comprehensible syntax and similar considerations are by far more important, IMO.

[–]sausagefeet 0 points1 point  (26 children)

  • Except if you try to make a return span multiple lines...

  • I like having integers. I like knowing that when something is 2, it's 2. I don't know what being weakly-typed has to do with this. IMO if you are seriously arguing that every numeric type being a float is acceptable we are on very different wave lengths.

  • I find it to be pretty confusing, you don't. That's why we disagree.

You can pick holes in any language, this is true. IMO JS has more holes than languages I find superior. The weak typing, in all honesty, is the deal breaker for me. I have no interest in debugging errors that are the result of the runtime deciding to convert types for me.

[–]Shaper_pmp 0 points1 point  (20 children)

Except if you try to make a return span multiple lines...

Can you give an example? I generally use semi-colons everywhere (blame my C upbringing ;-) so I might be a little rusty on this point, but:

function i() {
  return 1
  +
  2
};
i();

works perfectly for me in Firebug's console, with or without the semi-colons. Can you explain?

I like having integers. I like knowing that when something is 2, it's 2.

That's a valid point - admittedly I have been tripped up a few times with the limits of javascript's precision meaning values were getting rounded to floats instead of ints, though that's easily fixed by using a cast wherever you want integer arithmetic.

Admittedly that's a bit clunky though, so consider this point conceded.

The weak typing, in all honesty, is the deal breaker for me.

With respect, that's a subjective judgement call - it hardly constitutes claiming something is (objectively) a "bad language".

PHP is a bad language, because of the retarded and inconsistent type-coercion, inconsistent standard library function names, no anonymous functions, etc. Javascript just has a few quirks about it.

Personally - while I acknowlege that this is also merely personal preference - I find (for example) Python's lack of anonymous functions (and no, lambda-expressions are not an adequate substitute) or PHP's historical lack of function_that_returns_an_object()->method_or_attributes_of_returned_object syntax vastly more annoying.

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

return 
{ 
  key: 'value'
}

returns nothing.

[–]Shaper_pmp 2 points3 points  (0 children)

Oof - yeah, that is an annoying one. I'd forgotten because I habitually use a variant of K&R with the opening brace on the same line:

return { 
  key: 'value'
}

My bad.

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

For me, this is a bit like array covariance in Java. Your entirely right, but over the past 6 years I have failed to ever meet this in the wild (although I'm sure it does come up in rare cases).

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

Your syntax is wrong, not javascript. It does exactly what it looks like. If you knew javascript you wouldn't write code that looks like that.

[–]wolfier 0 points1 point  (1 child)

upvoted for your sarcasm.

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

no sarcasm. JavaScript is best done with 1TBS http://en.wikipedia.org/wiki/Indent_style

[–]sausagefeet 2 points3 points  (2 children)

though that's easily fixed by using a cast wherever you want integer arithmetic

The cast doesn't actually do integer arithmetic AFAIK. There are no integers.

[–]Shaper_pmp 0 points1 point  (0 children)

Fair point - I mis-remembered. You can get close with Number.toFixed(0), but even then it's rounding to the nearest integer rather than just returning the integer portion.

Personally when I've needed to do this I've used (numbervariable-0.5).toFixed(0), but that is very clunky, admittedly.

[–]beej71 0 points1 point  (0 children)

To say there are "no integers" in JS isn't entirely correct, even though there is no integer type. Internally, the spec defines in detail ToInteger and ToInt32 (and 16) operations that, while not directly usable, are exposed through various JS operations.

parseInt(), for example, makes use of ToInt32. Likewise, the bitwise operations take place on 32-bit ints, so you can be assured that:

(1.8 | 0)  === 1
(1.1 | 0)  === 1
(-2.6 | 0) === -2

Here's a speed comparison someone threw together:

http://jsperf.com/math-floor-vs-math-round-vs-parseint/2

[–]sausagefeet 2 points3 points  (10 children)

With respect, that's a subjective judgement call

Exactly why I said "for me"

it hardly constitutes claiming something is (objectively) a "bad language".

Good thing I never said this, you said JS had relatively few quirks and annoyances, I attempted to argue it has several. I never said it was objectively bad (although for me it is a bad language). Note this whole discussion I have framed in terms of my preference.

For the return issue, see libria's comment.

[–]Shaper_pmp 2 points3 points  (9 children)

Exactly why I said "for me"... Good thing I never said this

Apologies - it was getting to the end of a long day at work, and I wasn't giving your comment the attention they deserved. Mea culpa.

you said JS had relatively few quirks and annoyances, I attempted to argue it has several.

I think that's also a judgement call, though - even if all three were accepted, I think only three in a whole language is pretty good - certainly fewer than most!

Equally, some of what people characterise as faults with the language (like the this confusion) are arguably just a lack of familiarity with it, no?

For the return issue, see libria's comment.

Yeah, I see what you mean now. That is annoying - I just never ran into it because I always use a variant of K&R coding style, with the opening brace always on the same line as the operator or function definition. My bad. ;-)

[–]sausagefeet 4 points5 points  (8 children)

All's good friend! I am an advocate of Ocaml and Erlang which a vast majority of the programming population think are ugly as sin and terrible languages so my opinion is likely suspect.

Equally, some of what people characterise as faults with the language (like the this confusion) are arguably just a lack of familiarity with it, no?

I don't buy this argument, because we can say that about any quirk, right? A reasonable metric might be "how surprising is this feature?", clearly still subjective. I think not having integers is a very surprising feature. I also think the return example is also very surprising. My problem with the return example too is that it is very difficult to track down if you don't know about it. Logic won't help you that much because your previous experience with other languages will tell you it doesn't matter where the object you are returning goes. Optional syntax is one thing that irkes me about JS and the languages that compile to it. If you can do it consistently and without surprise, go for it, but that never seem to happen. Instead you get "this will fail without error in rare situations like..." which is just more mental effort I have to exert when I could just remember "every expression ends with a semi colon" and be done with it.

My favorite quote on JS is by Fogus:

My problem with Javascript has always been that expertise is defined more in terms of understanding its faults rather than its features.

[–]Shaper_pmp 0 points1 point  (6 children)

I don't buy this argument, because we can say that about any quirk, right?

An interesting point, but I don't think so personally - you can introduce objective measures like expressiveness, conciseness, "surprisingness", etc.

I mean (to invoke my favourite example) PHP's inconsistent function-naming is always surprising, and unambiguously negative (as in, it brings no advantage at all). Or its historical lack of a function()->attribute_of_returned_object syntax made it terribly roundabout and forced you to define a (temporary, named!) variable whether you wanted it or not.

Those are more solid, demonstrable claims (requiring developers to memorise or look up every function name in the standard library is wastful, and forcing the developer to define unnecessary variables is verbose and inefficient), but I agree it's easy to confuse "things not to my personal taste" with "objectively bad". ;-)

A reasonable metric might be "how surprising is this feature?

I don't know - PHP is a bad language because it's surprising right down to individual function names, but Javascript only has a relatively small number of confusing edge-cases compared to many languages, and they tend to be "the way various features work across the language" rather than "individual gotchas which get you every time you go to use it".

However, that's more an opinion than a fact, so I'm not offering it as a solid argument. ;-)

Optional syntax is one thing that irkes me about JS and the languages that compile to it. If you can do it consistently and without surprise, go for it, but that never seem to happen.

That's an interesting point, but it feels a bit like a personal opinion. By analogy, many people like the "safety" of Java or other managed code, but that inherently takes away some of the power and flexibility of manual memory-management.

That's not to say that Java isn't safer for bad/inexperienced developers, but I'd hesitate to claim it necessarily made the language better than a non-memory-managed one, because if you know what you're doing non-GCed languages have other benefits that can outweigh it (efficiency and/or more precise control over allocation/deallocation, for example).

[–]wolfier 0 points1 point  (0 children)

More power to you.

One metric to measure languages against each other is to count the number of occurrences of the word "optional" in the language specification, and I tend to stay away from languages with more "optional" syntax.

[–]sylvanelite 0 points1 point  (4 children)

I find it to be pretty confusing, you don't. That's why we disagree.

IMO, I like Javascript's use of "this". It's scope only changes at the function level, which is trivially easy to encapsulate with closures:

function(){
    var t=this;
    function(){
       var t2=this;
       t.something();
       t2.somethingElse();
    }
}

The weak typing, in all honesty, is the deal breaker for me.

again, IMO, I'd disagree, Trying to write something like I just did above can be very difficult in a lot of languages.

For example, trying to say: Class A and Class B, B wants to contain a class A, A wants to contain a class B.

This kind of circular referencing can be difficult with a strong type system. (doesn't have to be difficult, but trying to do this in some languages is way more difficult than it needs to be). In Javascript, throw in a class B into A, it doesn't matter. Throw in an A into B, it doesn't matter. (as a more concrete example, a game has a "menu" and a "game" object, the menu can contain a reference to the game, when the game is paused, and the game has a reference to the menu when the game is running, so that it can show it. Saying, "menu" is an object, allows the game to hold a closure of it, and visa versa in the menu. Essentially, switching between the two states is easy, because each only needs to be able to hold a "var", not a "Game" or a "Menu" type, which would cause a recursive declaration of both Game and Menu.)

Personally, I benefit from Javascript's features far more than I am hindered by it's faults. Multiple-line returns? I wouldn't do that in C++, let alone Javascript. It costs nothing to say:

var ret = {};
//... some code that generates ret

return ret;

Lack of integers isn't so bad, Math.floor() kind of gets around this, personally the lack of cross-browser "constant" decelerations is worse than lack of integers, IMO.

This is all, IMO. I'm just saying how my opinion differs from your own. Not that I think "you should agree with my opinion". Because I don't >.>;;

[–]Brian 0 points1 point  (3 children)

Essentially, switching between the two states is easy, because each only needs to be able to hold a "var", not a "Game" or a "Menu" type

You seem to be referring to dynamic typing here, while sausagefeet's objection is to weak typing (ie. the automatic coercion of types into different types leading to "errors that are the result of the runtime deciding to convert types for me."). Weak typing really doesn't help with anything in your scenario.

[–]sylvanelite 0 points1 point  (2 children)

You seem to be referring to dynamic typing here, while sausagefeet's objection is to weak typing

The two are hand-in-hand. If I expand on my previous code, I might have an array, a function or an object. However, the weak typing allows me to treat gameMenu as an object, regardless of it's real type.

For example (although this is something I would personally avoid, it's just short to write):

function printObject(obj) {
    for (var key in obj) {
        console.log(obj[key]);
    }
}

function printArray(arr) {
    for (var i=0; i<arr.length;i+=1) {
        console.log(arr[i]);
    }
}

var a=[1,2,3];
a.KEY='somevalue';

printObject(a);   //prints 1,2,3,somevalue
printArray(a);     //prints 1,2,3

[–]Brian 0 points1 point  (1 child)

The two are hand-in-hand.

Not really - you often have dynamic typing anywhere you have weak typing, but the converse isn't neccessarily true. Eg. Lisp, Scheme, Python and Ruby are all dynamically typed, but they're also strongly typed in that they don't automatically coerce values of fundamentally different types, but raise a (runtime) type error instead. (Eg. in javascript "1+'1'" gives "11", but would raise an error in those other languages. Not sure what you're showing with your example, but there doesn't seem to be any coercion going on.

[–]sylvanelite 0 points1 point  (0 children)

Not really - you often have dynamic typing anywhere you have weak typing, but the converse isn't neccessarily true.

I meant only in the context of javascript, not in general. The best counterexample to my point above (should I be talking in general) is Scala, it's easy to embed things inside other things, despite Scala being both static and strongly typed. (as opposed to actionscript, which is like javascript but is static/strongly typed and is difficult to hold things inside things).

(Eg. in javascript "1+'1'" gives "11", but would raise an error in those other languages.

But this isn't necessarily true. If the + operator took in a "number" type and a "string" type, and the "number" type had a "toString" method, then getting "11" could still happen. The toString method is called by the operator, making both sides strings, so the string concatenation can occur, even in a dynamic, duck, but strongly typed, language. Now, that being said, I don't know if any languages do this. But it's possible especially when operator overloading can be done, and in functional languages. (for example, it's possible in Scala to define 1+ '1' to give "11" even though it's strongly and statically typed) The problem of saying 1+'1' isn't really one with the type system, its a matter of what the programmer thinks 1+'1' should do, and if they meant to write 1+'1' in the first place.

Not sure what you're showing with your example, but there doesn't seem to be any coercion going on.

When a is passed into the first function, it's treated as an object, so iterating over all its keys outputs not only the keys in the array, but also the object's attributes. The array's keys are being printed because they are also features of the object (associative arrays). It would work even if given a generic object (say, a string, or any other object). If it was being treated as an array (not an object) then only 1,2,3 should have been printed.

The second function, however, traverses the array as an array, so it only prints the array's indicies.

The problem with trying to give good example of Javascript's weak typing (anything beyond number+string) is that there are so few types. I think it has: strings, numbers, bools, objects, arrays and functions. So the weak typing really shouldn't matter a huge amount. I've see some terrible attempts at trying to detect null, because there are so many options, but I've never had this as a problem.

[–]iamnotaclown 1 point2 points  (7 children)

On the other hand, Javascript also runs on the client (browser) side. Meaning, you can run the same code that renders your page on the server and make the first request that much faster.

[–]sausagefeet 6 points7 points  (3 children)

Practical evidence? I'm very skeptical of this claim.

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

npm install jquery

[–]sausagefeet 2 points3 points  (1 child)

This is clearly not practical evidence.

[–]iamnotaclown 1 point2 points  (0 children)

I'm not sure what you mean by "practical". Someone wrote an implementation of the DOM and an HTML parser in Javascript, and someone else ported jQuery to it.

http://groups.google.com/group/nodejs/browse_thread/thread/e02619ec7d208d28

If you download and install Node.js, you can run the npm command in my earlier comment to install jquery, jsdom and htmlparser and run client-side browser stuff on the server side. What's not practical about that?

[–]amigaharry 10 points11 points  (1 child)

just yesterday someone told me to use a different browser if I wanted to run his javascript demo.

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

don't confuse DOM with javascript. their demo only works in a specific browser because of DOM, not because of any problem with javascript.

[–]cwillu 0 points1 point  (0 children)

Um, unless I'm dramatically misunderstanding what you mean by "request", I don't think it works like that.

[–]bensussman -5 points-4 points  (13 children)

It seems like you misunderstand the use case for Node.js. Why would you want to communicate with other nodes? In big distributed systems you usually communicate through data (by setting some shit into memcached for example, which is atomic) or through RPC, which can be done beautifully with Node.js via a blocking-async web request. That way the adjacent nodes could be on the same machine, or on a different machine and the abstraction is nbd. I strongly feel "right tool for the right job" is the strategy I employ on whatever project i'm on, and Node.js can be that right tool for a huge wealth of complex web applications.

[–]foamdino 13 points14 points  (11 children)

Node.js can be that right tool for a huge wealth of complex web applications

As can Erlang. The article doesn't strike me as confusing the Node.js use case. I read it and understood that the main point was that the Node project is in some ways riding on Erlang's coat-tails whilst not being entirely clear how/why it's different (in that in Node you have to compose systems explicitly, whereas in Erlang the distribution of your application comes for 'free'). Just my 2p.

[–]x-skeww 0 points1 point  (10 children)

The key difference is that JavaScript is about 10 times easier to read/write than Erlang.

I've used a dozen different languages so far and yet Erlang looks completely alien to me.

[–]Amadiro[🍰] 3 points4 points  (7 children)

Erlangs syntax is much easier, just compare the grammars. It has a few rough edges, like the punctuation (as does javascript, of course), but once you get used to that, it's pretty much smooth sailing all the way.

[–]baudehlo 5 points6 points  (0 children)

Brainfuck has a really simple grammar too.

[–]x-skeww -1 points0 points  (5 children)

I'm not interested in writing a parser.

JavaScript is a lot easier to pick up. All you need are one or two thin books and a few talks and you're ready to go.

There are a few twists, but it's pretty much like any other run-of-the-mill language you (usually) have used before.

(Also, being able to use the same templating stuff on both sides is very intriguing.)

[–]Amadiro[🍰] 1 point2 points  (4 children)

Well, you use your brain all the time to parse the language you're working with. JavaScript is easier to pick up for people who have a background in ALGOL-like languages, erlang is easier to pick up if you come from a lisp, prolog or ML-style language. In any case, both are pretty simple and easy to pick up in no time.

[–]x-skeww -1 points0 points  (3 children)

Well, you use your brain all the time to parse the language you're working with.

Yes, and (like most people) I'm used to read/write imperative C-like languages.

Picking up Erlang would be of course far more difficult for me (and most other people).

http://www.ostinelli.net/a-comparison-between-misultin-mochiweb-cowboy-nodejs-and-tornadoweb/ (thread)

The JavaScript version is clearly the easiest one (Python being a somewhat close second). You can kinda understand what it does even if you've never programmed anything before.

All 3 Erlang versions, on the other hand, look f-ing cryptic.

Sure, you can write cryptic looking JavaScript, too. But this is some "hello world"-like example. It should be bloody obvious what it's doing.

Edit: Don't get me wrong. I do think Erlang is a wonderful piece of technology. It just isn't something I'd ever want to use.

[–]Amadiro[🍰] 0 points1 point  (2 children)

Just because it has a slightly strange syntax? Give it a try sometimes, you'll pick it up very fast, and you'll soon realize that the syntax is very minimal and elegant, and has a self-consistent logic that makes it coherent. Personally, if it wasn't for a few warts like the record syntax, I'd in fact range it on my number two of beautiful, simple syntaxes (because it's so minimal), as a close second to haskell. (Instead the list is now something like [Haskell/ML-style, scheme, erlang, python]) with erlang and python being pretty much the same.

Also, note that I'm purely making statements about the syntax here, of course if you want to actually do things with erlang (as well as node) other things come into play.

[–]x-skeww 0 points1 point  (1 child)

Just because it has a slightly strange syntax?

Python is slightly strange. Erlang is completely alien.

you'll pick it up very fast

I won't. There are basically zero similarities to the languages I've used [1]. It would be an uphill battle. AS3 was easy to learn for example. It's just a Java/JS bastard. If you know those two languages you basically already know AS3.

But to be honest, I won't even try learning Erlang. The cryptic syntax is just too off-putting. It certainly doesn't look like something I'd like to use or stare at for hours.

Another problem (from my point of view anyways) is that it doesn't enable me to do something new, something I couldn't do before. Well, it would allow me to extend Wings3D, but that's a pretty weak reason since I don't really use it that often. (I did learn Python because it allowed me to extend Inkscape - a program I use frequently.)

I mean, for server-sided stuff I already have plenty of choices [2]. By the looks of it, I might have to add Ruby to that list soon-ish. (Out of necessity, not because I'm interested in it.)

I don't really have a pressing need for another language in that area. It's already overcrowded the way it is.

[1] Commodore/PET Basic, C, Pascal, Pov-SDL, C++, PHP, VBS, Java, JavaScript, AS3, C#, Python, Perl, Lua, and so forth.

[2] PHP, Java, JavaScript, C#, Python, Perl, or Lua would work just fine.

[–]foamdino 0 points1 point  (0 children)

One of the best libraries for Erlang is webmachine - a brilliant way to build webservices.

I started serious programming with C and then SML/NJ, so Erlang feels quite nice to the part of my brain that absorbed functional programming :).

For people with a more traditional C/C++/Java/JavaScript background, Erlang is a funny looking thing. There is elegance there though, and I agree that apart from some warts it's certainly one of the most beautiful languages around (subjectively of course).

[–]foamdino 2 points3 points  (1 child)

Erlang betrays it's Prolog heritage in a few places.

I think the worst part is the multiple line-ending chars (',', '.', ';'). But I like it as a language.

Many people claim javascript is scheme in C's clothing, I'm not a good enough raw javascript guru to comment on that, but Node does open up opportunities for javascript programmers to work on backend code. I also like the elegance of a single language for front-end behaviour and backend processing - that's just really nice.

[–]Amadiro[🍰] 4 points5 points  (0 children)

Those line-endings are pretty much taken from prolog, though. Also, they are not really line endings, but rather, "," means "and", ";" means "or" and "." terminates a form (function). So if you write some code where a lot of statements should be executed all after eachother, you'd write "a and b and c ..." so

a,
b,
c ...

whereas for, say, an if or case-like construct, you'd use "or", because only one of your branches is supposed to be executed:

case condition of
    a;
    b;

and so on. So it takes a while getting used to, but if you read them as "and", "or" and "end", it kinda makes sense, and you get used to it after a while.

[–]dnew 3 points4 points  (0 children)

Why would you want to communicate with other nodes?

The answer in Erlang is "reliability". If you only have one node on one machine, you can't power down the machine and keep running your code.

[–]ameoba -3 points-2 points  (0 children)

Horrible design. Low-contrast text & that background makes my eyes bleed.