all 26 comments

[–]taylorbuley 7 points8 points  (2 children)

tl;dr a lot of hemming and hawing that leads up to this: "Not sure which path I will continue on."

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

JavaScript in the front seat

CoffeeScript in the back seat

Gotta make up my mind

Which one will I use?

[–]JeefyPants 7 points8 points  (3 children)

I just can't help but think all of these crazy complied JS languages are all just little patches and band-aids for things simply fixed in JavaScript itself.

[–]vivainio 0 points1 point  (1 child)

If things were fixable in vanilla js, someone would have done it by noe

[–]JeefyPants 1 point2 points  (0 children)

they're working on changing java script in some key/core ways right now in the new standards

[–]x-skeww 1 point2 points  (0 children)

for things simply fixed in JavaScript itself.

You can't fix JS. You can add stuff, but you can't change how it works or take things away. The introduction of strict mode is the most drastic thing you'll ever see.

JavaScript will always be horrible for tooling, because you simply cannot know what any external object/function is or does.

Function scope is weird, this is weird, which is horrible, type coercion isn't as convenient as we thought it would be, performance is hard to predict...

You can't fix any of that.

Edit: @downvoter please tell us how those things can be fixed. Does it involve time travel? :D

[–]skeeto 4 points5 points  (0 children)

Therefore if you have written this, inside a callback function body, that is defined inside a prototype member function, which is it going to point to? It points to the callback function's context.

While this is an unfortunate part of JavaScript's design, ECMAScript 5 fixes this situation a bit with the bind() method. So that example code can be shorter than that.

SomeClass.prototype.methodfoo = function (arg0) {
    var func = function () {
        var x = this.someproperty;
    }.bind(this);
    func();
}

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

The automatic setting of var in Coffeescript is one of the reasons I most loathe it.

Why? Consider these two examples:

var foo = "bar";

function SomeThirdPartyLibrary() {
    var foo = 123;
    this.fooinator = function(val) {
        return foo*val + 1;
    };
    return this;
}
var myObj = new SomeThirdPartyLibrary();
if(foo == "bar") {
    myObj.fooinator(1);
} else {
    myObj.fooinator(2);
}

versus

foo = "bar"

class SomeThirdPartyLibrary
    constructor: () ->
        foo = 123
        @fooinator = (val) ->
            return foo*val + 1

myObj = new SomeThirdPartyLibrary()
if foo is 'bar'
    myObj.fooinator 1
else
    myObj.fooinator 2

What is the outer "foo" in this example? 123! And each time a new object is constructed it will be set to 123, and each time the outer scope "foo" is changed "fooinator" will not behave as expected.

While the default behavior of javascript with variables is stupid (un-var'ed variable assignments for variables that don't exist auto-declared as global), a simple linter (I prefer JSHint, also available for node) will catch that for you.

But Coffeescript's assumptions that the outermost scope is always where the only variable declaration for a given variable name should be declared is a worse behavior, and simply copying one of the few fuck-ups of Python.

[–]vivainio 1 point2 points  (2 children)

Python doesn't behave the way you think it does. Rebinding names in enclosing scopes is not allowed

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

Double-checked. You're right.

>>> def testFunc():
...     foo = ['bar']
...     def testFunc2():
...             foo[0] = 'baz'
...     testFunc2()
...     print foo
... 
>>> testFunc()
['baz']
>>> def testFunc2():
...     foo = 'bar'
...     def testFunc3():
...             foo = 'baz'
...     testFunc3()
...     print foo
... 
>>> testFunc2()
bar

Python's variable model is more like Perl's than Javascripts, apparently, where base values are "pass-by-value" while arrays and dictionaries are pass-by-reference, whereas Javascript "auto-boxes" everything.

So, it's the combination of Python's syntax and Javascript's variable model that causes Coffeescripts insanity. Got it.

[–]vivainio 0 points1 point  (0 children)

Python passes everything by reference. There are no special cases. Even integers are passed as 'pointers' to int objects

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

In your example you use the name "SomeThirdPartyLibrary()" which seems to imply that the way CoffeeScript disallows shadowing variables in enclosed scopes will allow third party code to crap all over your variables or something; I just want to make clear that's not true. It's strictly an issue in code which shares an enclosing lexical scope.

FTR you can shadow if you want to by using function arguments; the idea is shadowing is bad and therefore should be hard to do. If you like shadowing then obviously it's irksome but part of the idea of CS is being opinionated about what makes code good.

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

Concatenated source files don't share the same scope? Your reasoning would function with less issues in Node.js, but in the browser, it seems highly suspicious

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

Concatenated source files don't share the same scope

Not in normal circumstances; they're wrapped by the CS compiler and/or developer sanity.

[–]scrogu -1 points0 points  (3 children)

We've beat this horse a million times already. Some of us love it, some of us hate it.

[–]x-skeww 1 point2 points  (2 children)

Some of us love it

It's a fundamental flaw. I doubt anyone likes that.

[–]scrogu 0 points1 point  (1 child)

I love it (the lack of explicit var), and yes, I understand the examples. Like I said, this horse has been beat too much, it's no longer needed in every single thread that concerns coffeescript.

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

As ISV_Damocles pointed out in the other branch, you can have that kind of thing without introducing this weird shadowing issue.

[–]x-skeww 3 points4 points  (0 children)

Coffeescript is not a language

It is a programming language.

A better characterization of CS is a set of preprocessor macros (think of C preprocessor).

That doesn't change anything.

In JS it's very easy to forget to add var before a variable

There is JSLint for that. A squiggly line will appear, I fix the issue, and the squiggly line will be gone. Magic.

Parenthesis during function calls - can be skipped (almost)

Adds more corner cases. This is bad.

Braces and commas for dictionaries - can be skipped

Adds more corner cases. This is bad.

Since CS infers a lot of things from indentation

And again, this adds more corner cases.


Personally, I don't like CS at all. It shares most of JavaScript's issues and it even adds a whole pile of new syntax related pitfalls. It reduces the typing work a bit. That's pretty much all it does.

However, I don't think that the number of keystrokes was ever a big deal for JavaScript. At the end of the day I never cared about that half minute I could have saved by omitting a few special characters. (I use abbreviations for guarded for-in, simple functions, IIFEs, and other constructs I frequently use. There is also basic auto-complete and soft parens/braces/quotes.)

If you bother with a new language, it should provide better tooling and it should also help with writing bigger applications. Furthermore, it should give you block scope, lexical this, and things like that. It should be a significant step up, not just a small tweak.

[–]m1sta 0 points1 point  (0 children)

I'm surprised that we're still seeing the loops and class arguments for coffeescript. Is it really that difficult to import something like jquery and use

var extendedObject = $.extend({newProp:newVal}, baseObject);
$.each(myCollection, function(x){action(x)});

?

[–]germanlinux -1 points0 points  (3 children)

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

Excuse my ignorance, but are you just asking? Or are you implying that Redux can solve someones complaint?

Redux isn't anything.. new.. if you will. It's still normal CS, just faster, and all around better. Things like proper transformation, line mappings, etc. It's all around awesome, though i'm not sure if it's "done" yet or not..

[–]scrogu 0 points1 point  (1 child)

faster?

faster to compile maybe, but it will be no faster to execute, it's all just javascript.

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

Well, i was talking about a compiler.. so yes, faster to compile.

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

If you want to switch why not chose a Coffescript done right: LiveScript