While if you know the rules, you can drop semicolons in JavaScript, many other syntax things aren't the same. JS doesn't enforce whitespace, doesn't do implicit returns, makes you define a variable with var
or let
, there's neither @var
for this.var
nor ..
for the head and tail, and requires parentheses and brackets everywhere you look. ES6 has a fat arrow but no concept of a thin arrow if you don't want that kind of variable scoping.
I'm not really for or against either technology, but they're still different beasts and require compilation at this juncture for production regardless of CS or ES6. It's a bit naïve to assume that one replaces the other.
The core issue comes from the fact that JS is the only browser scripting language and has one syntax that may not jive with some people's coding style. Take a look at Elm or PureScript for example which are Haskell-like and enforce immutability rather than using it as a convention in the same vein that JS/ES6 can't enforce whitespace the way CoffeeScript does.
I stick to vanilla because it's the one with the strongest vision and proven endurance.
CoffeeScript's biggest strength and biggest weakness is how opinionated the owner is. It keeps the language design clean but sometimes at the cost of cool new stuff. CoffeeScript Redux was actually a Kickstarter to fork the original CS compiler to make certain changes that were rejected. It did decently well for a while but has since (sort of) fizzled out.
Iced CoffeeScript is a much simpler project that only really brings await
and defer
to the table. Useful, but i'm not sure it justifies a fork.
So no, CoffeeScript Redux is a spiritual 2.0, but it will not be the official one.
I HOPE that CS 2.0 is going to bring ES6 features and finally abandons support for Netscape Navigator 2.0 so it doesn't fall behind Vanilla JavaScript. I hope that a lot of the features in these forks come into the next major version of CoffeeScript, but I've yet to see evidence that they will.
Hi, I am the author of the JS2Coffee utility. This is a one-to-one copy of your snippet.
DragDrop = DragDrop or {}
DragDrop.setup = -> dropContainer = document.getElementById('drop_zone') dropContainer.addEventListener 'dragover', (event) -> event.stopPropagation() event.preventDefault() , false dropContainer.addEventListener 'drop', DragDrop.handleDrop, false
DragDrop.handleDrop = (event) -> dt = event.dataTransfer files = dt.files count = files.length event.stopPropagation() event.preventDefault() alert 'File dropped!'
window.addEventListener 'load', DragDrop.setup, false
User MustRapeDeannaTroi has made some nice changes to implement your example more idiomatically, have a look at his comment.
looks great! bear in mind that you might be able to make this really useful in nodejs as well, which is something I can certainly see use for :).
Cakefiles are a useful way to keep things built. I have a repo here: https://github.com/benhowes/coffee-less-cake-starter that has an example of a cake file. This one will also compile Less to css, but you can probably strip that out (unless you're using less).
> How to create an anonymous function and execute it?
do (arg1, arg2) -> console.log arg1 + arg2
compiles to
(function(arg1, arg2) { return console.log(arg1 + arg2); })(arg1, arg2);
If you want to chain them together, you have to wrap arguments with ()
Try Coffeescript here. The js2coffee compiler seems flawed, to me, compared to the official site.
Definitely opt for the first version. Using the do
keyword, in my opinion, is more applicable when you are building a list of functions inside a for loop as it will construct and invoke a function with the proper arguments and closure.
See http://jsfiddle.net/hrw6qft9/ for an applicable example and usage of the do
keyword.
Most indentation-structured languages actually do have formal written rules. Python, at least has a very trivial ruleset, because there's only one construct -- the "suite" that allows an INDENT/DEDENT pair, and suites are always begun with a :
on the previous line. Python's tokenizer also doesn't issue INDENT/DEDENT pairs for lines inside of an open pair of brackets, parentheses, or braces.
CoffeeScript's grammar, on the other hand, is a bit more complex, as there are more places where something can be between an INDENT and an OUTDENT, and they can occur inside of open parentheses, brackets, or braces.
Anyway, the grammar is where all the written formal definition takes place, specifically the "Grammatical Rules" section. Search for each place an INDENT or OUTDENT appears, to see all the places where you can indent something. A lot of things take a Block
, which is the main indented structure, but there are a bunch of other places where INDENT and OUTDENT are allowed.
>Although suppressed within this documentation for clarity, all CoffeeScript output (except in files with import
or export
statements) is wrapped in an anonymous function: (function(){ … })();
. This safety wrapper, combined with the automatic generation of the var
keyword, make it exceedingly difficult to pollute the global namespace by accident. (The safety wrapper can be disabled with the bare
option, and is unnecessary and automatically disabled when using modules.)
Interesting, shame the site it's hosted on makes it such a chore to read it. Here's the pdf file or if you want it online, try google docs viewer.
I think you mean not written in coffeescript. Second this though.
Another similar function that's good to know is debounce. It will wait until some duration has passed since the function was last called, before calling the given function once. In the past I have used it for a search box that auto-searches; the onkeypress handler should be a debounce wrapper around the search function, with a time of maybe 1 or 2 seconds. That way it won't perform a search for every letter the user types, but only when the user pauses for that duration.
So if nikesoccer01 wants to wait til the user stops moving the mouse or til they pause for a moment, then they would use debounce.
Also sidenote for both of you; lodash is said to be better than underscore for various reasons but otherwise they have a pretty identical feature set and are almost fully compatible with each other. I don't know enough to be able to defend one or the other but I reach for lodash in my new projects.
Thanks for the pointers.
I took a look at Python's language reference. Its Lexical Analysis section has subsections called "Explicit Line Joining" and "Implicit Line Joining", which describe the situations in which indentation is ignored and an INDENT/DEDENT pair is not emitted.
For Coffeescript, this information seems to be provided here, I suppose? It seems to say that the newline+indentation will be ignored when either:
I must admit I can't read the LINE_CONTINUER regex; specifically:
(?![.\d])
I've come up with this solution so far, using the coffee-script browser compiler.
<!DOCTYPE html> <html> <head> <title> Tests </title> <link rel="stylesheet" href="../../node_modules/mocha/mocha.css" /> </head> <body> <div id="mocha"></div> <script src="coffeescript.js"></script> <script src="../../node_modules/mocha/mocha.js"></script> <script src="../../node_modules/should/should.js"></script> <script>mocha.ui('bdd');</script> <script> CoffeeScript.load("./myTests.coffee", function(){ if (window.mochaPhantomJS) { mochaPhantomJS.run(); } else { mocha.run(); } }, { bare: true }); </script> </body> </html>
Still interested to see if you guys know anything better/easier.
Look at the options you can provide to the <code>coffee</code> command. There is a --join
option that will concatenate files together and then output them. Is this not what you're looking for?
It just takes some time to get used to it I suppose, but it can of course be used in real world applications. Here's a mini jQuery in a few lines using those helpers and techniques:
toArray = builtin Array::slice query = curry (el, sel) -> toArray el.querySelectorAll sel
$ = query document $.map = compose compact, unique, flatten, map
parent = pluck 'parentNode' parents = pluckR 'parentNode' children = compose toArray, pluck 'children' nextAll = pluckR 'nextElementSibling' prevAll = pluckR 'previousElementSibling' siblings = concatF prevAll, nextAll
tag = pluck 'tagName' text = pluck 'textContent' html = pluck 'innerHTML'
$.map children, $ 'ul' #=> [li, li, li] $.map parents, $ 'li' #=> [ul, body, html, document] filter compose(isF('UL'), tag), $.map parents, $ 'li' #=> [ul] $.map text, $ 'li' #=> ['A', 'B', 'C'] first $.map compose(trim, html), $ 'ul' #=> '<li>A</li>\n<li>B</li>\n<li>C</li>'
Here's a demo: http://jsbin.com/wokeb/1/edit
The beauty of this approach is that you can keep making functions by currying or partially applying other functions, so you get an increase in code re-use while getting more specific in your abstractions. You start very generic, and end up composing functions out of very simple blocks, it's like Legos.