coco icon indicating copy to clipboard operation
coco copied to clipboard

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

Open qqueue opened this issue 13 years ago • 11 comments

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 ->.

qqueue avatar Nov 05 '12 23:11 qqueue

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

vendethiel avatar Nov 06 '12 00:11 vendethiel

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

qqueue avatar Nov 06 '12 00:11 qqueue

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

gkz avatar Nov 06 '12 09:11 gkz

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

get-fn! !->

is still unambiguous.

qqueue avatar Nov 06 '12 23:11 qqueue

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.

satyr avatar Nov 07 '12 00:11 satyr

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 !->:

  • !-> already looks like a standalone symbol and it's used plenty of places in the coco source--as well as my own projects.
  • unlike @prop or &method, !-> is entirely made up of special symbols, so it's harder to recognize that it is, in fact, two symbols (as a comparison, haskell makes all-symbol identifiers auto-inflix).
  • Adding arguments to a hushed function doesn't feel the same as a non-hushed function, since the optional arglist is actually squeezed between the ! and the -> instead of in a space, e.g. fn = -> it => fn = (arg) -> arg.
  • Having ! <fn literal> hush the auto-return is a clever way to make compilation simple, but given that nobody really uses the english not form, I think it's clear that human coders aren't thinking not ->, they're thinking !->. See also: not function and <- not expression.
  • Recognizing !-> as a standalone literal is backwards compatible, and given its widespread usage (as two symbols), much of the code that has hushed functions wouldn't be deprecated either.

And the full list of changes are:

  • !-> <body>: hushed function symbol.
  • !~> <body>: hushed bound-this symbol.
  • <-! <expression>: hushed backcall symbol.
  • function! <args> => <body>: hushed function literal.

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.

qqueue avatar Nov 07 '12 02:11 qqueue

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

vendethiel avatar Nov 10 '12 19:11 vendethiel

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

akx avatar Nov 14 '12 12:11 akx

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

vendethiel avatar Nov 14 '12 12:11 vendethiel

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

gkz avatar Dec 29 '12 23:12 gkz

gkz/LiveScript@79e5d7771552131556fab3b7f6b2810a07f4b277

vendethiel avatar Dec 19 '13 13:12 vendethiel