Comments (90)
Obviously there's some hostility here. Frankly I think it's ridiculous. I don't understand why you won't add the functionality back in. Since there's such hostility, it should be an option, not a default. However, you are violating this very description of coffeescript (via CoffeeScript.org):
The golden rule of CoffeeScript is: "It's just JavaScript". The code compiles one-to-one into the equivalent JS, and there is no interpretation at runtime. You can use any existing JavaScript library seamlessly from CoffeeScript (and vice-versa).
Well, it's not "just JavaScript". There's something I can do in plain JS (NFE) that I can't do with coffeescript because its creators are too strongly opinionated against it. Either implement it as a non-standard option, or change the description on coffeescript.org.
from coffeescript.
|=._
| \
| |
>>>--|-----(-(arg)>
| |
| /
|=*''
sorry :D
from coffeescript.
Let's be pleasant, folks.
from coffeescript.
If you really care, add a displayName property to your functions after defining them.
Do you really think that manually adding displayName property to all functions is a very good idea?
Really, I'm working with server-side javascript, so, I cant imagine any reason why some old microsoft's garbage is poisoning it for me now... :)
from coffeescript.
@em:
Node.js and Chrome are using Function.name to build stack trace (see here and here).
Sometimes, it will print my function name instead of unknown source
saving me some seconds of searching... reason enough for me.
For production enviroment with some buggy browsers we can always turn off this feature, of course.
from coffeescript.
What's wrong with
if obj instanceof baseStream && !obj._readableState.ended
obj.on 'end', next
obj.on 'data', data = ->
obj.removeListener('end', next)
obj.removeListener('data', data)
next()
else
next()
from coffeescript.
Reference for named functions in JS:
http://yura.thinkweb2.com/named-function-expressions/
from coffeescript.
Since we're always going to name the function with the same name as the variable, I think we can avoid most of the pitfalls of the above article. It is going to leak memory in Internet Explorer, if you create 100000 named function objects, but that's an affordable price. This is on master now, closing the ticket.
from coffeescript.
There's a problem with functions with the same name as variable
E.g.
x:1
y: {}
y.x: => 3
should either
- throw a compiler error,
- make the function anonymous in this instance
- name the something else
from coffeescript.
I'm not so sure that this is a problem. It seems to behave correctly when I try it. This is now a test case in test/fixtures/execution, that prints all true
.
x: 1
y: {}
y.x: => 3
print(x is 1)
print(typeof(y.x) is 'function')
print(y.x() is 3)
print(y.x.name is 'x')
from coffeescript.
Let me know if you're hitting any errors or unexpected behavior, with a test case, and I'll reopen this ticket.
from coffeescript.
One year later...
I'm wondering why this behavior was changed, so that square = (x) -> x * x
no longer gives the resulting function the name square
(which would be useful for stack traces).
Searching through later issues doesn't give me much. I can't make heads or tails of issue 758 from October; it begins "Now that we have a format for allowing named functions without breaking IE..." What was that referring to?
from coffeescript.
Ah, just found the full explanation in the FAQ here.
from coffeescript.
I'm going to chime back in on this one...
I've read and fully understand the IE issues with named functions. However, I think it's asinine that CoffeeScript explicitly disallows the use of named functions just to support IE. By default, CoffeeScript should not allow for named functions, however, why can't we have an alternative syntax or optional compile-time flag that let's the user determine if they want named functions, not that language.
CoffeeScript has become increasingly popular among NodeJS developers - developers who don't need to support IE - they are writing server-side language. They could leverage so much more if they could name functions... I cite the example of express. If they could access the named function in a routes file, they could "guess" the name of the view (like rails) using arguments.callee.caller.name
... but that's impossible when everything is an anonymous function when compiled.
Bottom line - I understand why it was taken out. It needs to be put back in as a non-default compile option or alternative syntax. You've taken away one of the best features of Javascript :'(
from coffeescript.
I really need this. I didn't realize coffeescript with OK with removing javascript features. I thought it was supposed to be nothing fancy, and I think attempting to remove the responsibility of cross-platform programming is pretty much as fancy as you could get.
from coffeescript.
When was this fixed? Can someone cite a commit?
from coffeescript.
@sethvargo: it hasn't been fixed and never will. There's no need for NFEs or FDs. Your example above is not convincing. arguments.callee
is a poison pill in strict mode, and highly highly discouraged outside of strict mode. Like eval
, it doesn't allow the interpreter to do almost all of its optimisations. If you really care, add a displayName
property to your functions after defining them.
from coffeescript.
Well, aside from debugging and profiling where function names are essential. I use the .name property that v8 puts on all functions for a kind of monkey patching. The problem is not that I can't design an API which uses strings and a hashmap (object), but aside from it looking ugly, the entire codebase at hand is written in js which has named functions, so I now need two alternate interface for patching methods one using strings so coffeescript can work, and another using function names, because coffeescript is not compatible with javascript. Alternatively I can't use coffeescript in the app.
You are making the assumption that a library will never use function.name, but if anything does (like my lib) then it cannot be used by coffeescript, unless it repurposes itself for coffeescript's sake. : \
e.g.
var module = {
foo: function() { /.../ }
, bar: function() { /... }
};
function patch(functionToPatch) {
module[functionToPatch.name] = functionToPatch;
}
patch(function foo() {
// my replacement foo
});
Again, "patch" could be repurposed for coffeescript, the problem is that coffeescript probably shouldn't be requiring js to change for its sake.
Also... the real problem creating the IE issue is the assumption that "a = ->" generates "function a()", instead of an additional syntax for named functions. The idea that a named function is the same as a named variable holding a function, is a false premise of how javascript works.
from coffeescript.
@em: name
is a non-standard property. That's what you get for relying on it being set by your interpreter. You should be assigning an identifying value of your own. Are you also going to rely on iteration order of keys in a for-in loop (another assumption people often make that's not guaranteed, in case you didn't know) and then complain about coffeescript?
edit: regarding debugging, most debuggers actually look at the displayName
property, which you should be setting yourself.
from coffeescript.
The IE bug is not standard either, so what's your point? The .name property is one example of how different environments can do different things for named-functions and anonymous-functions. They're different things. The other example bodes the same, debugging and profiling use function.name to build call stacks.
Honestly, I bet if you asked Brendan Eich why he gave javascript named functions at all and didn't make everything anonymous he'd cite the same point. Sheesh.
from coffeescript.
IIRC, var square = function square(){ ... };
or square = function square() { ... };
should work...the leakage in IE occurs when the reference and the function name are different (var a = function b() { ... }
). The square
variable declaration is still overwritten with the square
function declaration, but, because they are identical, the former should be garbage collected immediately.
Pinging @jdalton; he clarified this point for me some time ago.
from coffeescript.
@em:
named-functions and anonymous-functions. They're different things.
They're really not different things. NFEs and anonymous FEs are identical except NFEs add their name to their body's scope. Other than that, they're supposed to behave exactly the same. FDs are different because they respect odd hoisting rules and they add their names to the containing scope.
The IE bug is not standard either, so what's your point?
That's just a reason for not using the extraneous feature that we're not providing for you. We're not providing it because it's not necessary and, as the IE bug points out, can even be harmful. We also don't provide with
statements or unqualified access to the undefined
global. Sure, some interpreters have errors related to those features, but those are only reasons not to use the features. We don't include the features because they're just not useful.
debugging and profiling use function.name to build call stack
As I said above, they use displayName
first. You should be defining that value if you want better debugging support.
note: in case you aren't familiar with the common acronyms, NFE = named function expression, FE = function expression, FD = function declaration
from coffeescript.
@kitcambridge: you are correct. The IE bug treats NFEs similarly to FDs in that it adds the name to the containing scope instead of just the function body's scope.
from coffeescript.
I was summoned by @kitcambridge to confirm that var square = function square(){ ... };
takes care of the IE memory consumption problem. I used this in my code/projects to handle it.
from coffeescript.
Furthermore, labeling this as "fixed" was quite misleading... I suggested "blatantly ignored due to overzealous opinions"...
from coffeescript.
@sethvargo At the time the issue was closed, named functions existed on master. They were later removed for the reasons detailed above.
from coffeescript.
Well, someone should remove the label... Without reading the entire thread, it's very easy to think this issue has been resolved...
from coffeescript.
@sethvargo: CoffeeScript's golden rule doesn't apply to constructs, but functionality. As I said above, there's no way to put an unqualified reference to the undefined
global or a with
statement (without the god-awful backticks) in your output JS. But that doesn't prevent you from doing anything. It's still a one-to-one (injective) compilation, but it's not onto (surjective). I think you're confusing the injective relationship with a bijective relationship. Being injective but no surjective is not a problem in our case. The functionality of the JS constructs that don't have CS equivalents can be accomplished through combinations of CS constructs.
Also, I'm not sure what hostility people are talking about. I don't see any. If it was directed at me, I didn't mean to come off as hostile.
from coffeescript.
Yeah, I don't see any hostility either. My "Sheesh"? Sorry, it resonated as light-hearted in my head.
from coffeescript.
Well... fortunately, it is one-line fix. I've just replaced if (this.ctor)
condition with if (this.name !== undefined)
in nodes.js
:
code = 'function';
/*if (this.ctor)*/ if (this.name !== undefined) code += ' ' + this.name;
code += '(' + vars.join(', ') + ') {';
and now it works just fine.
from coffeescript.
Chiming in to say I tested every major browser, safari, ff, and chrome. None of them use 'name' or 'displayName' for profiling or console display of function names.
from coffeescript.
@rlidwka Thanks for the mod! I can see functions in my stack traces, now
from coffeescript.
Thanks @rlidwka ! Will implement this in our CS compiler
from coffeescript.
@pke what fork have you implemented this in?
from coffeescript.
@devinrhode2 unfort did not have time, but maybe @milgner can take another look.
from coffeescript.
Small note on this issue, as I understand, @jashkenas will never except FD. In my code, I need recursion, but argument.calle is deprecated https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee
For example, this syntax worked:
function factorial (n) {
return !(n > 1) ? 1 : factorial(n - 1) * n;
}
but:
[1,2,3,4,5].map(function (n) {
return !(n > 1) ? 1 : /* what goes here? */ (n - 1) * n;
});
did not. To get around this arguments.callee was added so you could do
[1,2,3,4,5].map(function (n) {
return !(n > 1) ? 1 : arguments.callee(n - 1) * n;
});
and then for bla bla bla, it is deprecated. ECMAScript 3 resolved these issues by allowing named function expressions. For example:
[1,2,3,4,5].map(function factorial (n) {
return !(n > 1) ? 1 : factorial(n-1)*n;
});
// typeof factorial === 'undefined'
Now, the tricky part:
[1,2,3,4,5].map factorial = (n)->
unless n > 1 then 1 else factorial(n-1) * n
will be translated into:
var factorial;
[1,2,3,4,5].map(factorial = function(n) {
return !(n > 1) ? 1 : factorial(n-1)*n;
});
// typeof factorial === 'function'
But hey, I don't want var leak. So, just do the closure
[1,2,3,4,5].map -> (factorial = (n)->
unless n > 1 then 1 else factorial(n-1) * n
)()
will be:
[1,2,3,4,5].map(function() {
var factorial;
return factorial = function(n) {
return !(n > 1) ? 1 : factorial(n-1)*n;
};
}());
// typeof factorial === 'undefined'
Anyway, no comment on performance.
from coffeescript.
Hey guys. Maybe we can create some version of coffeescript for modern browsers? With named functions, without checks for indexOf in arrays and so on? I realy don't care about IE8 and I think there a lot of devs just like me. Maybe someone knows such fork of coffee? Maybe you know good book or article how I can write such coffee?
Many thanks.
from coffeescript.
This makes me cry (not really, but it's sad).
from coffeescript.
Created fork with named functions https://github.com/redexp/coffee-script
Syntax:
plus(a, b) -> a + b
result:
function plus(a, b) {
return a + b;
};
[1..5].map factorial(n) ->
unless n > 1 then 1 else factorial(n - 1) * n
If named function in the end of code then it will not be returned
test ->
asd() ->
test(function(){
function asd() {};
});
because I want to do like this
test ->
if valid() then save()
valid() ->
save() ->
if save() will be after return then I will not be able to use it
But you can assign it
x = asd() ->
Very important last thing
asd() ->
asd () ->
function asd() {};
asd(function() {});
from coffeescript.
@redexp You don't need new syntax, you can use the current name = ->
, this used to be part of CS.
from coffeescript.
@xixixao actually I need. With name = ->
you first of all declare all functions then you using them. With name() ->
you can use first and in the end of code declare. Also I really don't like when in debugger all functions in Call stack is anonymous.
from coffeescript.
@redexp, I think what @xixixao is saying is thatโฆ
name = ->
could compile toโฆ
function name() {}
orโฆ
var name = function name() {};
depending on whether you want to support hoisting. It should be possible to have the compiler output your desired JavaScript without new CoffeeScript syntax.
from coffeescript.
@davidchambers sorry, can you show example when name = ->
will be compiled to function name(){}
from coffeescript.
@redexp: I think the argument is that in your fork you could choose to retain the existing syntax on the CoffeeScript side (name = ->
) and merely modify the compilation to translate name = ->
into function name()
.
from coffeescript.
@mklement0 @xixixao it will looks weird. New syntax is like notice which shows that here is something unusual and regular compiler is not enough
One more thing. I need named function to make things like this https://leanpub.com/javascript-allonge/read#leanpub-auto-modules
from coffeescript.
@redexp This is how it used to compile before the IE bug was discovered (as jashkenas notes above). In CoffeeScript you cannot use stuff before defining it, so this would be valid:
DrawModule = do ->
# public methods
drawLine = (screen, leftPoint, rightPoint) -> ...
# private helpers
bitBlt = (screen, ...) -> ...
drawLine: drawLine
But you can simply use static classes as modules and keep the desired order:
class DrawModule
# public methods
@drawLine = (screen, leftPoint, rightPoint) -> ...
# private helpers
bitBlt = (screen, ...) -> ...
I said before that not being able to define functions after using them is my biggest CS regret, but I tend to use classes much more these days because they make me think about splitting up my code (and if I was writing something purely functional, I'd use the above pattern).
from coffeescript.
Ok, so I hate to revive this extremely old thread, but after reading through all of the other threads listed in the FAQ under this issue, I wanted to get some things clear considering there are a lot of sources of information and these appears to be more or less the place people go to look for this issue.
And again, I apologize in advance @michaelficarra.
-
Is this or is this not fixed in redux? michaelficarra/CoffeeScriptRedux#131 ended with a revert, but this issue is labeled as
fixed-in-redux
-
If the answer to number 1 is "yes", will it be merged into CS proper?
If the answer to number 1 and number 2 was "yes", feel free to ignore the rest of these questions.
-
Is the only reasoning behind not doing this because of the IE <= 8 bug?
-
If the answer to number 3 is "yes" then, at what point can we safely add it back? IE <= 8 is less than 6.5% as of last month.
-
If it isn't added back as a default, given that even @jashkenas said that it was a 2 line change is there a chance this will become a compiler option?
Thanks all.
from coffeescript.
@jfelchner: The PR for CoffeeScriptRedux was ready to be merged and safe for old IEs. But I closed it because there was a lot of fear-mongering and I didn't want to jeopardise the community's trust in my compiler. We can solve this by using the strategy in the linked PR, but we probably won't revisit this for a while. Also, for the foreseeable future, the officially-endorsed compiler will compile to IE6+ compatible JS. CSR was designed so that it may be extended to use additional compilation targets (e.g. ES6); see slides 42-43 of https://speakerdeck.com/michaelficarra/an-analysis-of-the-redesign-of-the-coffeescript-compiler for an example.
from coffeescript.
@michaelficarra Is there an easy way for me to grab the PR you mention? Lack of hoisted functions is the only genuine issue I have with coffeescript. No point in opening another issue about it from what I've read here so I figure I'll just have to maintain a patch for my own use.
from coffeescript.
That diff will not apply to this project. You can apply the same concepts from the linked PR to this project, though I can't guarantee it will be a simple 8-line diff as it was in CSR.
from coffeescript.
Named functions would be really helpful for constructor functions. The objects you construct can easily have their constructor bound to them, so you can do isType Constructor, instance
, but there's no way to get a string of the name, so you can't implement a function that does isType "Constructor", instance
. This is a fairly serious issue for me personally right now. A new assignment operator is an option.
square =: (x) -> x * x
from coffeescript.
ES6 now specifies that var func = function(){};
creates a named function, which should ultimately put this issue to rest. @carlsmith if you really need named functions, dig back through the commit log, @michaelficarra added the feature on some thread I was on but then reverted it, so iirc it is somewhere in the commit log of coffeescriptredux
from coffeescript.
@devinrhode2 - I didn't know that. Do you have a link? It'd be nice to know if this going to be applied to all JS code, or only the code in ES6 classes and modules. If JS engines are going to make lambda assignments name the function, that would solve the problem in some cases. Will a.b = ->
name the function b
?
Hacking the compiler isn't really an option for me. The app lets the user enter CoffeeScript, so a fork would need to be maintained with docs and everything. It just makes sense to stick to the de facto standard.
from coffeescript.
@devinrhode2 - I didn't know that. Do you have a link?
http://wiki.ecmascript.org/doku.php?id=harmony:function_name_property
As far as i understand, JS engines would apply the new function naming semantics to all JS code, not just ES6 classes/methods.
IDK if this proposal has been formalized in the ECMAScript spec though.
Will
a.b = ->
name the functionb
?
Yes! ๐บ
from coffeescript.
@epidemian - Thanks man. Looks good.
from coffeescript.
I know this is closed, but just in case I missed anything in subsequent releases, the capability to transpile named functions by reference name would be great, esp in node contexts, and in many web browsers. Daft general example, already well understood. From this
methodLogger =
log: (method) ->
console.log method.name
A = ->
methodLogger.log A # "A"
to this
var A, methodLogger;
methodLogger = {
log: function(method) {
return console.log(method.name);
}
};
function A () {};
methodLogger.log(A); // "A"
from this at present
var A, methodLogger;
methodLogger = {
log: function(method) {
return console.log(method.name);
}
};
A = function() {};
methodLogger.log(A); // "undefined"
really would be useful in many situations IMO e.g. custom error logging, bindings, application contexts, ... Perhaps a compiler option? Obviously not all deployment environments will support Function#name properties yet, but in certain deployment specific environments e.g. WebKit based apps outside of the browser context... Thats borderline everyday as far as I can see... my tuppence. Out of here!
from coffeescript.
This is an awful idea, on a already closed topic, but why not:
-(test)>
# do something
from coffeescript.
Just got a notification that this is still being discussed and not available in CS.
Happily unsubscribing now because I have moved on to ES6 some time ago anyway.
from coffeescript.
pls at least change the label from fixed
to wontfix
from coffeescript.
If ES6 will fix it for us, then it's essentially fixed. Just have to be patient.
http://wiki.ecmascript.org/doku.php?id=harmony:function_name_property
from coffeescript.
I really need named functions instead of anonymous functions assigned to variables!
When stupid-ass support for IE 6 will be dropped??
from coffeescript.
@avalanche1 what use-case do you have that demands named functions?
IE6 is being dropped in the 2
branch, though there is currently no plans to compile to named functions as modern environments can determine function names from the assigned variable.
var foo, bar
(foo = function () {}).name // 'foo'
(bar = () => {}).name // 'bar'
from coffeescript.
I need this for:
1)'name' property of a function
According to https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name only latest Chrome supports names for anonymous functions:
2) function hoisting. I DO like to code like:
doStuff()
doOtherStuff()
doStuff = ->stuff
doOtherStuff = ->other stuff
(pls dont tell me it's 'bad', cause I like to have freedom of choice, you know - if I want to code in a 'bad' way - that's my choice)
from coffeescript.
- function hoisting. I DO like to code like:
The problem with that is that the assignment operator means two completely different things depending on whether the assigned value is a (literal) function or some other value. Personally, i dislike that sort of complexity on language constructs. If named functions where to be added, they should use some other syntactical form than the existing assignment.
from coffeescript.
@avalanche1 cool, thanks for the references. I didn't realised anonymous function names were only available in V8.
Even if we started using named functions, which we could feasibly do in 2
, I don't think hoisting would change, since that would make a function assignment different from any other assignment, e.g. we would probably compile:
doStuff = ->
doStuffWithThis = =>
into
var doStuff, doStuffWithThis
doStuff = function doStuff () {}
// ruh roh, bound function syntax doesn't allow for a name
doStuffWithThis = () => {}
SO I'm not sure the status of this issue should change, carlsmith
's comment above still stands - we can't reliable add names to all functions, so we just have to wait for JS engines to catch up with the spec.
Discussions of a "named function declaration" syntax have ranged back and forth over the years, but those discussions are independent of IE6.
from coffeescript.
Wait a second.... just noticed that CoffeeScript in fact does support named functions currently. It's just not pretty. But if you need it, it's there. The secret is how coffeescript implements classes:
class namedFunction then constructor: ->
doSomething()
compiles to:
var namedFunction;
namedFunction = (function() {
function namedFunction() {
doSomething();
}
return namedFunction;
})();
making namedFunction
a named function. Yay!
Or, you can just use Javascript interpolation
`function test(){`; do -> # the `do ->` part is optional, but it allows for indentation, making your code a bit clearer
doSomething()
`}`
from coffeescript.
Sadly, that pollutes the global namespace.
huh? how so?
from coffeescript.
@vendethiel that better?
No. I don't see any difference.
which returns the named function & doesn't pollute the local namespace:
Sure, but you still need to assign it to something. Which will "pollute" the local namespace much the same way.
Or, you can just use Javascript interpolation
That also "pollutes" the local namespace the same way
from coffeescript.
Sure - but in some cases, you could be passing a named function as an argument - idk. I guess I'll take out the whole part.
from coffeescript.
@jashkenas why reopen?
from coffeescript.
@GeoffreyBooth @lydell @vendethiel โ
Now that IE8 and below aren't relevant anymore, is there a good reason why CoffeeScript 2.0 shouldn't bring back our old-school named-by-default functions everywhere?
edit: To be clear โ I'm not talking about function declarations. I'm talking about all functions being named in addition to assigned, like we used to have, briefly.
from coffeescript.
I'd be concerned about users expecting the same behaviour from bound functions, for which there is no named syntax.
With the rules of the ES spec named functions are basically redundant in CS (where an assignment is needed for the name anyway).
from coffeescript.
I'd be concerned about users expecting the same behaviour from bound functions, for which there is no named syntax.
Huh? That's not true. We can put names on bound functions in exactly the same way as unbound ones:
hello = ->
hello = function hello() {};
hello = =>
hello = (function(_this) {
return function hello() {};
})(this);
from coffeescript.
Fair point. I was thinking of the 2
branch where bound functions are now compiled to ES6 arrow functions
hello = =>
hello = () => {};
from coffeescript.
Oh, of course -- sorry. I forgot about those.
from coffeescript.
@jashkenas what about function hoisting? let's also support that!
@penne12 thanks for ``function test(){; do ->
- didn't know about the `do ->` part ๐
from coffeescript.
@jashkenas We were discussing named classes here in the CS2 reimplementation of classes. Basically the CS2 version of classes will output code like var Foo; Foo = class Foo {
. I was suggesting that if weโre doing this, we should be consistent and do the same for functions.
So yes, I think function declarations like var foo; foo = function foo () {
would be great. Even if we canโt do it in all circumstances, we might as well do it where we can to make debugging easier. Iโm not worried about the increase in file size, because CS output wasnโt meant to be minified in the first place, and a minifier would make short work of this duplication.
from coffeescript.
what about function hoisting?
@avalanche1 It was clearly pointed out that function declaration (or hoisting) is not a part of this thread. Please create a separate issue where we could have a focused discussion about its necessity and implementation.
from coffeescript.
well, function hoisting without named functions doesnt make sense to me - so I'll wait if named functions are set upon as an agreed solution - then I'll make a sep. request if needs be.
from coffeescript.
Void
WHOA! Super duper kool!
3a.m. and I've just found that named functions DO EXIST in Coffeescript. (Well, sort of named.. ๐ )
And they ARE hoisted to!! (When you declare in the following way:)
foo()
foo = f = ->log arguments.callee.name
// foo
The following works for objects:
obj=
foo: foo = ->log arguments.callee.name
Finally we can drop all the backtick voodoo and other magic. Hurray! ๐บ
I think this can be closed.
But I think the Functions section of the docs should be amended.
from coffeescript.
@avalanche1 That's not coffee script - it's the browser doing it for you, and it has limited support (and is undocumented behavior). This issue still should be worked on to make it work in all browsers.
from coffeescript.
@penne12 , huh?
- Don't spoil all the happiness!
- Care to explain?
R u talking about argumetns.callee
? Well, it doesnt matter if it's being deprecated - functions are hoisted and can be called before being declared - KOOL!
Pllus, I need arguments.callee.name
exclusively for debugging & testing purposes.
from coffeescript.
Oops... sorry bout that ๐จ
Anyways, basically, a named function looks like this:
function namedFunction(){
// this is a namedFunction
}
But, with your example, CoffeeScript generates:
var f, foo;
foo();
foo = f = function() {
return log(arguments.callee.name);
};
Which means that the function isn't named - but some browsers will assume the name based on what they're assigned too, but not always.
In terms of hoisting, CoffeeScript is smart and declares variables the first time they're used, and many browsers will do a "first past" while parsing Javascript to define variables before running the rest of the code (as far as I understand it, maybe someone more familiar with the inner workings of the language could explain better).
from coffeescript.
I see.
Does this feature have a name? I'd like to lookup JS engine compatibility.
from coffeescript.
@avalanche1 Itโs not a feature with a name like you would find in an ES6 compatibility table. I would refer to it as debugging tools inferring anonymous function names from their assigned references. See https://www.bennadel.com/blog/2836-anonymous-functions-assigned-to-references-show-up-well-in-javascript-stack-traces.htm
from coffeescript.
Ahem, after further investigating, it turns out that what I've posted above is actually void.
I was testing aforementionned techniques in Coffeescript Console extension for Chrome;
On the first run it throws en error, on the second, though - it works as described above.
Guess, that's the effect of working till 3AM.
Anyway:
still no function hoisting;
function name inferred from variable assignement works only if JS engine supports it.
from coffeescript.
Here's a simple little script if you want to force names onto functions, but this uses runtime evaluation, and might not be the best choice except in some very specific scenarios.
DO NOT LET THE USER PICK THE FUNCTION'S NAME, OR THEY WILL BE ABLE TO EXECUTE ARBITRARY JAVASCRIPT CODE
nameFunc = (n, func) ->
new Function("func",
"return function #{n}(){return func.invoke(this, Array.prototype.slice.call(arguments))}"
)(func)
Then just:
nameFunc 'namedFunc', (a) -> console.log a
might be somewhat broken, also shouldn't be used for user input.
from coffeescript.
@penne12 , thanks mate!
Thankfully my dev environment supports named functions. And I'll make sure not to use them in production builds.
from coffeescript.
Per #4531, it was decided that CoffeeScript will not be supporting function declarations (outputting function foo()
as opposed to foo = function ()
) or outputting named functions as part of the currently output function expressions (so still foo = function()
, not foo = function foo()
).
from coffeescript.
@GeoffreyBooth I was cleaning up an old coffeescript project and came across arguments.callee
, because coffeescript does not have support for named functions.
if obj instanceof baseStream && !obj._readableState.ended
obj.on('end', next)
obj.on('data', ->
obj.removeListener('end', next)
obj.removeListener('data', arguments.callee)
next()
)
else
next()
In es5 you would do:
if (obj instanceof baseStream && !obj._readableState.ended) {
obj.on('end', next)
obj.on('data', function data() {
obj.removeListener('end', next)
obj.removeListener('data', data)
next()
})
} else
next()
If coffeescript had support for named functions, you could do:
if obj instanceof baseStream && !obj._readableState.ended
obj.on('end', next)
obj.on('data', \data ->
obj.removeListener('end', next)
obj.removeListener('data', data)
next()
)
else
next()
Which is a nicer than:
if obj instanceof baseStream && !obj._readableState.ended
# don't inline event handlers in coffeescript (no support for named functions)
# arguments.callee is deprecated so don't use it to remove event handler
data = ->
obj.removeListener('end', next)
obj.removeListener('data', data)
next()
obj.on('end', next)
obj.on('data', data)
else
next()
The \name
is the anti Lambda Abstractions hehe ;). Joke aside, I don't know how the syntax should be, but \ is an anonymous function in Haskell, so perhaps it could be a named function in coffee.
from coffeescript.
Related Issues (20)
- Unnecessary `splice` ref added for Array destructuring with rest element not in last position HOT 4
- Bug: Re-ordered nested non-end BindingRestElement doesn't get transpiled HOT 1
- CoffeeScript is fantastic, please donโt give it up HOT 1
- How to imitate `let` behavior in loops? HOT 5
- Proposal: Alternative file extension HOT 1
- Bug: Excessive variable and shallow copy for leading or middle rest parameter
- Proposal: Introduce `let` statement. HOT 6
- Proposal: Document Existential Operator Assignment
- Site issue: code blocks twitch on hover HOT 2
- Proposal: cake command should support ES6 modules HOT 2
- Need help understanding class member meanings HOT 1
- CLI `npm` `scripts` and input `.coffee` file/s as last argument conflicting with `--watch` HOT 2
- Bug: wrong code is transpiled for function call without parentheses HOT 2
- Proposal: Add end word to close method or class HOT 2
- Bug: Invalid indentation allowed after `do`
- Bug: Remove checkShebangLine multi arguments check HOT 1
- feature_request(html): backend CoffeeScript compilation inside HTML files HOT 3
- Bug: yield cannot be used in do -> expressions reliably? HOT 5
- [not an issue] An embeddable playground for CoffeeScript HOT 1
- Please help HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. ๐๐๐
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google โค๏ธ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from coffeescript.