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

a +"b" compiles to a(+"b") #1036

Closed
STRd6 opened this issue Jan 11, 2011 · 14 comments
Closed

a +"b" compiles to a(+"b") #1036

STRd6 opened this issue Jan 11, 2011 · 14 comments

Comments

@STRd6
Copy link
Contributor

STRd6 commented Jan 11, 2011

It may be my expectations that are to blame, but I would expect this to compile to:

a + "b"

or something equivalent. The prefix + operator and function call are surprising.

@TrevorBurnham
Copy link
Collaborator

This behavior definitely feels weird coming from most languages (in Scala, for instance, I believe the preferred String concatenation style is a +"b"+ c), but +"b" in JavaScript is actually a valid way of saying "Evaluate "b" as a number." Check it out:

$> +"b"
NaN
$> +"1000"
1000
$> +"0.5"
0.5

Again, that's just JavaScript—CoffeeScript simply keeps the behavior the same. So given that +"0.5" is a number, and a 0.5 means a(0.5), I hope you can see why a +"0.5" being a(+"0.5") is actually pretty natural (though not especially useful).

Of course, you're probably aware that the preferred string concatenation style in CoffeeScript, as in Ruby, is

"#{a}b"   # a + "b"

@satyr
Copy link
Collaborator

satyr commented Jan 12, 2011

a + "b" is invalid JavaScript if a is anything other than a string

Nope?

@STRd6
Copy link
Contributor Author

STRd6 commented Jan 12, 2011

Hi Trevor, thanks for the response.

I'm aware of the unary + operator, but in plain JS it's not space sensitive.

a = "foo"
a +"b" // => "foob"

Though a workaround in CoffeeScript is to write it thusly:

a + "b"

Or

a+"b"

As for the string interpolation, I definitely prefer to use that where possible, but I primarily use CoffeeScript from filters within my Rails application so the Ruby interpolation overrides it.

@TrevorBurnham
Copy link
Collaborator

@satyr Sorry, that last part was posted by mistake. Corrected.

Bummer about the filters, STRd6. That didn't occur to me when we were debating the string interpolation syntax. Maybe %{...} would've been better after all.

Of course, another syntactic option would be for you to write a function:

interp = (args...) -> args.join ''
interp a, "b"   # equivalent to a + "b"

@gchlodzinski
Copy link

I posted a new similar report but I've noticed that similar one is already reported.

I am using coffeescript for a large javascript project since August. We ended up using 0.9.4 for some time. Today I did some verifications if we can safely upgrade do 1.0 and I this is the first issue that I discovered (and it was compiling properly under 0.9.4):
a=b +c compiles into a = b(+c)
Of course a=b+c or a=b + c works well.

I am not sure if consider this as a bug (there are reasons when space character is treated as start of function call) but IMO coffeescript compiler should detect expressions as an exception and it was doing so in 0.9.4.

@satyr
Copy link
Collaborator

satyr commented Jan 12, 2011

$ irb
>> p +1
1
=> 1
>> p + 1
NoMethodError: undefined method `+' for nil:NilClass

@gchlodzinski
Copy link

@satyr. I am not sure if I understood your point (having great respect for your contribution to coffeescript) but my point is that:
irb(main):009:0> p=1
=> 1
irb(main):010:0> p +1
=> 2

but in 1.0 coffeescript:
p +1 will compile into p(+1)
which IMO is wrong.

edit: I got it now - I keep forgetting about p as a puts shortcut.

@satyr
Copy link
Collaborator

satyr commented Jan 13, 2011

p=1

Unlike JS, Ruby has separate namespaces for methods and variables.

p as a puts shortcut

http://www.ruby-doc.org/core/classes/Kernel.html#M001409

@jashkenas
Copy link
Owner

I'm afraid that the current behavior is the correct fix. With +, as you demonstrate, it's a bit unintuitive, but with -, it's totally necessary. For example:

squareRootOf -1

In CoffeeScript, the above must parse as squareRootOf(-1) and not as squareRootOf - 1, for any of the implicit function calls to make any sense.

@TrevorBurnham
Copy link
Collaborator

Since folks are still talking about this, here's a concrete example of why this is useful:

roundedNum = Math.floor +getUserInput()

It wouldn't feel very CoffeeScript-y to require parentheses there, now would it?

@satyr
Copy link
Collaborator

satyr commented Jan 18, 2011

a concrete example

Except that the + is redundant (Math.floor implies ToNumber).

@TrevorBurnham
Copy link
Collaborator

Well, OK, good point:

roundedNumPlusOne = Math.floor +getUserInput() + 1

@odf
Copy link

odf commented Jan 26, 2011

Is this mentioned in the documentation yet? I think Coffee's behaviour is perfectly sensible here, but very surprising if one's not used to it. Unlike the block structure via indentation thing, which even after years of Python programming I'm still not too happy about, this is actually a use of significant white space that I can get behind. In fact, a+b, a+ b and a + b all compile to a + b. Only a +b, the one with the + clearly associated to the second term, is compiled to a(+b).

@TrevorBurnham
Copy link
Collaborator

Added to the FAQ under Grammar.

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

No branches or pull requests

6 participants