CoffeeScript naming lambdas - javascript

In JavaScript, you can name lambda functions
(function() {
...
}).call()
doSomething(param1, param2, function() {
...
});
like
(function main() {
...
}).call()
doSomething(param1, param2, function callback() {
...
});
So they are not anonymous and error tracing becomes clearer to the programmer -- especially useful with Node.js to avoid (or at least understand) callback hells.
I am currently getting into CoffeeScript to try and see if it makes my coding clearer/faster, but can't get around to naming throw-away functions like these ones.
(->
...
).call()
doSomething param1, param2, ->
...
Is there a way to name these functions in CoffeeScript? Although not critical, I would see that as a big fault in CS.

I got my answer from here.
Basically, you can't do that -- CoffeeScript does not allow the naming of functions. They say it's because of IE9 compatibility, but what if you don't really care about that? (Come on, even low information users nowadays know IE8 and lower aren't meant for use, and in my personal opinion those browsers died together with Win XP.)
Back to the answer, CoffeeScript only accepts function expressions, as opposed to declarations -- meaning I can't name a lambda function unless I assign it to a var and pass it as a parameter later.

Also discussed in the FAQ: Q: Is there any way to name functions, for reflection and recursion?
https://github.com/jashkenas/coffee-script/wiki/FAQ
It lists a number of related repository issues, including:
https://github.com/jashkenas/coffee-script/issues/366

Related

Decorators on functions

I see that babel.js decorators (available in "stage 1") implement the spec at https://github.com/wycats/javascript-decorators. It appears that decorators are limited to (1) classes, (2) accessors, and (3) methods. In my case, I want to use decorators on plain old functions, as in
#chainable
function foo() { }
where (just an example)
function chainable(fn) {
return function() {
fn.apply(this, arguments);
return this;
};
}
I don't see any logical reason why decorators should not be able to apply to functions. My question is, is there some way to accomplish this? Or is there some good reason why functions cannot be decorated?
It turns out there is an issue raised for this at https://github.com/wycats/javascript-decorators/issues/4.
To execute a decorator, you evaluate an expression and doing that prevents hoisting (even for a variable declaration, the right-hand side of an assignment stays put). Therefore, it is not compatible with function declarations being hoisted.
As a work-around, I suggested that function expressions, generator function expressions and arrow functions could be enabled to be decorated:
const func = #someDecorator('abc') (x, y) => { return x + y };
Alas, that wasn’t met with much enthusiasm: Decorators for functions
You certainly have a point here.
But as neo_blackcap pointed out, function decorator are not part of the ES7 decorators draft.
So, the best thing you can do is to start discussion on the corresponding tracker to attract community attention to your proposal.
ES7 decorators are on their first stage of development second stage of development, meaning that their API is still under development and could undergo any change.
I think the problem is function decorator has not been ES7 draft.
Of course, you still can implement your function decorator by yourself

Code convention for function and callbacks

So I started learning javacript and I've noticed that the coding convention for functions and callbacks is something like this (this is a jQuery example but I've seen these everywhere):
$.getJSON('some/url.json', function(a) {
// do stuff with a here
});
Coming from other languages, I would usually write the above as this:
function myFunction(myVar){
//do stuff with myVar here
};
$.getJSON('some/url.json', myFunction());
Why is the former usually the preferred way of writing in JS, instead of the [probably more readable] latter?
There are plenty of good reasons to use the second, more explicit, format (assuming you fix the issue listed in the comment), including:
reusing the function passed as a callback
giving that function a definitive name to make it easier to debug
making sure that function is noted as something important in your system
separating out that functions because it's simply too long to comfortably declare in place
But the first format, with an anonymous function passed as a callback is short and sweet. If you don't need to reuse the function, if it's relatively short, and if it's not of high importance in your system, it can be really useful to declare it exactly where you use it. You avoid adding another variable to your scope, and you make it entirely clear exactly what that function is for.
It's not the preferred way. You can do anything you want. However, if you need to reuse the function, then you need to do your second option, or alternatively the following, for code reuse:
// in some accessible context/namespace
App.myCallback = function(a){
...
};
// somewhere else
$.getJSON('url', App.myCallback);
Your first example is what is referred to as an anonymous function or block. They are used when they'll only be called once. The second example is when you'd use the function many times... it would be a lot of wasteful typing if you repeated the anonymous block over and over.

Why is setTimeout("otherFunction()",2000) wrong?

I am a newbie to java script and currently reading John Resig's Pro javascript techniques . While explaining closure he refers to calls like setTimeout("otherFunction()",2000) as instances where new JS developers have problems . I could not understand why this is a problem ? Can some one explain please ?In this http://www.w3schools.com/js/js_timing.asp I am seeing a call like var t=setTimeout("alertMsg()",3000); which looks similar to me .
It's not "wrong", it's just not necessarily "right", and it's certainly not recommended.
The setTimeout() function's first parameter can be a string or a function reference / function expression.
If you pass a string it will be slower because effectively you are doing an eval() which is not recommended. More important than speed though is that the scope in which the code in the string executes may not be what you are expecting (and may not be the same in different browsers).
By passing a function reference / function expression instead these problems can be avoided.
The "right" syntax for your example is:
setTimeout(otherFunction, 2000);
Note there are no parentheses after otherFunction - if there were it would call otherFunction() immediately and pass the return value from that function to setTimeout().
If you need to pass parameters to your function you can wrap it in an anonymous function:
setTimeout(function() {
otherFunction(param1, param2);
}, 2000);
That may seem kind of clunky compared to setTimeout("otherFunction(param1,param2)", 2000) but again it avoids issues with scope of where otherFunction, param1 and param2 are defined.
The recommended approach is to use the following:
setTimeout(otherFunction, 2000);
or a closure:
setTimeout(function() {
otherFunction();
}, 2000);
Do not use the overload which takes a string as first parameter because the javascript interpreter will need to parse this string into javascript code.
And yeah, the site you have linked to http://www.w3schools.com is probably one of the worst sites out there to learn programming. It shows exactly what you shouldn't do.
Because it has to eval otherFunction() (and hence spawn a new instance of the interpreter) every time. If you provide a reference to the function, setTimeout can execute it without the necessity to spawn a new interpreter.
So use:
setTimeout(otherFunction,2000);
Anything enclosed with "" is a string so a JavaScript interpreter will generally need to parse the string.
Parsing the string is unnecessary even if it works.
If we simply use
setTimeout(alertMsg,3000);,
the interpreter is not required to do any additional (unnecessary) work, resulting in better code.
Instead of setTimeout("otherFunction()",2000), pass the function directly by doing
setTimeout(otherFunction,2000) is much better. The previous way has to do eval the string "otherFunction()".

Javascript Function Syntax

In my feeble attempt to learn JavaScript, I bought a book which teaches you how to do things in JavaScript, but forgets to mention WHY.
Coming from PHP I am familiar with the typical function syntax:
function name() {return;}
which from what I understand works the same in JS.
Then I decide I want to attempt to use the YUI 3 framework for a small project to continue learning and come across this...YUI Global Object
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
As far as I understand this is using the 'use' function of the YUI() object, passing 'node' to the 'use' function....but then what...why is it declaring a function within another function call?
Could someone please explain the syntax being used here?
Also a good reference that explains JavaScript general syntax's similar to php.net would also be beneficial.
Thanks for your help.
Its an anonymous function. Its considered a callback.
In PHP 4 and early versions of PHP 5 you might see something like this:
PHP
function callback($var){
...
}
array_filter( $array, "callback" );
In later versions of PHP 5 you can define them as anonymous functions inline.
So, in JavaScript, the old version would look like this:
JavaScript
function use_callback(Y){
Y.Node.get('#demo');
}
YUI().use('node', use_callback);
But by defining an inline anonymous function, you can save the extra clutter and defined function:
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
Both those functions are equivalent.
In javascript, functions can be passed around as variables. So, here's some other ways that the YUI code could have been written
//original
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
//more traditional "global function"
function useNode(Y) {
Y.Node.get('#demo');
}
YUI().use('node', useNode);
//local callback function
var myUseNode = function(Y) {
Y.Node.get('#demo');
}
YUI().use('node', myUseNode);
edit As for the second half of your question, you could write what I know about PHP on a postage stamp, so I can't help you there, sorry :-)
This is constructing an anonymous function, and then passing the function itself in as an argument to use. The use method will then call your anonymous function with a value, which in your function will be called Y, which contains the modules that you asked for in the previous arguments to use.
This is essentially equivalent to the following, which passes myFunction in as a callback to YUI().use, except that the anonymous function doesn't have a name:
function myFunction(Y) {
Y.Node.get('#demo');
}
YUI().use('node', myFunction);
This pattern is used because JavaScript doesn't have any kind of explicit notion of namespaces or modules. They can be emulated, however, by using the scope of a function to act as a sort of namespace. In this case, YUI().use will construct an object that has all of the functionality that you request, and pass that object in to the function you provide, so you can use that Y object to call methods that you have imported.
For a good online reference on JavaScript syntax and methods, I like to use the Mozilla Developer Center documentation. In particular, they have good references on JavaScript and the DOM. As it is part of the Mozilla project, they focus on the methods and syntax supported by Gecko (the rendering engine of Firefox), but they usually include compatibility notes to mention what is portable and what is specific to Gecko.
For your question, I would recommend reading the MDC documentation on functions and function scope. Sadly, the MDC doesn't usually come up on top on a Google search; instead, you get W3Schools, which tends to be lower quality and have more ads. I've found it useful to always prefix my searches for anything about JavaScript or the DOM with "mdc" in order to get the MDC documentation; so, for instance, to find that link, I searched for mdc function, and found what I needed.
In JavaScript, functions are objects. In that case, they are passing in an object as the second parameter value (and defining it inline).
YUI().use('node', function(Y) {
Y.Node.get('#demo');
});
is the same as this:
var xxx = function(Y) {
Y.Node.get('#demo');
};
YUI().use('node', xxx);
It is an anonymous function (akin to lambda function) declaration.
YUI().use('node', function(Y) {
Y.Node.get('#demo');
})
In Javascript, functions are 1st class citizens - they are objects like any other; hence, they can be passed as parameter.
What is being shown is what is known as an anonymous function that is being passed as an argument to a function. I don't think PHP has first-class functions like this, so I have no idea how to explain the syntax in terms of that (I also don't do much with PHP, so..)
Here is my example code:
function something_random(a) {
alert("the type of a is ... " + typeof(a));
if (typeof(a) === 'function') {
a();
}
}
Now with this function in mind, you can plug this into Firebug or something similar and run the following code:
something_random(function () {
alert("This is a test.");
});
Something interesting will happen here - you will get two alerts. One should say "the type of a is... function" and the other should say "this is a test." This is because in JavaScript - as well as some other languages - functions are treated just like objects (well, they technically are objects.)
You can throw around functions all day if you like - they are just like numbers, arrays, and so on.
Something interesting can also happen. You can also pass arguments into anonymous functions, which is something that jQuery does quite a bit (except it uses call, but we won't go there.) This is where you get the special things like where you put function(d) {} in a code.
Hope this helps.

Are named functions underrated in JavaScript?

Taking the jQuery framework for example, if you run code like this:
$(document).ready(function init() { foo.bar(); });
The stack trace you get in Firebug will look like this:
init()
anonymous()
anonymous([function(), init(), function(), 4 more...], function(), Object name=args)
anonymous()
anonymous()
As you can see, it's not very readable, because you have to click on each function to find out what it is. The anonymous functions would also show up as (?)() in the profiler, and they can lead to the "cannot access optimized closure" bug. It seems to me that these are good reasons to avoid them. Then there's the fact that ECMAScript 5 will deprecate arguments.callee in its strict mode, which means it won't be possible to reference anonymous functions with it, making them a little less future-proof.
On the other hand, using named functions can lead to repetition, e.g.:
var Foo = {
bar: function bar() {}
}
function Foo() {}
Foo.prototype.bar = function bar() {}
Am I correct in thinking that this repetition is justified in light of the debugging convenience named functions provide, and that the prevalence of anonymous functions in good frameworks like jQuery is an oversight?
I agree there are certain downsides to using anonymous methods in JavaScript/EMCAScript. However, don't overlook how they should be used. For simple one liners that you want to pass to another function, they are often excellent.
I found the answer to my question in this very informative article. Firstly, it turns out that I was right about named functions being more desirable, but the solution is not as simple as adding identifiers to all anonymous functions. The main reason for this is JScript implementing function expressions in a very broken way.
Secondly, there is a distinction between function statements and expressions. An anonymous function is just a function expression with the identifier omitted, and adding an identifier (naming it) wouldn't make it a statement (except in JScript, which is why it's broken). This means that all of the other answers were off mark.
But for me anonymous functions are more readable in the source code, because I am sure they are only used there.
Anonymous functions are very convenient. A better fix to this problem, instead of naming the functions, would be if firebug told you on which line in which file the anonymous function was created.
init()
anonymous() // application.js, line 54
anonymous() // foo.js, line 2
And the stack trace is the only place where anonymous functions are a problem imo.

Categories

Resources