Closed jussiry closed 10 years ago
What compilation would you recommend for a b c .d()
? Should it be a(b(c)).d()
or a(b(c).d())
? Should a .b()
then be compiled as a().b()
?
What about this common use case for jQuery? What would the whitespace do here?
$('a')
.button()
.click(load_ajax)
So you're suggesting a function call's argument list ends when it sees a dot-style property access but only when there's whitespace before the dot (which, I'll remind you, is just JS)?
> obj.f0 a0, a1, a2 .f1 b0.b00, b1 .f2 c0
obj.f0(a0, a1, a2).f1(b0.b00, b1).f2 c0
I can kind of see why someone might want to write that the first way (DSLs maybe?), but it is quite a bit more readable with explicit parentheses. -1 for now.
erisdiscord, i think a b c .d()
should compile to a(b(c)).d()
(property after . binds to the first function).
EDIT: now that i think of it, a .b()
should just compile to a.b()
. Like in CoffeeScript in generals, without parenthesis function is executed only when it's given parameter(s).
michaelficarra, yes, but JS is ugly. ;) I agree that the second example is cleaner and I hope that no one writes the code in real life with as many parameters without parenthesis. But the point is not to allow long lists of parameters without parenthesis (as long as there's a clear logic on how they would compile if someone wrote them), but to allow cleaner code in simpler examples.
Interesting. There would be enough visual hint since you don't usually space before .
, and you can still write a b. c
to mean a(b.c)
. Similar to the new "command chain" in Groovy 1.8.
:+1: Increased craziness:
a b c .d()
compiles to
a(b(c).d())
and
a b c .d()
compiles to
a(b(c)).d()
(good luck if you don't like fixed-width fonts :P )
@thejh that's horrifying.
@erisdiscord I'd rather call it "consistent".
Humm... on a related note, what would you think about doing operator precedence using spaces? Something like
1+1 * 4 # 8, not 5
@thejh I call it "pretty difficult to read". I'm not really a fan of the original proposal and I can't see this version bringing any additional value. -1 :C
@thejh, why would it make a difference if there's one or two spaces before dot (.)? As i see it, with this proposal a b c .d()
would also compile to `a(b(c)).d()``.
@thejh, on the operator precedence: i like it. :) Haven't given it that much thought, though.
To return to the jQuery example presented by @erisdiscord:
$('a')
.button()
.click(load_ajax)
Would work just as it now does, but with the new rules you could actually write it without the parenthesis:
$ 'a'
.button()
.click(load_ajax)
Which isn't possible in CoffeeScript at the moment. The only problem would arrive if you would add another function before $:
another_func $ 'a'
.button()
.click(load_ajax)
Because in this case the .button() would be executed on another_func
, but i don't see this being a very common use case.
It gets really unreadable after a few methods. Consider this:
get(words).split(' ').filter((w) -> r.test w).join(', ')
It would be written as
get words .split ' ' .filter (w) -> r.test w .join(', ')
You just borked the function expression. This could be the case for a custom operator, we don't have many options since |
is taken:
get words ..split ' ' ..filter (w) -> r.test w ..join(', ')
$.get '/api' ..success fn ..error fn
// overload then
foo bar then .baz()
get words then .split ' ' then filter (w) -> w then join ', '
// spermatozoid operator
foo bar ~> .baz()
get words ~> split ' ' ~> filter (w) -> w ~> .join ', '
But it doesn't make things much better, besides being a huge departure from "normal" syntax.
One that is kind of ok is re-using @
:
foo bar @ baz()
This would be different from foo bar @baz()
in the same fashion that foo 1 + 2
is not the same as foo 1 +2
. And it would re-use the @
semantics of being this
, in this case this
is the result of the left-hand expression.
For clarity the dot could be kept: get words @.split ' ' @.filter (w) -> w @.join ', '
get words .split ' ' .filter (w) -> /bacon/.test w .join(', ')
You just borked the function expression.
Only because you mixed implicit indentation (inserted after ->
, consuming the rest of the line) which obeys its own, different rules.
One-liner functions must be parenthesized in such cases.
@satyr but that kind of defeats the purpose of not having to nest things in parenthesis.
"Significant whitespace" speaks primarily about significant linebreaks and significant indentation. These are readable. Not all whitespace should be significant. Some types of whitespace should not be significant: such as the whitespace within a line.
Some types of whitespace should not be significant: such as the whitespace within a line.
Already significant beyond help:
$ coffee -bpe 'a? b ? c?'
if (typeof a === "function") {
a(typeof b !== "undefined" && b !== null ? b : typeof c !== "undefined" && c !
== null);
}
$ coffee -bpe 'a[b...] [c...]'
var __slice = Array.prototype.slice;
a.slice(b)(__slice.call(c));
Yeah, we are pretty big on the significant whitespace here. Still, this one's a bit of a stretch. I could live with it, but it's nowhere near as intuitive or readable as our other instances of significant whitespace.
I agree that binding the property after the dot notation to the first function in the command line (or the one after the previous dot notation) allows you to write code that is hard to read. But there's no programming language that can stop people from writing bad code. So i guess my question is this: is there ever a time when someone would write foo bar .baz()
currently in CoffeeScript? Sure, we chain the commands with empty space between, but in that case we always put the next command on the next line. And even when you take the one real world case that would brake with the new notation...
another_func $ 'a'
.button()
.click(load_ajax)
...I actually find it much more logical that .button() would bind to another_func:tion, since this allows us to process the whole function line at once, and only after that move to the next lines. Currently it's slightly backwards since you first have to process $('a') in your head, then .button(), then .click(...) and only then jumping all the way back to another_func.
Yep, CoffeeScript has intra-line significant whitespace. But maybe it's a good idea not to increase the quantity of it, especially by adding an easily confusable and barely debuggable significance of whitespace affecting the order of operations.
Actually, while I am not too keen on a b .c()
becoming a(b).c()
, I do like the cut of that multi-line jib.
$ 'a.popup'
.button()
.click -> popup this.href
Is it reasonable for a newline to close the outermost implicit parentheses in this case?
This came up on Stack Overflow recently. It would mean that you could write
js = require 'coffee-script' .compile coffee
which is pretty nice. And people have long been begging for
$ '#sprite'
.html str
.css left: x, top: y
.bind 'click', clickHandler
to be supported somehow. The main counterargument Jeremy and others have expressed toward such proposals is that they overload indentation with multiple meanings. This proposal, on the other hand, makes the indentation non-significant, the same way that
a +
b
is a perfectly acceptable way of writing a + b
. I find that to be consistent and beautiful.
Let's remember that "it allows ugly code" isn't a compelling argument against a language feature—ugly code will always be possible. The question is, rather, "Does it encourage ugly code?" And this proposal, in my view, does the opposite, allowing more stylistically consistent code to be written. An enthusiastic +1 from me.
I would really, really like this to happen. There isn't a great reason to write foo bar .baz
if you mean foo bar.baz
, but there are a lot of reasons to write jQuery- or connect-style method chains. CoffeeScript already promotes aesthetic structure as defining behavior; this just makes the structure more beautiful and more expressive.
I wanted to propose why this issue is more in line with CoffeeScript's philsophy by preserving significant whitespace. Right now, CoffeeScript is less ambiguous in one way because it converts
brush
.startPath 'red'
.moveTo 10, 10
into
brush.startPath 'red'.moveTo 10, 10
where the .
operator responds to the trailing argument in the previous line. Yet when reading this code, it is ambiguous to which object we are referring. CoffeeScript will currently let you can nest method calls for different objects in the same indentation level (brush
vs the string 'red'
), which seems unintuitive. Indentation, or nesting level, should really imply statements are in the context of the most recent line of a lesser indentation level. Reading it in this way, each method call refers to brush
.
Depending on how #1495 is resolved, this definition may not extend to nested chaining syntaxes (though parentheses could still be omitted); but one possibility to get the current behavior is to make greater indentation override the implicit parentheses:
brush
.startPath 'red'
.moveTo 10, 10
Compile to brush.startPath 'red'.moveTo 10, 10
as before.
OP @jussiry, +1
I just wanted to add the main Benefit of supporting this feature, is to not have to go backwards into your code, to have to add parenthesis to do something simple.
js:
x('hi')
~> x('hi').y
coffee:
x 'hi'
~> x 'hi' .y
doesn't work >:[
x('hi').y
wth, why can't I write it this way x 'hi' .y
!?!
if I meant x('hi'.y)
I would've written in coffee x 'hi'.y
!!! (no-space after 'hi')
This happens a lot! (having to go backwards just to add parenthesis ... especially in client-side jQuery code and other libraries that does chaining... it's really annoying to have to go backwards...
And I think yes, white-space is important, actually I think any character in programming is important... every ;
every "
every _
... I believe we as efficient programmers, likes code, with as minimum amount of characters as possible, that's still readable/maintainable.
We account for every character, trying to get rid of as much as possible.
Coffee-Script was made I believe, to make coding JavaScript more joyable and efficent, one of the main benefits is a cleaner syntax, with less ; ( ) { } ...
I think Coffee-Script programmers, translates _
white-space_
after function/method, in their minds to mean (
parenthesis)
...
x y => x(y)
x.y z => x.y(z)
x y .z => x(y).z
@quangv If you hate all the punctuation and stuff and prefer whitespace, you might be interested in this other language. ;D
@erisdiscord why does CoffeeScript translate x 'hi'
into x('hi')
?
Why not just keep the parenthesis?
@quangv I'm going to guess that CoffeeScript's allowance for omitting parentheses, as well as its precedence rules in terms of missing parentheses, come directly from Ruby. Which I think is sensible. (It also translates x y .z
as x(y.z)
, by the way)
I do not think people translate spaces to mean parentheses. I think they read it to mean:
/(\W+)\w+(\W+)/ => $1 + "(" + $2 + ")"
which is pretty easy to remember if you think about it. So the following expressions are pretty straightforward this way:
a b => a(b)
a b c => a(b(c))
a.b c => a.b(c)
a b.c => a(b.c)
a b.c d e.f => a(b.c(d(e.f)))
That said, x y .z
admittedly has an ambiguous interpretation, but only if you think about it different ways. If you hold to the rule above, then you could think about it this way:
x y => x(y)
x y .z => x(y(.z)) # uh oh, invalid! try removing the level of parens we just added
=> x(y.z) # ok!
Or, something like this, which is probably closer to how CoffeeScript actually parses x y .z
:
"x" -> ["x"] # yay identifier
" " -> ["x", ??] # hmm, maybe this is a function? i'll wait
"y" -> ["x", "y"] # this must be a function arg. push onto stack
" " -> ["x", "y", ??] # another upcoming arg?
".z" -> ["x", "y.z"] # huh! this starts with a dot. welp, it can't be an identifier, identifiers can't start with a dot. i'll just append to the prev token
["x", "y.z"] => "x(y.z)" # code translation
Translating whitespace as a placeholder for parentheses is fine for the cases that work:
x y => x(y)
x y.z => x(y.z)
x.y z => x.y(z)
x y .z => x(y).z
but doesn't work for everything:
x y z => x(y)z ??
a b.c d e.f => a(b.c)(d)(e.f) ??? oh good grief
@mcmire, addmittedly this could add some complexity to the current way of parsing code, but the idea would be to use [whitespace].foo
as special case that would causes the expression before that to be evaluated, before continuing with the parsing.
This would cause one weird situation though: how to parse if there is white space on both sides of the dot? I'd just throw a parse error in this case, since i can't see any reason for using such a syntax.
@mcmire
(It also translates x y .z as x(y.z), by the way)
lol, yeh I threw that in there because x y .z
seems like it should translate to x(y).z
Also I just meant translate as a mental image of the code, not a literal translation of _
space to mean (
)
...It's easy enough to know that [space]name
to mean (name
perhaps it's better to look at [space]
to mean just the opening (
parenthesis, and it just closes on it's own... and [space].
force closes the most previous (
, special case like @jussiry said.
I like your parenthesis examples.
x y .z
=> x(y(.z))
invalid! but at least i "makes sense" in mind?
but still if I wanted to write x(y.z)
in coffeescript I'd write it x y.z
, I wouldn't include unnecessary space
x y z => x(y)z ??
nope it'll be in my mind x(y(z
and coffee compiles to => x(y(z))
a b.c d e.f => a(b.c)(d)(e.f) ??? oh good grief
This would be a(b.c(d(e.f
in my mind and compiles to => a(b.z(d(e.f)))
It's currently _impossible_ to write x(y).z
in CoffeeScript without (
parentheses)
. This is an injustice for me as a CoffeeScript parentheses-function-call-hating programmer ... there should be a way.
x y .z # nope
x y
.z # nope
... that's the thing that gets me... I <3 CoffeeScript, it has trained me, to _not use_ parentheses for function/method calls...
x 'hi'
x.y 'hi'
but the only time I have to use parentheses again is for chaining! and then I have to go back and _add that (
...
x(y).z # ahh what the freak, I thought I was rid of those ( ) !!! >:[
It's so freaking weird while programming to write
x y
and then wantin x(y).z
# the only way to write this syntax in CS is to write it the exact same way in JS
It feels unnatural as a CoffeeScript programmer to have to add (
and )
just to chain .z
onto x y
... especially when chaining is so common on client-side coffeescript/javascript programming ... you have to go backwards a lot... very annoying to me.
the only way to write this syntax in CS is to write it the exact same way in JS
Not exactly. I would have written your example as (x y).z
. I find that much more natural because x y
produces a value, upon which we are using the member access operator .
.
@michaelficarra (x y).z
ah good point... you still have to use (
)
though... and when the code started as x y
, it's really annoying to have to add those, and change code to (x y).z
@quangv: Yes, I agree. That's a very common bother for me. This syntax seems like a pretty good solution, although not the most readable. But I'd probably make use of it.
This is an injustice for me as a CoffeeScript parentheses-function-call-hating programmer
See, this I think is a mistake that many people who've jumped on the CoffeeScript bandwagon have made. A thing I learned a while back is just because CoffeeScript lets you do something, doesn't mean you should do it everywhere. Just as you have the option to remove parentheses, you also have the option to leave them in where it would be more readable. Same goes for one-line if statements, comprehensions, etc. CoffeeScript gives you a lot of tools and it's quite easy to abuse them.
I'm not disagreeing with you that it's annoying that you have to add back parens in the x(y).z
case. I just don't think the solution is to allow leaving out the parens, I think the solution is to get into the habit of using parens for require statements only. This is what I do, it's only two extra characters (!), and it's future-proof.
The only case I see where x y .z
makes sense to be interpreted as x(y).z
is when written
x y
.z
(it's still kinda weird but line breaks actually mean something in CoffeeScript so it seems okay). In that light, perhaps x y ; .z
is the solution here. So you could write require "foo"
and then come back later and write require "foo" ; .bar
(or require "foo";.bar
if you wanted to save two characters) and boom, problem solved.
@mcmire Exactly. It's like a Perl programmer writing all of their conditionals like this because Perl allows it:
do { stuff();
moreStuff() } if (condition);
@quangv I was kidding! But really, CoffeeScript isn't about getting rid of parentheses. The parenthesisless syntax for function calls is prettier and possibly more readable on its own and it allows us to make nicer-looking DSLs, but stuff like foo 37 .bar()
is harder (for me) to head-parse than foo(37).bar()
.
@mcmire I think the solution is to get into the habit of using parens for require statements only.
Oh I use chaining in way more things then require
statements... as I learned from #1495 (the multi-line discussion of chaining... I consider this thread the single-line discussion of chaining) for require to use CoffeeScript's destructuring assignment
{bar} = require 'foo'
This is an injustice for me as a CoffeeScript parentheses-function-call-hating programmer
I'm just saying that while writing CoffeeScript codes, I've been train and got into the habit of _not_ using parentheses for function/method calls... and it's a pain to have to go back into my existing code, add parentheses, just to make chaining work.
In other languages/communities, the general conventions seem to tend towards:
Even though the language lets you skip parentheses at times, that's not the go-ahead to skip parentheses all the time.
@yfeldblum, what do you think the CoffeeScript way should be?
CoffeeScript is inspired by Python
In Python, there's the credo
"There should be one-- and preferably only one --obvious way to do it."
Now does the below seem to go with or against this principal ?
x y .z # => x(y.z)
x y.z # => x(y.z)
I think the above is an oversight, unless you can find somewhere or someone who thinks the above is a feature, to let you do, dot notation with space in-between...
The status-quo isn't good enough sometimes, if CoffeeScript wanted to be JavaScript, it wouldn't exist.
@erisdiscord but stuff like
foo 37 .bar()
is harder (for me) to head-parse thanfoo(37).bar()
.
Yes it is, but it's easier to program.
The act of actually adding .bar
onto foo 37
, is much, much simpler, and less annoying, if foo 37 .bar()
was supported instead having to, use your mouse, or keyboard, changing that [space]
after foo
to a (
, then going back to where you was, end of the line, adding ).bar()
...
ahh, annoying just to think about it... it totally _kills the flow_ of you programming.
Looking at other people's code, even looking at your old code, it takes a bit to grok it, but while programming, if you type foo 37
... then you add .bar()
... you have 100% clarity as to what it is you want and expect...
But yeah I don't think CoffeeScript's goal is to have the must beautiful, understandable code in the world (maybe it might be...) but I think it's bigger goal is having one of the best programming experience in the world...
If we wanted 100% understandable, no margin for confusion code, we'll use parenthesis all the time.
foo(37)
is much more self-explanatory then foo 37
... so I ask again, why does CoffeeScript support omissions of parentheses on function/method calls?
maybe CoffeeScript needs a Philosophy ? ...
@quangv CoffeeScript's Philosophy with parentheses isn't that hard to interpret. You can put parentheses in lots of places, even in places where it's only to help the reader. But, unlike Python, CS doesn't require you to put them in places where there's a natural order of operations. Python doesn't require you to write "(5 * 3) + 2" in order to get 17; you are allowed to write "5 * 3 + 2". OTOH Python won't let you write "sum x, y", even though that many folks would say that code has one pretty obvious interpretation. CS just gives you a little more flexibility. It's really not that big a deal.
The whole argument about having to backtrack seems kind of specious to me. If I say x + y, I don't have to surround it in parentheses. But then if I want to double the expression, I have to backtrack and write "(x + y) * 2". That's true even in Python.
maybe CoffeeScript needs a Philosophy ? ...
We got some:
@satyr
- What Ruby does can't be bad.
- The more your code reads like English, the better.
Nice... where you get those?
@showell ... interesting interpretation, very laissez-faire... parentheses are optional, only when they are not... my only comment is (x + y) * 2
has a very known order of operations... what's the order operation of x y .z
...
I still don't like how that [space]
in between y & .z means nothing...
It's like the [space]
in between x & y, means something, why not the later?
What do you guys think about this, for single-line & multi-line chaining support.
x y .z
# => x(y).z
x y
.z
# => x(y).z
CoffeeScript is inspired by Python
Well, CoffeeScript is inspired by a few languages. Comprehensions, significant whitespace, and leaving off "end's" come from Python, the rest comes from Ruby/Perl and some of the Harmony/ES6 proposals.
maybe CoffeeScript needs a Philosophy ? ...
I think it already does, really: be a better version of JavaScript. CoffeeScript starts with JavaScript and makes it suck less by adding 'modern' features that have already been well accepted in other languages.
In any event, your example (against Python's motto) doesn't really fly because x y .z
isn't an intended alternate way to write x y.z
, it's an edge case, something that the parser is forced to handle because it isn't a feature of the language. Actually the whole parentheses thing is a red herring -- the edge case is x .y
. There's two ways to handle this -- either convert it to x.y
, or fail with a parser error -- and obviously we know what CoffeeScript does. I mentioned that its behavior comes from Ruby, but I just checked and Python not only does this, but more importantly, JavaScript does as well. (Where JavaScript got it from, I'm not sure, perhaps C?) So while it's kind of silly -- honestly I would expect a parse error -- that's what happens. It's a historical thing. (Although, not entirely illogical; after all, you can say foo[bar]
just as you can say foo [bar]
... so in that light foo .bar
is just being consistent. You can also say foo \n .bar
or foo ; .bar
, so foo .bar
is also being consistent there too.)
Normally this behavior would be a non-issue and could be "fixed", because being an edge case and not a feature, no one would (should) actually write x .y
in their code on purpose, and that's as complicated as an expression like that can get without creating a parse error (because x y .z
is not valid JavaScript), so handling it in a weird way is inconsequential, so no one would (probably) mind if you changed it.
It's only consequential now because CoffeeScript has the ability to fill in missing parentheses.
my only comment is (x + y) * 2 has a very known order of operations... what's the order operation of x y .z ...
Exactly -- which takes precedence, placement of parenthesis or autocorrection of method calls. So going back to my take on the "philosophy" of CoffeeScript -- I think when ambiguity arises like this, the correct behavior would be to do what JavaScript does first, then layer CoffeeScript-specific behavior on top of that. That's why I think x y .z
should remain as x(y.z)
-- because with parenthesis, JavaScript would parse x(y .z)
as x(y.z)
, so parsing x y .z
as x(y.z)
is just the next logical step. In other words, apply the JavaScript rule first, then CoffeeScript. I think this is true to the design of CoffeeScript itself, if you look at other things in CoffeeScript.
You asked why does CoffeeScript let you omit parentheses and I say, for the same reason that it drops parentheses around if statements and lets you write foo if bar
or foo for foo in bar
. These features serve their purpose when you use them if 1) you write less code and 2) your code is more readable in the process. If you write less code but your code is less readable, then it is probably not wise to use them. (Yes it is true that it is easier to write, but then again, all code is easier to write than read. Always.) In the case of require "foo" .bar
it is less readable only because we have been trained to expect (through previous languages that use dot notation for OO code, and just, I think, the natural way that people read code, which is left-to-right) that a dot is connected to whatever comes immediately before it, and that whitespace (well, spaces) in this scenario are insignificant and should be ignored.
Nice... where you get those?
Jeremy's mind.
@mcmire
Thanks for thorough reply. A lot of the reasons you make against proposed [white-space][dot]
syntax could be had in support of the syntax.
First let me clear up:
"For x .y
, I think we can look at it like (x).y
and compile it to x.y
=p"
#1495
I totally think x .y should still be x.y ... weird I know, hah but it makes the most sense to me. if we wanted to chain x, write it as x().y
... there's no annoying back-track-coding that takes place.
x y .z
isn't an intended alternate way to writex y.z
, it's an edge case, something that the parser is forced to handle because it isn't a feature of the language.
Totally agree with you. It's an 'oversight', 'toleration', not really a 'feature'.
Thanks for checking how Ruby, Python handles this. I kinda agree that throwing an error might be worse than just pretending that the space isn't there... but that's up for debate as well. (like JS supporting lines without ending in ;
) ... whoa foo [bar]
is worst then foo .bar
!
Normally this behavior would be a non-issue and could be "fixed", because being an edge case and not a feature, no one would (should) actually write
x .y
in their code on purpose, and that's as complicated as an expression like that can get without creating a parse error (becausex y .z
is not valid JavaScript), so handling it in a weird way is inconsequential, so no one would (probably) mind if you changed it.
Yes, well put! Hopefully not... x .y
i think should still be x.y
, but x y .z
compiling into x(y).z
would make a lot of us salivating for a chaining syntax happy. :)
I think when ambiguity arises like this, the correct behavior would be to do what JavaScript does first, then layer CoffeeScript-specific behavior on top of that. ... I think this is true to the design of CoffeeScript itself, if you look at other things in CoffeeScript.
Yes, I agree, default to JS when there's no CoffeeScript-specific behavior. Hopefully we can have a CoffeeScript-specific chaining syntax for everyone who wants it, but inconsequential enough that people who don't use this new CS-specific syntax, won't be impacted by it, and all their current CS code, compiles and works the same... tall order, but hopefully we can get-her-done... back-track-coding is just way too annoying.
You asked why does CoffeeScript let you omit parentheses and I say, for the same reason that it drops parentheses around if statements and lets you write foo if bar or foo for foo in bar. These features serve their purpose when you use them if 1) you write less code and 2) your code is more readable in the process. ... In the case of require "foo" .bar it is less readable only because we have been trained to expect that a dot is connected to whatever comes immediately before it, and that whitespace (well, spaces) in this scenario are insignificant and should be ignored.
:)
I think this x y .z => x(y).z
agrees with your 1., less code, and 2. readability is in the eye of the beholder, and I also agree with you that once we are trained of this new behavior, it'll be that much easier to understand the code.
Some non-Coffee-er cold argue foo(bar)
is easier to read than foo bar
... but I don't think any Coffee-er is willing to give up this great syntax... CoffeeScript's makes white-space significant and it's clever use of white-space is one of the reasons I think that makes it so awesome.
@satyr I think it should be written somewhere... I believe more lexical conflicts of syntax, taste, and grammar would come up in the future that maybe a simple "doesn't comply with our Philosophies" would be a great response... and people can argue the merit of a particular principal before a proposed syntax enhancement or change. The FAQ is a great lift-off point and the official docs has philosophies and principals littered through-out. :) Keeping CS awesome I think is everyone's main goal...
@quangv So this is interesting, look what coco does: http://satyr.github.com/cup/#c:a%20b%20.c%20.d%20e /cc @satyr
@quangv So this is interesting, look what coco does: http://satyr.github.com/cup/#c:a%20b%20.c%20.d%20e /cc @satyr
Oh wow, that's cool! Nice job @satyr ... I didn't realize what Coco was...
http://satyr.github.com/cup/#c:x%20y%20.z awesome, perfect... coffeescript should compile this way too.
Currently
foo bar .baz()
compiles tofoo(bar.baz());
This seems unlogical, since the same result can be gained with cleaner code by writing
foo bar.baz()
.So should't it rather compile to
foo(bar).baz();
? This would allow us to write code with even less parenthesis in many situations (something i'v really learned to love with CoffeeScript).