satyr / coco

Unfancy CoffeeScript
http://satyr.github.com/coco/
MIT License
497 stars 48 forks source link

Change the auto-return hushing syntax to a literal !-> #189

Open qqueue opened 12 years ago

qqueue commented 12 years ago

Whenever I start out with a hushed function

thing.onclick !-> console.log \clicked

And then want to add a parameter, I usually end up doing this:

thing.onclick (e) !-> console.log \clicked e

Which, unlike (e) -> ...., actually compiles to:

thing.onclick(e(function(){
  console.log('clicked', e);
}));

This is--given how auto-return hushing works--how that code should compile, but I'd much rather it compile to what I expected, and I've been bitten enough times by it to care.

Proposal

Let the literal !-> define a function without auto-return:

<arglist> !-> <fn body>

In the same way -> defines auto-returned functions.

Why

I think of !-> as analogous to the ruby convention of appending ! to functions that mutate in place, e.g. array.uniq!; !-> defines functions that usually change state, not return values.

But since !-> is really not ->, a hushed function with arguments becomes !(args) ->, which loses most of that distinction.

Using the english form of hushing also reads really strangely:

thing.onclick not -> console.log \click
not function doStuff => do stuff

With a literal !-> marking hushed functions instead, there's no chance of a confusing-looking not being used, nor is there a break in muscle memory when changing -> it.stuff to (thing) -> thing.stuff or !-> it.method! to (thing) !-> thing.method!.

For named functions, the literal function! could be used unambiguously:

function! mutate-stuff a b c
  ...

Furthermore, this change doesn't have to immediately break backwards compatability, since not <fn literal> still would otherwise evaluate to a useless false. The old hushing method could be deprecated while still introducing the new hushing literals.

Other thought is that the literal could instead be !>, but that loses the distinctive arrow look of regular ->.

vendethiel commented 12 years ago

I believe it was made for this kind of case : get-fn! ->.

qqueue commented 12 years ago

What does get-fn! -> signify? I don't see how that effects the proposal.

gkz commented 12 years ago

get-fn returns a function, which is then called with the parameter ->

qqueue commented 11 years ago

I understood that part, but nothing about that effects hushing auto-return.

get-fn! !->

is still unambiguous.

satyr commented 11 years ago

Needs {up,down}-votes.

Other thought is that the literal could instead be !>

That leaves out ~> and <~. See #91.

Avoiding symbol-bikeshed was one of the reasons to choose the current syntax.

qqueue commented 11 years ago

That leaves out ~> and <~. See #91.

True, which is another reason I didn't like !> as much. Promoting !-> to a single token is less of a bike-shed problem, given that it's already in wide use as two symbols.

More succinctly, here are my arguments for a literal !->:

And the full list of changes are:

I'm actually less sure about function!. !function would be more backwards-compatible (if only in how it looks), but function! is more english-like or ruby-like.

vendethiel commented 11 years ago

Not sure about function! as well, but +1 for unified !->

akx commented 11 years ago

:+1: for unified !-> and why not function! too. Don't see anything wrong with that.

vendethiel commented 11 years ago

!-> would put ! just before the actual function syntax (->). !function already works that way.

gkz commented 11 years ago

I support this, though I feel it should be !function rather than function!

vendethiel commented 10 years ago

gkz/LiveScript@79e5d7771552131556fab3b7f6b2810a07f4b277