|
View:
New views
20 Messages
—
Rating Filter:
Alert me
|
| < Prev | 1 - 2 - 3 - 4 | Next > |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 17, 2009, at 1:11 PM, Brendan Eich wrote:
> On May 17, 2009, at 12:43 PM, Mark S. Miller wrote: > >> On Sun, May 17, 2009 at 11:00 AM, Brendan Eich >> <brendan@...> wrote: >>> Analogous to direct vs. indirect eval in ES5 (15.1.2.1.1), there >>> is no >>> purely syntactic specification for what Neil proposes. A runtime >>> check is >>> required. So I don't see why you are focusing only on syntax here. >> >> I don't follow. What runtime check? For the eval operator, the >> runtime >> check is whether the value of the eval variable is the original >> global >> eval function. It makes no sense to have a corresponding global yield >> function value. > > If we reserve yield then you're right. It's goofy to have return w; delete x.y; typeof z; yield a; => SyntaxError! must use yield(a) The mandatory parentheses could be avoided by breaking from Python's precedent and making yield a canonical unary (that is, high-)precedence operator like delete, !, etc. But then almost any algebraic or logical expression computing the value to yield would need parentheses, and people would make mistakes such as yield a + b where they meant yield(a + b) -- as in Python -- but got yield(a) + b. This is one reason, if I recall some PEP text correctly, why Python requires parentheses around all yield expressions except those on the right of assignment operators in assignment statements, and in yield statements. It seems best to require explicit parentheses when yield is part of a larger expression, no matter the precedence of its optional argument/operand. But when there's no larger expression, why require gratuitous parentheses? /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxBrendan Eich wrote:
> On May 17, 2009, at 12:43 PM, Mark S. Miller wrote: >> On Sun, May 17, 2009 at 11:00 AM, Brendan Eich <brendan@...> >> wrote: >>> Analogous to direct vs. indirect eval in ES5 (15.1.2.1.1), there is no >>> purely syntactic specification for what Neil proposes. A runtime >>> check is required. So I don't see why you are focusing only on syntax here. >> >> I don't follow. What runtime check? For the eval operator, the runtime >> check is whether the value of the eval variable is the original global >> eval function. It makes no sense to have a corresponding global yield >> function value. > > If we reserve yield then you're right. One of the appealing (at least to > me) aspects of Neil's suggestion was that it would avoid opt-in > versioning required by reserving yield (which is used in extant web > content, or was when we tried reserving it without opt-in versioning -- > the particular use was as a formal parameter name, used as a flag not a > function). Oh, right. We've been talking at cross-purposes. I assumed that you were suggesting that 'yield' should be contextually reserved. That is what I've been saying couldn't work due to ambiguities. -- David-Sarah Hopwood ⚥ _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxOn May 17, 2009, at 5:05 PM, David-Sarah Hopwood wrote:
> Brendan Eich wrote: >> On May 17, 2009, at 12:43 PM, Mark S. Miller wrote: >>> On Sun, May 17, 2009 at 11:00 AM, Brendan Eich <brendan@...> >>> wrote: >>>> Analogous to direct vs. indirect eval in ES5 (15.1.2.1.1), there >>>> is no >>>> purely syntactic specification for what Neil proposes. A runtime >>>> check is required. So I don't see why you are focusing only on >>>> syntax here. >>> >>> I don't follow. What runtime check? For the eval operator, the >>> runtime >>> check is whether the value of the eval variable is the original >>> global >>> eval function. It makes no sense to have a corresponding global >>> yield >>> function value. >> >> If we reserve yield then you're right. One of the appealing (at >> least to >> me) aspects of Neil's suggestion was that it would avoid opt-in >> versioning required by reserving yield (which is used in extant web >> content, or was when we tried reserving it without opt-in >> versioning -- >> the particular use was as a formal parameter name, used as a flag >> not a >> function). > > Oh, right. We've been talking at cross-purposes. I assumed that you > were > suggesting that 'yield' should be contextually reserved. Oh, I should have seen that. Thanks for clarifying. > That is what > I've been saying couldn't work due to ambiguities. RIght, no sane way to reserve yield or another keyword contextually (e.g., only in callee position; "contextually" in the sense of get and set in object initialisers). In JS1.7+, we reserve yield with opt-in version selection via <script type="...;version=1.7"> and the like. In such a script, yield and let are reserved the same way the other identifiers are, which is how ES5 does it (with an extension we've discussed -- the extension where a reserved identifier can be used after 'function' -- but that's not interesting for this discussion). /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 17, 2009, at 7:01 PM, Brendan Eich wrote: > The mandatory parentheses could be avoided by breaking from Python's > precedent and making yield a canonical unary (that is, > high-)precedence operator like delete, !, etc. But then almost any > algebraic or logical expression computing the value to yield would > need parentheses, and people would make mistakes such as yield a + b > where they meant yield(a + b) -- as in Python -- but got yield(a) + b. I'm going to make the argument that this is about where the parenthesis go -- not *if* -- but where. - we could always allow parenthesis to be dropped when the yield is the entire expression of an expression statement or the right-hand side of an assignment. - in my experience with JS 1.7 I almost always had to parenthesize the yield expression when it was in some other kind of expression. An in the cases where parenthesis weren't required, I parenthesized anyway to avoid ambiguity and maintain coding style consistency. (And because I got tired of predicting incorrectly whether or not parens would be required in a particular context.) So I would argue that there are two syntactical forms of yield, yield E and (yield E), and that the rules regarding the requirement for parenthesis are hard to predict (from personal experience). Therefore, I argue that it would make sense to simplify a bit: - the yield E form may be used when it is the entire expression of an expression statement - all other times it must be parenthesized Which is *kind of* a way of saying, if you're ignoring the send value, you don't have to parenthesize. But if you use the send value, you must parenthesize. And now that we've made clear the definition of parenthesized and non- parenthesized forms of yield, we can proceed to argue that yield(E) is a valid form of parenthesis, as much so as (yield E). Pros for yield(E): - backward compatible - easier to read (to my eye) - it "feels" more correct to me in context of the when-using-send- value rule Pros for (yield E): - consistent with python - doesn't present any is-it-a-function? ambiguities _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)As a follow on to my argument I would cite two examples for why it
would be good to always require parenthesis when the send value is used: Example 1 I saw somewhere else in this thread: yield a ? b : c Is it (yield a) ? b : c | yield(a) ? b : c, or (yield a ? b : c) | yield(a ? b : c) example 2: let x = yield-5; is that let x = (yield) - 5; | let x = yield() - 5; or is it let x = (yield -5); | let x = yield(-5); I know the rules for both examples are very clear, but programmers don't always read the specs. :P To someone not intimately familiar with JS order of precedence, either one presents ambiguity (or worse, doesn't!) Why play with fire? On May 17, 2009, at 8:39 PM, Neil Mix wrote: > > On May 17, 2009, at 7:01 PM, Brendan Eich wrote: >> The mandatory parentheses could be avoided by breaking from >> Python's precedent and making yield a canonical unary (that is, >> high-)precedence operator like delete, !, etc. But then almost any >> algebraic or logical expression computing the value to yield would >> need parentheses, and people would make mistakes such as yield a + >> b where they meant yield(a + b) -- as in Python -- but got yield(a) >> + b. > > I'm going to make the argument that this is about where the > parenthesis go -- not *if* -- but where. > - we could always allow parenthesis to be dropped when the yield is > the entire expression of an expression statement or the right-hand > side of an assignment. > - in my experience with JS 1.7 I almost always had to parenthesize > the yield expression when it was in some other kind of expression. > An in the cases where parenthesis weren't required, I parenthesized > anyway to avoid ambiguity and maintain coding style consistency. > (And because I got tired of predicting incorrectly whether or not > parens would be required in a particular context.) > > So I would argue that there are two syntactical forms of yield, > yield E and (yield E), and that the rules regarding the requirement > for parenthesis are hard to predict (from personal experience). > Therefore, I argue that it would make sense to simplify a bit: > - the yield E form may be used when it is the entire expression of > an expression statement > - all other times it must be parenthesized > > Which is *kind of* a way of saying, if you're ignoring the send > value, you don't have to parenthesize. But if you use the send > value, you must parenthesize. > > And now that we've made clear the definition of parenthesized and > non-parenthesized forms of yield, we can proceed to argue that > yield(E) is a valid form of parenthesis, as much so as (yield E). > > Pros for yield(E): > - backward compatible > - easier to read (to my eye) > - it "feels" more correct to me in context of the when-using-send- > value rule > > Pros for (yield E): > - consistent with python > - doesn't present any is-it-a-function? ambiguities > > _______________________________________________ > es-discuss mailing list > es-discuss@... > https://mail.mozilla.org/listinfo/es-discuss _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 17, 2009, at 11:48 AM, Brendan Eich wrote:
> On May 17, 2009, at 11:00 AM, Brendan Eich wrote: > >> Python differs from JS by having only assignment statements, not >> assignment expressions, which simplifies the problem a bit, as the >> grep output cited above shows. > > Of course this makes trouble with automatic semicolon insertion, > unless assignment statements are split from assignment expressions. > D'oh! > > js> function g() {z = yield a ? f : x++()} > typein:2: SyntaxError: missing ; before statement: > typein:2: function g() {z = yield a ? f : x++()} > typein:2: .................................^ > js> function g() {(z = yield a ? f : x++)()} diagnostic being suboptimal). This is not a case of a high-precedence prefix operator whose following operand is a low-precedence expression non-terminal. That's unsound. In this example, yield is just like a nested assignment: js> function g() {z = w = a ? f : x++()} typein:1: SyntaxError: missing ; before statement: typein:1: function g() {z = w = a ? f : x++()} typein:1: ...............................^ where the body (z = w = a ? f : x++()) === (z = (w = (a ? f : x++()))). If PrimaryExpression: yield AssignmentExpression were a production in the grammar, then we would have the bug I was worried about, the one that Waldemar pointed out let expressions, which also afflicts expression closures (ASI makes the bug harder to spot, was Waldemar's further point -- but ASI is not an issue here). > Patching this is harder than I thought it would be. After hacking at > the Bison grammar a bit, I concede your point about implementation > difficulty! I still concede greater burden on implementor, but here's an updated WebKit/JavaScriptCore/parser patch: /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 17, 2009, at 6:39 PM, Neil Mix wrote:
> On May 17, 2009, at 7:01 PM, Brendan Eich wrote: >> The mandatory parentheses could be avoided by breaking from >> Python's precedent and making yield a canonical unary (that is, >> high-)precedence operator like delete, !, etc. But then almost any >> algebraic or logical expression computing the value to yield would >> need parentheses, and people would make mistakes such as yield a + >> b where they meant yield(a + b) -- as in Python -- but got yield(a) >> + b. > > I'm going to make the argument that this is about where the > parenthesis go -- not *if* -- but where. Yes, this is the issue. > - we could always allow parenthesis to be dropped when the yield is > the entire expression of an expression statement or the right-hand > side of an assignment. Right-hand side of assignment is ok without parens in Python because assignment is a statement. In JS if you allow assignment expressions ending in unparenthesized yields, then you can have unparenthesized yields in argument and initialiser lists, comma expressions, and in the middle and final operand positions in ternary (?:) expressions. > - in my experience with JS 1.7 I almost always had to parenthesize > the yield expression when it was in some other kind of expression. > An in the cases where parenthesis weren't required, I parenthesized > anyway to avoid ambiguity and maintain coding style consistency. > (And because I got tired of predicting incorrectly whether or not > parens would be required in a particular context.) The only contexts we allow you not to parenthesize in JS1.7 are assignment expressions and final argument in list. But see above -- the assignment expression loophole is big enough to allow foo(a = yield b, c); One argument, or two? Comma is low enough precedence that users (with or without Python exposure) don't view it as an operator. > So I would argue that there are two syntactical forms of yield, > yield E and (yield E), and that the rules regarding the requirement > for parenthesis are hard to predict (from personal experience). > Therefore, I argue that it would make sense to simplify a bit: > - the yield E form may be used when it is the entire expression of > an expression statement > - all other times it must be parenthesized Agreed; this closes the assignment expression loophole. > Which is *kind of* a way of saying, if you're ignoring the send > value, you don't have to parenthesize. But if you use the send > value, you must parenthesize. > > And now that we've made clear the definition of parenthesized and > non-parenthesized forms of yield, we can proceed to argue that > yield(E) is a valid form of parenthesis, as much so as (yield E). Nothing prevents you from writing yield(E) of course -- but you're arguing that foo(a = yield(b), c) should be enough, no extra parens required -- no foo(a = (yield(b)), c). Right? > Pros for yield(E): > - backward compatible But for this to be true, we would need to use the direct-eval detection hack I mentioned previously. > - easier to read (to my eye) > - it "feels" more correct to me in context of the when-using-send- > value rule These are subjective enough there's no point in arguing. I hear ya. > Pros for (yield E): > - consistent with python > - doesn't present any is-it-a-function? ambiguities These are more objective (no look & feel ;-). There is a borrowing from Python. There isn't a function call going on. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)2009/5/17 Brendan Eich <brendan@...>:
> One of the appealing (at least to me) > aspects of Neil's suggestion was that it would avoid opt-in versioning > required by reserving yield (which is used in extant web content, or was > when we tried reserving it without opt-in versioning -- the particular use > was as a formal parameter name, used as a flag not a function). This yield-like-eval proposal also requires to have a special function to create a generator since yield (as implemented in SpiderMonkey and in Python) is used both to implement the yielding action and to indicate that the function is a generator. The latter is necessary as a call to a function with yield somewhere in the body creates a generator, it does not execute one. For that reason the compiler must know what yield means, it can not wait for a runtime check. The remedy for this is simple - the generator can be created using explicit call like Generator(f, arg1, ... argN). This would turn any function into a generator and would allow for runtime checks for eval. The plus side of this is that an empty generator can be created with a straightforward: Generator(function() {}) and not with a rather unnatural (function() { if (false) yield; })() Igor _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On 2009-05-17, at 14:00EDT, Brendan Eich wrote:
> those painful and fruitless parentheses Sometimes those parentheses are comforting, not painful. How many times in JS do you see: typeof(foo) or in C.* sizeof(boo) _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 18, 2009, at 5:56 AM, P T Withington wrote:
> On 2009-05-17, at 14:00EDT, Brendan Eich wrote: > >> those painful and fruitless parentheses > > Sometimes those parentheses are comforting, not painful. How many > times in JS do you see: > > typeof(foo) > > or in C.* > > sizeof(boo) > Or even return(wahhh); -- a sign of weakness in the old days, among kernel hackers :-P. Making them mandatory is the issue. You can derive whatever comfort you want from 'em, but they are not required and we're not going to start requiring them for return, delete, or typeof. So mandating parentheses for yield is kind of wrong. Obviously the issue would go away if the precedence where the same as delete and typeof. Hence "kind of". /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 18, 2009, at 2:25 AM, Igor Bukanov wrote: > The remedy for this is simple - the generator can be created using > explicit call like Generator(f, arg1, ... argN). This would turn any > function into a generator and would allow for runtime checks for eval. You mean yield, not eval, right? > The plus side of this is that an empty generator can be created with a > straightforward: > > Generator(function() {}) > > and not with a rather unnatural > > (function() { if (false) yield; })() No one makes empty generators. I think this cure is worse than the disease! The problem of yield's precedence can be solved by mandating parenthesization as Python does -- or if ugliness prevails, as Neil proposes :-P. It doesn't need more runtime magic machinery and global constructors that are otherwise unmotivated. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)> Nothing prevents you from writing yield(E) of course -- but you're
> arguing that foo(a = yield(b), c) should be enough, no extra parens > required -- no foo(a = (yield(b)), c). Right? Yes that's correct. >> Pros for yield(E): >> - backward compatible > > But for this to be true, we would need to use the direct-eval > detection hack I mentioned previously. On the plus side, this would allow for feature detection of generator support, right? (Is there any other way to detect generator support?) >> - easier to read (to my eye) >> - it "feels" more correct to me in context of the when-using-send- >> value rule > > These are subjective enough there's no point in arguing. I hear ya. Yes, one man's opinion and experience. If others chimed in claiming the opposite experience, obviously my argument would be moot. But I hope I'm providing a decent "average hacker" POV for you. >> Pros for (yield E): >> - consistent with python >> - doesn't present any is-it-a-function? ambiguities > > These are more objective (no look & feel ;-). There is a borrowing > from Python. There isn't a function call going on. Agreed. If look-and-feel weren't factors, I wouldn't have brought it up. ;) _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)2009/5/18 Brendan Eich <brendan@...>:
> > On May 18, 2009, at 2:25 AM, Igor Bukanov wrote: > >> The remedy for this is simple - the generator can be created using >> explicit call like Generator(f, arg1, ... argN). This would turn any >> function into a generator and would allow for runtime checks for eval. > > You mean yield, not eval, right? Right, that was a typo. > >> The plus side of this is that an empty generator can be created with a >> straightforward: >> >> Generator(function() {}) >> >> and not with a rather unnatural >> >> (function() { if (false) yield; })() > > No one makes empty generators. For me the problem with the way the generators are defined is that a dead code like that "if (0) yield;" affects the semantic by mere presence of it. Surely, this is not the first feature in ES that has that property - "if (0) var a;" is another example. But "if (0) yield;" sets a new record affecting the nature of the whole function. > It doesn't need more runtime > magic machinery and global constructors that are otherwise unmotivated. That is true, but then runtime-only generators allows to avoid opt-in tax for all the users. How high is that tax I do not know, but surely it prevents some user cases for the feature. Igor _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 18, 2009, at 11:53 AM, Neil Mix wrote:
>> But for this to be true, we would need to use the direct-eval >> detection hack I mentioned previously. > > On the plus side, this would allow for feature detection of > generator support, right? (Is there any other way to detect > generator support?) In JS1.7 you could object-detect: if (this.Iterator) ... or similarly. But I'm in the midst of writing up strawman:iterators proposal that doesn't add Iterator to the global object (nor any __iterator__ getter, no double underscores). One generalized idea for object detection of keywords that could be used as if they named functions in code that would be work in old browsers: if (Object.implementation && Object.implementation.supports('yield'))) { ... function gen() { ... yield(E); .... } ... } else { ... do something else ... } I'm abusing Object as ES5 does, but harder, to avoid polluting the global object. I'm supposing Object.implementation could be useful for other properties than the supports method. This reads well enough, although its a bit long-winded altogether (but individual names are short enough). Comments? /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 18, 2009, at 12:23 PM, Brendan Eich wrote: > Making them mandatory is the issue. You can derive whatever comfort > you want from 'em, but they are not required and we're not going to > start requiring them for return, delete, or typeof. So mandating > parentheses for yield is kind of wrong. Obviously the issue would go > away if the precedence where the same as delete and typeof. Hence > "kind of". Ah, but delete and typeof are different in that they both *require* an argument (terminology be damned, hopefully you understand what I mean by that.) And return is different because it can't be used in an expression. See my previous let x = yield-5; example -- let x = typeof-5; is unambiguous. I'm tempted to argue that yield should require an argument, and then you could give it precedence equivalent to delete and typeof. But that would make a statement like yield x - 1; utterly confusing. Set aside for a moment the argument of *which* form of parenthesis for a moment, and assume (yield E) wins for now. Could we redefine yield so that it has two forms, a statement form and an expression form? The statement form would be yield E; where E is optional. And the expression form would be yield E where E is required, and yield has precedence equivalent to delete and typeof. Is that possible? Doing so would render any argument about parenthesis moot, since they'd rarely be required, right? _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntax (diverging from: How would shallow generators compose with lambda?)On May 18, 2009, at 12:15 PM, Neil Mix wrote:
> Ah, but delete and typeof are different in that they both *require* > an argument (terminology be damned, hopefully you understand what I > mean by that.) And return is different because it can't be used in > an expression. See my previous let x = yield-5; example -- let x = > typeof-5; is unambiguous. > > I'm tempted to argue that yield should require an argument, and then > you could give it precedence equivalent to delete and typeof. But > that would make a statement like > > yield x - 1; > > utterly confusing. Yes; I pointed that out earlier in this thread: "But then almost any algebraic or logical expression computing the value to yield would need parentheses, and people would make mistakes such as yield a + b where they meant yield(a + b) -- as in Python -- but got yield(a) + b." But this objection applies to yield expressions in larger expressions too. > Set aside for a moment the argument of *which* form of parenthesis > for a moment, and assume (yield E) wins for now. Could we redefine > yield so that it has two forms, a statement form and an expression > form? The statement form would be > yield E; > where E is optional. And the expression form would be > yield E > where E is required, and yield has precedence equivalent to delete > and typeof. Is that possible? Doing so would render any argument > about parenthesis moot, since they'd rarely be required, right? Not clear. Using yield in a larger expression may nevertheless want to yield an expression with precedence lower than unary (delete, !, etc.) precedence. ES3 grammar: UnaryExpression : PostfixExpression delete UnaryExpression void UnaryExpression typeof UnaryExpression ++ UnaryExpression -- UnaryExpression + UnaryExpression - UnaryExpression ~ UnaryExpression ! UnaryExpression Since yield has some some similarity to return I'm still in favor of what Python did: low precedence, mandatory parenthesization of the whole yield expression in any non-statement context. JS1.7 tried to relax this, but it's not worth it as your experience says. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxBrendan Eich wrote:
> On May 17, 2009, at 6:39 PM, Neil Mix wrote: >> - we could always allow parenthesis to be dropped when the yield is >> the entire expression of an expression statement or the right-hand >> side of an assignment. > > Right-hand side of assignment is ok without parens in Python because > assignment is a statement. > > In JS if you allow assignment expressions ending in unparenthesized > yields, then you can have unparenthesized yields in argument and > initialiser lists, comma expressions, and in the middle and final > operand positions in ternary (?:) expressions. > >> - in my experience with JS 1.7 I almost always had to parenthesize the >> yield expression when it was in some other kind of expression. An in >> the cases where parenthesis weren't required, I parenthesized anyway >> to avoid ambiguity and maintain coding style consistency. (And >> because I got tired of predicting incorrectly whether or not parens >> would be required in a particular context.) > > The only contexts we allow you not to parenthesize in JS1.7 are > assignment expressions and final argument in list. But see above -- the > assignment expression loophole is big enough to allow > > foo(a = yield b, c); > > One argument, or two? *If* it is allowed, then it should be two. It would be very surprising if foo(a = b, c); had two arguments (as it does), but the above expression with yield had one. But I agree that it may be better not to allow it. >> So I would argue that there are two syntactical forms of yield, yield >> E and (yield E), and that the rules regarding the requirement for >> parenthesis are hard to predict (from personal experience). >> Therefore, I argue that it would make sense to simplify a bit: >> - the yield E form may be used when it is the entire expression of an >> expression statement >> - all other times it must be parenthesized > > Agreed; this closes the assignment expression loophole. This would disallow foo(yield x); which seems unnecessary. -- David-Sarah Hopwood ⚥ _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxIgor Bukanov wrote:
> 2009/5/18 Brendan Eich <brendan@...>: >> On May 18, 2009, at 2:25 AM, Igor Bukanov wrote: >>> The plus side of this is that an empty generator can be created with a >>> straightforward: >>> >>> Generator(function() {}) >>> >>> and not with a rather unnatural >>> >>> (function() { if (false) yield; })() >> No one makes empty generators. > > For me the problem with the way the generators are defined is that a > dead code like that "if (0) yield;" affects the semantic by mere > presence of it. Surely, this is not the first feature in ES that has > that property - "if (0) var a;" is another example. But "if (0) > yield;" sets a new record affecting the nature of the whole function. A more explicit alternative is to require some kind of decoration on the function definition, e.g. (just a straw man): function generator foo() { ... } -- David-Sarah Hopwood ⚥ _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxOn May 19, 2009, at 2:00 PM, David-Sarah Hopwood wrote:
> *If* it is allowed, then it should be two. It would be very > surprising if > > foo(a = b, c); > > had two arguments (as it does), but the above expression with yield > had one. > > But I agree that it may be better not to allow it. Good; it was a loophole in JS1.7 and up, which I think should be closed. >> Agreed; this closes the assignment expression loophole. > > This would disallow > > foo(yield x); > > which seems unnecessary. I thought so too, but Python keeps its grammar simple this way, and simpler is better, ceteris paribus. JS1.7 allows this but also suffers the assignment loophole. Getting rid of the latter but not the former is grammar-hacking busy work. I haven't done it in the WebKit/ JavaScriptCore/parser/Grammar.y. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
|
|
Re: yield syntaxOn May 19, 2009, at 2:08 PM, David-Sarah Hopwood wrote:
> A more explicit alternative is to require some kind of decoration on > the > function definition, e.g. (just a straw man): > > function generator foo() { ... } Or just (we discussed this briefly last summer in Oslo): generator foo() { ... } In JS1.7, we followed Python, which uses def, same as for defining a function, and distinguishes generators by presence of yield (which makes value returns illegal). It seems unwise to diverge from Python without more evidence of an actual usability problem. We have no such evidence from shipping JS1.7 and up in Firefox 2 and up. /be _______________________________________________ es-discuss mailing list es-discuss@... https://mail.mozilla.org/listinfo/es-discuss |
| < Prev | 1 - 2 - 3 - 4 | Next > |
| Free embeddable forum powered by Nabble | Forum Help |