Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
qqueue opened this issue Nov 5, 2012 · 11 comments
Open

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

qqueue opened this issue Nov 5, 2012 · 11 comments

Comments

@qqueue
Copy link

qqueue commented Nov 5, 2012

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
Copy link
Contributor

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

@qqueue
Copy link
Author

qqueue commented Nov 6, 2012

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

@gkz
Copy link

gkz commented Nov 6, 2012

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

@qqueue
Copy link
Author

qqueue commented Nov 6, 2012

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

get-fn! !->

is still unambiguous.

@satyr
Copy link
Owner

satyr commented Nov 7, 2012

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
Copy link
Author

qqueue commented Nov 7, 2012

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.

@vendethiel
Copy link
Contributor

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

@akx
Copy link

akx commented Nov 14, 2012

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

@vendethiel
Copy link
Contributor

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

@gkz
Copy link

gkz commented Dec 29, 2012

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

@vendethiel
Copy link
Contributor

gkz/LiveScript@79e5d77

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants