-
Notifications
You must be signed in to change notification settings - Fork 111
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
Is this a reportable issue? #45
Comments
I think you need to show a better example. Not only would that example give a run-time error but I can't think of why anyone would code something so wrong. |
jQuery code, for example ? ;) |
That kind of syntax was fantastic with jQuery: $('<a/>').css
'color': 'blue'
'text-decoration': 'underline'
.appendTo 'body'
$('<a/>').css({
'color': 'blue',
'text-decoration': 'underline'
}).appendTo('body'); |
Thanks connec - that's more accurate to the way I'm actually doing it, I was just trying to provide a really simple example :) There's a few modules/libraries (jQuery, fs.createWriteStream pipe, underscore) that use "chaining" (is that the right word?) like that, and the habit of being able to put a period at the start of the line for those chains, separating them onto separate lines makes them easy for me personally to read/undertsand. I'm sure it's wrong as mark-hahn said, so I was really hoping to ask more generally if coffeescriptredux intends to support those wrong things that folks like me are doing :) |
After looking into this syntax, I've come to the conclusion that this was not an intentional feature. At the end of a function call, an implicit object may be given on the next line, specifying that it is to be used as the last argument. You shouldn't then be able to chain to that result without using parentheses to explicitly specify the target. Instead, use (($ '<a/>').css
color: 'blue'
'text-decoration': 'underline'
).appendTo 'body' or $('<a/>').css({
color: 'blue'
'text-decoration': 'underline'
}).appendTo 'body' or (($ '<a/>').css color: 'blue', 'text-decoration': 'underline').appendTo 'body' |
Hmm... i feel this is yet another case for a nice chaining syntax. For example, this is valid in LiveScript: $ '<a/>'
.css color: 'blue', 'text-decoration': 'underline'
.appendTo 'body' However, it seems this is not supported: $ '<a/>'
.css
color: 'blue'
'text-decoration': 'underline'
.appendTo 'body' A proper chaining syntax does not belong to this issue, and it has been discussed many times before, but i just wanted to comment that this might be another case for it :) |
I'd be very disappointed if this didn't make it into Redux, clean chaining syntax like this is a pretty big deal for myself, and I expect others, who regularly use jQuery and other similar APIs and wish to fully utilise CoffeeScript's clean, low-parenthesis syntax. Also, from what you've said ("specifying that it is to be used as the last argument"), would the following also not be intentional: some_func
object: 'argument'
, another_param |
@connec: You've got it. I would run screaming from code written like that. |
Putting a comma in the front of a line is the standard way to ensure it FWIW, I'm a bit concerned that redux is pulling a lot of useful features On Tue, Sep 18, 2012 at 3:50 PM, Michael Ficarra
|
@michaelficarra: OK how about (I can't run the Redux compiler on this system, sorry):
Not supporting these syntaxes could break a significant amount of production code... |
@mark-hahn: That is also a concern of mine. I really do not want this compiler to change the CoffeeScript language or break our users' production CoffeeScript code. But there has to be a line we draw between intentional features and quirks. I am not duplicating quirks. The original compiler was very, very permissive, allowing unintentional and inconsistent syntax. |
One man's meat is another man's poison. And it isn't just quirks. BTW, some of these issues fall under the category of line continuations. I'm not suggesting a continuation fix, just stating the problem. On Tue, Sep 18, 2012 at 4:11 PM, Michael Ficarra
|
So, I'm not sure what the decided action is on this sort of thing, however it seems to me that:
is entirely non-ambiguous and likely used all over production code. IMO, I think the initial release of CoffeeScriptRedux is probably not the place to be making choices that significantly change the semantics of the languages for items that seem to be already well specified, even if a bit clunky, or cumbersome. Now, I only stand behind the argument so long as this sort of thing is both unambiguous and well specified, but it does seem so to me. |
+1 It would be a step backwards to lose this construct. On Sun, Dec 16, 2012 at 2:46 AM, Arelius [email protected] wrote:
|
-1 I find those constructs completely unreadable for anyone not expert in CoffeeScript (like other employees, which I'm trying to convince to use CoffeeScript). Less parens are counter productive IMO |
@delaaxe I'd tend to agree, in fact I feel any instance of implicit parens are error-prone and counter-productive. But this is about the fact that this is a compiler for an existing, and reasonably well used existing language. With what's quite possibly hundreds of thousands of existing lines of code, many of which use these more poorly specified quirks of the language. And it's awfully naive to assume that the community is going to manually rewrite thousands of lines of code for dubious gains. Frankly disallowing this sort of code is the place of a strict-mode, or perhaps even something much more like coffeelint. Or perhaps this could be a valid approach, if someone wrote a source rewriting tool to perform these modifications automatically, however the problem with that, is first a parser needs to exist that can fully understand legacy CoffeeScript, and also do source location tracking. Yet since one of the major goals behind the Redux rewrite was to implement that behavior, that legacy parser is clearly not to come from the mainline codebase. |
While i agree with the general sentiment in that it would be cool to have a more clear way to express chaining (i.e. chaining special syntax), i also agree with @mark-hahn in this one, forbidding these constructs altogether will break lots of today-legal code. This a sample snippet from a Stack Overflow answer i saw today: items
.map (item) ->
item.price * item.quantity
.reduce (x, y) ->
x + y These constructs are valid in today's CS and lots of people are very used to using them. It's hard to imagine someone fixing their codebase all over the place just to support a new compiler. That's why i think it would be cool if Redux supported this arguably "bad" syntax constructs. |
It may be arguable but I'd take the side of the argument saying it is a On Wed, Dec 19, 2012 at 8:23 AM, Demian [email protected] wrote:
|
+1 We use this style of chaining extensively. Chaining is encouraged by libraries like jQuery and underscorejs so I expect many coffeescript users are using chaining sugar like this. |
👍 |
The current Redux allows multi-lined chaining chart = d3.select('#graph')
.append('svg')
.attr('width', width)
.attr('height', height) There are lots of codes such as this one below, and I would say that there is no confusion what the programmer's intensions are. Like @epidemian said, lots of people have to adjust their styles if Redux drop this. chart = d3.select('#graph')
.append('svg')
.attr('width', width)
.attr('height', height) Sometimes unintended creations works as well, no? |
Yep, just tried to compile a pretty big CoffeeScript app with Redux and ran into this. CoffeeScript mainline has always been a bit fiddly with chaining, but this always worked: a.b()
.c() That now throws an error in Redux but not the original compiler. Redux does allow you to chain without the spaces in front of the |
Nami: Wait, what exactly are you arguing for? You don't like the back-and-forth indenting, it seems. Well me neither, but I don't like the "run-away" indenting either. Normally, indenting means something. It means a change in something. Here, it changes nothing. Or at least, that's what I'm discussing now. :) eq nonce, o
.a()
.b
.c should mean something, but I don't want it to mean the same as eq nonce, o
.a()
.b
.c Do you get what I mean by "dot-blocks". Blocks are things that have the same indenting, and therefore belong to each other. You do "if something", change indenting, do a few things, go back (outdent), and then you're in the original indenting. Back in original "context". |
I doubt jashkenas would state that as his goal specifically. |
It should not mean the same as your second example ... In a perfect world. In a world where we need backcompat, we need that too. If we use that to allow for prog1s (or anything else) later, we first need to remove that from the official compiler. And that's not going to happen. So I think this is usually bad style, but should still be supported |
Michael, I know your coffee dreams. That's what the original title for the kickstarter was I think. That has won you my sympathy. |
I agree about non breaking things in a whim, but that what's deprecation is for. No-one says that the very next release of CS has to be Redux-based, no? The next release of CoffeeScript 1.x could introduce warnings about such syntax. It could even be two releases, or three, for all I care. I must admit: I don't know the exact roadmap for "2.0", if there is any. If indeed CSR will be the next major release of CoffeeScript then yes, it better has backwards compatibility with every quirk. But if there's still time, then the old CS code could be made to pave the way (by issuing warnings) for a new compiler, which does not have to do quirks. (I'm speaking in broad terms now). |
Considering jashkenas likes this syntax (see my HN link), I doubt you're going to get it removed from the official compiler. (and also because it's completly fucked-up concerning whitespace :p) |
Nami: Thanks, I had not seen these code examples before. Looking at them, I can kind of understand why people would like the "run-away" indenting. I personally never had a need for heavy method chaining (I generally dislike the idea) before I started to explore promises seriously, so I don't have much feel for how people "see" the chains they made. How they see them, is how they want to express them in code. And give them then chance (as CoffeeScript has), they will. I think jashkenas comment is a bit weird though. Technically, I think it's "wrong". What I mean by that is that "significant whitespace" in context of CoffeeScript, Python etc has meant that whitespace actually has meaning to the parser. The examples given are really examples of insignificant whitespace. Languages like Javascript and C allow this kind of stuff everywhere, as long as you remember to always "match your braces" (or else, hell and fury upon you). CoffeeScript also don't allow you to embed your programs in kind of ASCII art, as some guys who want to be funny in C and Javascript do. That's all user perception. And yes, I can appreciate "99 bottles of beer" seeing written in the shape of a beer bottle. Now and then. Not too often, please. :) |
I think raganwald's comment is much more sensible. He actually proposes two different meanings for same-indent and increasing-indent, wrt to lines starting with a dot. It actually goes counter to what would be ideal for how promises work (at least, how they are specced now) because they were designed to use with chaining to prevent run-away indenting. But at least, it assigns significance for white space. He mentions array and pop in his example. I'd whip up a prototype, but right now it cannot result in pretty coffeescript syntax. I would have keep saying scheduler.schedule -> new Promise(a)
scheduler.schedule -> new Promise(b)
scheduler.schedule -> new Promise(c) No way to keep referring to the same object, I think. @schedule -> apromise
@schedule -> bpromise
@schedule -> cpromise or @then -> apromise
@then -> bpromise
@then -> cpromise The fact that this is quite terse (@ is exactly the same length as a ".") might actually be an argument to not use these dot-blocks for this purpose. They're too precious for that. Scheduler could be called "promise chain" too. Instead of a regular promise chain, represented with syntax, the chain would be represented by an object. His example of multiple pops could probably work if he'd do arr =[1,2,3,4,5]
func = ->
@pop()
@pop()
@pop()
func.apply arr
# arr should now be [1,2] Not the prettiest, I must admit. |
Craziness: raganwald, the guy arguing for different meaning of same-indenting and increasing-indenting actually is the same guy telling us about his personal style where he uses whitespace just for his own understanding of the code. |
A hypothetical SweetArray instance could have a arr = new SweetArray([1,2,3,4,5]).applyToSelf ->
@pop()
@pop()
@pop()
# arr.getRealArray() is [1,2] This is basically an alternative way for a library like jQuery to allow chaining-like syntax. It could also be implemented by my aforementioned PromiseChain. The interesting thing is that the object's individual methods (in this case pop) can return a different, otherwise meaningful value (in this case, the value that was popped). IMO, that reduces the question down to: How many times do you want to apply chaining to builtins like Array, String and Number? How many times of those is it that hard to wrap the native object inside a decorator (like SweetArray). Or just extend the Array prototype... |
In fact, the value of arr is the return value of applyToSelf arr = quickWrap([1,2,3,4,5]).applyToSelf ->
@pop()
@pop()
@pop()
# arr is [1,2] The wrapper object is immediately discarded. It was only there to allow for the chaining "syntax". arr = [1,2,3,4,5]
$(arr).do ->
@pop()
@pop()
@pop()
# arr is [1,2] |
@Nami-Doc The point is here that jashkenas is asking raganwald how he would design syntax for a language. And indeed, raganwald answers that he'd like whitespace to be actually significant in his ideal language so that "run-away" indenting means something different than same-level indenting. Jeremy applauds that. So that means he actually likes (or at least - liked) the idea that o
.a()
.b
.c would indeed mean something different than o
.a()
.b
.c That's the whole point of "significant whitespace". Hence his comment. He sees even more expressive power in whitespace than before. |
I'd love to see that as a cascade (prog1) :). Probably with a slightly different op, tho |
@Nami-Doc Maybe you could ask Jeremy to give a quick comment on his current state of thinking on this?
|
@meryn: Just call him here. Oh @jashkenas, @jashkenas, wherefore art thou, @jashkenas? |
Forsooth, doth yonder issue beckon?
Finally, to answer Michael's question way, way upthread, the current implicit-object-implicit-call-chaining "support" is actually intentional:
... as you can start with a filled-in version of it, and then arrive at that point by removing parens and braces. I remember having a conversation about allowing it a while back. But that said, it's extremely poor style. I'd be pretty happy to get rid of it, if that's the consensus. |
I think at least wrt to current parser behavior it should be added: "it should be treated as an effective continuation of the previous line if indent stays same or increases", because:
does not equal
and I'm thankful for that. On second thought, this is probably more of an instance where some other rules (leaving function definition because of outdent) take precedence, at least in current parser. Because current parser indeed supports back-and-forth indenting of regular |
So to get this clear: You favor o
.a()
.b
.c and o
.a()
.b
.c to mean the same as o
.a()
.b
.c ? I'd rather have it stricter, and demand starting-dots to be aligned, effectively forming a dot-block. They could be arbitrarily indented though, to allow visual aligning the "dot-block" with the dot on the previous line. You can also indent regular a block (say something following an |
Maybe I'm gonna write a new kind of parser, in the form of
and just see how far I come. :) If it works, we'd have a nice list of rules, ordered by precedence. BTW I don't know how current parser works. |
IIRC, CoffeeScriptRedux is a try-and-fail compiler. The compiler tries every rule, starting from its preferres rule, and failing with an explanative error message if none matched |
I shouldn't have said "new kind", because I don't know current parsers. But there may be difference to my idea and redux, at least if I can trust the program's error message: Redux says "unexpected [token]", my output would say "ambiguous blurp beyond current position". It would do it best to look at everything beyond the current "cursor" position (i.e. from the point in the code where it was still unambiguous what was going on). Which could make it very slow, but that's not a concern. |
To explain further: Most notably, there wouldn't be a "grammar", or at least not in the traditional sense. Just a bunch of "rule" functions or classes, each documented in prose, implemented however seems best to me. I'd want to be able to turn this:
into a self-standing piece of code (a class, or a function), that could be left in or out without any repercussion. Leave it out, and there's no indented member access. Put it in, and you have it. |
+1 I like CS over JS due to it being more "readable" & a bit more "standardized". Too much zig-zag makes code harder to scan. It also makes it slightly more confusing to figure out what indentation is significant or not. So dot-lining would be great. |
What's the status with this? I just tried object
.method(arg)
.method2()
.method3() and noticed it worked. That's pretty cool! This, however, does not: startChain()
.then ->
doSomething()
.then (result) ->
console.log result
That's unfortunate, because I use this type of syntax a lot throughout my code. |
Also, anObject
.someProp
.someOtherProp and
|
@meryn: That looks pretty serious. Can you open an issue for that? |
@michealficarra: done On Thu, Aug 22, 2013 at 10:43 PM, Michael Ficarra
|
Just tried out coffee-redux, and also ran into the issue with the SomePromise()
.then ->
'do something here'
.otherwise ->
'fail' does this look like something that'll eventually make it into this version (since the ticket is still labeled as question)? |
Is the plan still to fix this? I ran into the same issue as @tgriesser above using the latest version of redux. |
There's a lot of probably bad conventions of gotten used to being able to do in coffee that I'm not even sure are supposed to be ok in coffeescript, but since it was the first syntax errors I encountered in my own code with this project I thought I'd ask:
Is this something worth reporting at this point? Is this project's goal to handle all issues like this, or was that bad coffeescript?
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: