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
Allow calling functions with a bang! #2289
Conversation
This commit adds a little loophole into the rewriter to allow syntax like: class Foo bar: -> "Bang!" faz = new Foo! faz.bar! # Bang! I think it makes extending into objects when you need to use functions a lot cleaner: Number.prototype.seconds = -> this * 1000 4.seconds! # 4000 Perhaps it's a case of parens-itis. Or perhaps it's awesome! I think it'll end up making quick little calls to methods a little less painful. One character less. This was originally inspired by @joshuaclayton's tweet: https://twitter.com/#!/joshuaclayton/statuses/190496586533576705
Totally love it! |
That's pretty handy, definitely +1 |
See #514, particular's Jeremy's comment when closing it: #514 (comment) |
Hmm. More ruby-like, but imo makes less sense. Might be a point of confusion when people come to coffeescript and wonder why they cant just call In that case Embrace the parens, just like you did significant indentation levels. |
or allow calling methods with : faz.bang:trollface: :-D |
It seems like no code was produced out of that discussion, hopefully this might be a little more valuable given it works, and all of the tests are passing. I think the "this character means something different in Ruby" argument is a bad one. The existential operator has wildly different semantics in CoffeeScript than the convention Ruby lays down for methods ending with |
👎 |
In all seriousness, I think this is a great patch. When I started coding coffeescript (about two weeks ago!) I thought it was super lame I still had to use I also think it looks a lot cleaner when chaining: foo.bar().baz()
foo.bar!.baz! IMO, |
also, could it be possible to do: foo.bar!baz! or is that too confusing? |
@ngauthier it doesn't allow chaining right now. I don't think it should. |
awesome! (Or should that be: awesome()?) +1 |
The context of ! is no where near as clear as () is. ! in a lot of cases means that state will be mutated, or in the case of ActiveRecord in rails, something entirely different. Adding ! here further muddies the water. The common thing in all cases is that ! means that this method will do something that you might not expect, be careful. -1 |
I'm not a fan either. It further deviates CS from it's golden rule of "It's just JavaScript". ☔ Pulling in @rkneufeld |
For me, ! means "in place value modification", not "no args" |
Huge -1. In ruby, it is used for a certain purpose, to warn that the method is either going to mutate the object or that something else that's special will take place and to be careful. You want it here just so you can avoid using Let's not forget the reason we need parens, because functions are properties like anything else except they also have the ability to be invoked. So @ngauthier it's not lame that we have to use parens because it's common that we actually want to refer to the function without invoking it (passing it as an argument, for example). In my opinion the parens are necessary and desired because the lack of parens means "treat this as a property" whereas the use of parens means "invoke this property". However, I am totally for using the trollface in place of parens. |
I dont want to make the argument that it should act like ruby in all cases (since, yes, it does differ in many cases). But i dont want to change syntax for the sake of developer laziness when it adds potential to confuse, muddle clarity, or decrease consistency. Thanks to @TrevorBurnham for posting the two-year old attempt at this, which was closed as wontfix. I agree with the arguments made in that closing comment. |
The coffeescript equivalent of warning that a function is being used for its side effects (signalling mutation) is |
👍 This seems a lot cleaner to me |
-1 I think it introduces a lot of confusion. I spent 20 seconds figuring out what is this about. And it's useless. By the way, bad example:
|
This is interesting, for sure. Not that having to type parentheses is really that "painful", I mean saving one character isn't that big of a deal for me. But aesthetically it has a certain feeling which is kind of... well, interesting. There are other things to consider though, obviously -- readability and consistency. If you didn't know anything about CoffeeScript could you guess what this means?
And how would you know that this would not be valid (or would it?):
And this is going to be a sticking point with people, I suspect. So I'm -1 for now.... but I'd be curious to see this in a real CoffeeScript file. |
That would be valid, just like I like this, in fact I use this a lot in coco, although it's not that much of a bonus either. +0.1? |
|
||
test "bang calling a function", -> | ||
class Foo | ||
bar: -> 3 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The evil TDD me keeps thinking this means that bar!
only returns a 3
. :-)
My initial reaction was +1 to this, but after reading the comments I am a bit worried that it could cause confusion. This mimics behavior in Ruby, but not fully. The examples quoted above as In the end, I think I'm now +0. I'd like to see it changed around a bit to allow function to execute automatically a la Ruby, but that can't happen without some serious issues, so... :-/ |
@renekooi:
Well, the reason I asked is, just as these are equivalent
would these be equivalent
or would it throw a syntax error if the grammar rule is simply that if a bang comes after a word it gets converted to parentheses, a la...?
|
@mcmire, I'd say
|
@tswicegood how does this mimic the intended behavior of ruby? It may at first glance look like ruby, but it does not mimic how these are supposed to be used in ruby and also, as previously stated, in CS |
I'm not feeling this. It adds confusion (two ways to do the same thing, which should I use?), loses consistency with other languages (ruby's change in place convention, javascript's not) all to save a single character. What's the point? |
@benjreinhart Thanks for the correction -- that's what I intended. It mimics it in that it looks the same, but the actual result is different. I think that's a bad thing. |
Yet another Coco-fication (or MoonScript):
I don't think Jeremy likes this one though. |
My intention for this was to only use the The ideas were along the lines of: class User
constructor: (firstName, lastName) ->
@firstName = firstName
@lastName = lastName
fullName: ->
[@firstName, @lastName].join " "
sayHi: ->
name = arguments[0] || @fullName!
alert "Hi! I'm #{name}."
josh = new User("Josh", "Clayton")
josh.fullName! #=> "Josh Clayton"
josh.sayHi! #=> alerts "Hi! I'm Josh Clayton."
josh.sayHi "John Doe" #=> alerts "Hi! I'm John Doe." |
If the proposal is simple to replace "()" with "!", then I think the drawbacks far outweigh the benefits. It wouldn't cure the fact that Ruby folks are inclined to omit parens, because they're used to Ruby's very different object model, and the "!" would have different semantics than Ruby, leading to even more confusion. Not to mention the fact that there's a ton of existing code that uses "()" for no-arg calls. I've been back in Python land for a while, and I have to say that paren-free syntax is a highly overrated feature of both CS and Ruby. Actually, there are a couple features of Ruby that you don't miss at all when back in Python. Not that Python is perfect by any stretch. I would love it if Python adopted CS's syntax for functions. |
-1 |
Great -- seems like there's a clear majority opinion on this one. Closing for the same reasons as previously. |
the "!" actually should modify the object that is calling it, not just by "converting" the # like doing t = t.toFixed(2)
if t.toFixed!(2)
t += 0.2
# or a one liner array convertor (like a filter)
i.toFixed!(2) for i in [2,3,4,5,6]
###
would be
var i, _i, _len, _ref;
_ref = [2, 3, 4, 5, 6];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
i = _ref[_i];
_ref[_i] = i.toFixed(2);
}
now all the numbers in _ref would be x.00
###
# even though it's the same as doing
arr = [2,3,4,5,6]
arr[key] = value.toFixed(2) for key,value of arr |
@pocesar: I don't think we should add sugar for |
@davidchambers the problem is that, if it's done inside the parenthesis, it returns an array. the ! would make it differ and return the original object, like this funct(value.toFixed(2) for key,value of {"1":1,"2":2,"3":3,"4":4,"5":5}) # passes an array to the funct, the object is lost it would work like this obj = {"1":1,"2":2,"3":3,"4":4,"5":5};
obj[key] = value.toFixed(2) for key,value of obj
funct(obj) 3 lines, what could be just one, since coffeescript is all about shortands and sugar. funct(value.toFixed!(2) for value of obj) #rewrites the obj[key] automatically and passes the obj instead of an array, all because of the ! |
This commit adds a little loophole into the rewriter to allow syntax like:
I think it makes extending into objects when you need to use functions a
lot cleaner:
Perhaps it's a case of parens-itis. Or perhaps it's awesome! I
think it'll end up making quick little calls to methods a little less
painful. One character less.
This was originally inspired by @joshuaclayton's tweet:
https://twitter.com/#!/joshuaclayton/statuses/190496586533576705