Re: Existential operator (was: ||= is much needed?)
On Thu, Jun 21, 2012 at 5:55 PM, Aymeric Vitte vitteayme...@gmail.comwrote: According to my previous posts I am quite convinced it has an interest, I remain perplex regarding the use of ?( , then, I am really curious to see CS's uses, could you please highlight some projects ? Certainly. Here's a brief sampling of some of the uses. Mostly cases where function values may not exist, or cases where you're passing a very heterogenous set of objects into an API, and you're not entirely sure what methods are available, but want to look for specific things. if typeof block is 'function' then block.call(@, params) else @[block]?(params) hashKeyFor: (obj) - obj?.hashKey?() or obj callback?(err, mappedRecords, env) unless varBase.hasProperties?() callback?() return true if lhs?.isEqual?(rhs) and rhs?.isEqual?(lhs) wrapper = wrapper?(core) or wrapper ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. What's wrong with it per se? Let it be exposed, let people use it. Some of uses will be wrong, they will eventually die, some of them will be fine, they survive (no need to add keyword or API for it, null.? yields it and it is usably short). And BTW, if foo.? is too long and abuse of dot, you can use for example postfix tilde to get foo~.bar, foo.bar~(), bar in foo~ etc. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any Spec / impl overhead or memory / perf overhead? Because the latter is of little worries, common uses of foo.? like foo.?.bar can be of course shortcut without using [[NullPatternObject]] at all. Herby kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 21, 2012, at 3:22, Herby Vojčík he...@mailbox.sk wrote: Brendan Eich wrote: Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. What's wrong with it per se? Let it be exposed, let people use it. Some of uses will be wrong, they will eventually die, some of them will be fine, they survive (no need to add keyword or API for it, null.? yields it and it is usably short). And BTW, if foo.? is too long and abuse of dot, you can use for example postfix tilde to get foo~.bar, foo.bar~(), bar in foo~ etc. /be Herby Language-level support for the null object pattern would be pretty excellent! I think, given the CoffeeScript grep stats (not to mention common `options = options || {}` code), people are definitely using ? in that capacity. The possibility of introducing something elegant like this seems like exactly why getting in only property-access ?. would be a mistake. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
So do you have to do it by treating the ?. operator as a standalone? Instead, could you do the indefinte soak part during parsing, treating the rest of the expression differently after having seen a ?. operator? -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
John Tamplin wrote: So do you have to do it by treating the ?. operator as a standalone? Not sure what you mean here -- standalone ? (with an English-langauge ? implied after in your sentence? ;-)? Or something else that amounts to a concealed Reference or Nil-value-proxy expression? Just talking spec here: as Allen mentioned, ECMA-262 specifies semantics by evaluating productions in a mostly-LR(1) grammar, so member and call expressions (left-associative) have to result in some kind of (spec-internal or language-external) value. Thus foo?.bar.baz.quux is really (((foo?.bar).baz).quux). Instead, could you do the indefinte soak part during parsing, treating the rest of the expression differently after having seen a ?. operator? Indeed one can translate when parsing. CoffeeScript does this, with some separate passes for its other purposes (implicitly declared variables, indentation-based block structure, etc.). The ES specs can't do this, though, not without a total rewrite. /be -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Thus foo?.bar.baz.quux is really (((foo?.bar).baz).quux). So (as many have noted) parenthesization does not call GetValue in ECMA-262: 11.1.6 The Grouping Operator The production PrimaryExpression : ( Expression ) is evaluated as follows: 1. Return the result of evaluating Expression. This may be of type Reference. NOTE This algorithm does not apply GetValue to the result of evaluating Expression. The principal motivation for this is so that operators such as delete and typeof may be applied to parenthesised expressions /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Thu, Jun 21, 2012 at 11:23 AM, Brendan Eich bren...@mozilla.org wrote: John Tamplin wrote: So do you have to do it by treating the ?. operator as a standalone? Not sure what you mean here -- standalone ? (with an English-langauge ? implied after in your sentence? ;-)? Or something else that amounts to a concealed Reference or Nil-value-proxy expression? Just talking spec here: as Allen mentioned, ECMA-262 specifies semantics by evaluating productions in a mostly-LR(1) grammar, so member and call expressions (left-associative) have to result in some kind of (spec-internal or language-external) value. Thus foo?.bar.baz.quux is really (((foo?.bar).baz).quux). Yes, and I am suggesting during parsing it gets treated as: (((foo?.bar)?.baz)?.quux) because we saw a ?. operator earlier in the expression. That way you don't have to get the Coffeescript behavior by introducing some fake object or a MaybeReference, and you just implement the ?. operator as always returning the LHS if it is null/undef. Indeed one can translate when parsing. CoffeeScript does this, with some separate passes for its other purposes (implicitly declared variables, indentation-based block structure, etc.). The ES specs can't do this, though, not without a total rewrite. I realize it would be changes, but then so would adding a MaybeReference. Just thought I would bring it up. -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
John Tamplin wrote: On Thu, Jun 21, 2012 at 11:23 AM, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: John Tamplin wrote: So do you have to do it by treating the ?. operator as a standalone? Not sure what you mean here -- standalone ? (with an English-langauge ? implied after in your sentence? ;-)? Or something else that amounts to a concealed Reference or Nil-value-proxy expression? Just talking spec here: as Allen mentioned, ECMA-262 specifies semantics by evaluating productions in a mostly-LR(1) grammar, so member and call expressions (left-associative) have to result in some kind of (spec-internal or language-external) value. Thus foo?.bar.baz.quux is really (((foo?.bar).baz).quux). Yes, and I am suggesting during parsing it gets treated as: (((foo?.bar)?.baz)?.quux) because we saw a ?. operator earlier in the expression. Ok, but this doesn't seem observable, or necessary in the spec. That way you don't have to get the Coffeescript behavior by introducing some fake object or a MaybeReference, CoffeeScript does not introduce a fake object or MaybeReference: $ cat /tmp/soak.coffee o = null console.log(o?.p.q.r.s.t) $ ./bin/coffee -p !$ ./bin/coffee -p /tmp/soak.coffee (function() { var o; o = null; console.log(o != null ? o.p.q.r.s.t : void 0); }).call(this); Rather, ECMA-262 would need to elaborate its internal Reference type as Allen wrote. and you just implement the ?. operator as always returning the LHS if it is null/undef. Note also that CoffeeScript does not short-circuit to the unbound/null/undefined LHS value, it always uses void 0 -- AKA undefined. Indeed one can translate when parsing. CoffeeScript does this, with some separate passes for its other purposes (implicitly declared variables, indentation-based block structure, etc.). The ES specs can't do this, though, not without a total rewrite. I realize it would be changes, but then so would adding a MaybeReference. Just thought I would bring it up. Allen's right, MaybeReference is a much (much!) smaller change, especially if we want to support the ?( and suffix-? variants. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Replying to both Herby and Domenic here. Domenic Denicola wrote: On Jun 21, 2012, at 3:22, Herby Vojčíkhe...@mailbox.sk wrote: Brendan Eich wrote: Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. What's wrong with it per se? 1. The overhead, which is not wanted in almost all cases. Then saying implementations may optimize simply makes a de-facto standard with high implementation cost inevitable. We should normatively spec what CoffeeScript does -- boolean result for suffix-? or anything like it -- or else add a singleton Nil object that can be reused. 2. It's not what CoffeeScript does. 3. For foo?.bar if foo is not bound or has null or undefined value, if I understand correctly, you propose to use ({}) instead. This does not provide indefinite soak, where foo?.bar.baz.quux silently short-circuits to undefined value on unbound or ==-null foo. And if Object.prototype.bar exists, foo?.bar where foo is unbound/==-null will wrongly evaluate to Object.prototype.bar's value. 4. Likewise foo?(bar) or however it might be spelled will try to invoke an empty fresh object, throwing a TypeError -- not what we want. 5. if (foo.?) as Herby proposed evaluates to a truthy fresh object if foo is unbound or has ==-null value. CoffeeScript and any sane interpretation of suffix-? or variant spelling wants falsy if not false result for unbound/==-null foo. These are problems _per se_. But see below on the Nil singleton idea. Let it be exposed, let people use it. Some of uses will be wrong, they will eventually die, some of them will be fine, they survive (no need to add keyword or API for it, null.? yields it and it is usably short). And BTW, if foo.? is too long and abuse of dot, you can use for example postfix tilde to get foo~.bar, foo.bar~(), bar in foo~ etc. /be Herby Language-level support for the null object pattern would be pretty excellent! Depends on what you mean by null object. I don't believe anyone wants a fresh empty object for each ? ?. ?( or however we spell the variants. There's no evidence for this from CoffeeScript. A fresh object as default value breaks indefinite soak and may expose proto-properties (3), breaks the ?( call variant (4), and breaks boolean tests of suffix-? expressions (5), as far as I can tell. I think, given the CoffeeScript grep stats (not to mention common `options = options || {}` code), people are definitely using ? in that capacity. Sure, no one argues otherwise. The minority use-cases could wait, but we should discuss them before deferring. Agree with all that. But a Null object meaning fresh empty object is no solution, per (1-5) above. The possibility of introducing something elegant like this seems like exactly why getting in only property-access ?. would be a mistake. What is elegant may be something you haven't actually described: a Nil singleton, a proxy actually, which can soak up indefinite gets, sets, and calls. It must be a singleton to avoid the overhead problem. Adn that is precisely what I proposed under name [[NullPatternObject]]. So all of (1), (3), (4) and (5) are void. This Nil proxy would take the place of the concealed Reference type that Allen suggested. It has some appeal to fans of Smalltalk who message nil. Smalltalk nil is a bit different from Null Pattern. I proposed Null pattern (optimized off when not actually needed in the equation, but exposed when needed). Such a Nil proxy still cannot masquerade as false, though, and that is required for suffix-? testing. An object that can convert to false awaits value objects (http://wiki.ecmascript.org/doku.php?id=strawman:value_objects) married with proxies to make value proxies. Such a [[NullPattternObject]] can ToBoolean to false. No problem I see. I've argued in the past against coupling proposals and chaining risk of non-acceptance, so I don't think the existential operator and variants should depend on such a Nil proxy singleton idea. Happy to discuss it more, but as a practical matter I would want it concealed in http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator and exposed only in a separate proposal, once we have value objects and value proxies (assuming we get them). /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Herby Vojčík wrote: Adn that is precisely what I proposed under name [[NullPatternObject]]. So all of (1), (3), (4) and (5) are void. Apologies, I missed that and saw only someone (perhaps it was Domenic) write ({}) as the default value, which is not the same. Such a Nil proxy still cannot masquerade as false, though, and that is required for suffix-? testing. An object that can convert to false awaits value objects (http://wiki.ecmascript.org/doku.php?id=strawman:value_objects) married with proxies to make value proxies. Such a [[NullPattternObject]] can ToBoolean to false. No problem I see. You're right we could hardcode a special case in ToBoolean ahead of value objects. To prevent this object from escaping into the language, we would need a special case in GetValue too. That makes this equvalent to Allen's conditional Reference (MaybeReference). Or were you thinking of letting this magic singleton esape into the language? If so, I think you'll get serious push-back on TC39. Escaping raises the ante quite a bit. We have to be sure a falsy object won't confuse some code (SES code in particular) in a way that could lead to an exploit. Apart from SES-focused concerns, letting the magic reference-like type escape exposes something ahead of schedule, before value objects in particular. If there's no need to let this thing escape, then we sholudn't. And in that case it's equivalent to MaybeReference. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Herby Vojčík wrote: Adn that is precisely what I proposed under name [[NullPatternObject]]. So all of (1), (3), (4) and (5) are void. Apologies, I missed that and saw only someone (perhaps it was Domenic) write ({}) as the default value, which is not the same. Such a Nil proxy still cannot masquerade as false, though, and that is required for suffix-? testing. An object that can convert to false awaits value objects (http://wiki.ecmascript.org/doku.php?id=strawman:value_objects) married with proxies to make value proxies. Such a [[NullPattternObject]] can ToBoolean to false. No problem I see. You're right we could hardcode a special case in ToBoolean ahead of value objects. To prevent this object from escaping into the language, we would need a special case in GetValue too. That makes this equvalent to Allen's conditional Reference (MaybeReference). Or were you thinking of letting this magic singleton esape into the language? Definitely. It brings all pros of Null Pattern there (all of the uses I included in previous posts, automatically and consistently). When it is explicit, users can begin to use it willingly. It may bring previously hard-to-get solutions. If so, I think you'll get serious push-back on TC39. Escaping raises the ante quite a bit. We have to be sure a falsy object won't confuse some code (SES code in particular) in a way that could lead to an exploit. That I cannot envision... but Null Pattern object that produces itself for all operations ([[Get]], [[Call]], ...) should not be problematic. Apart from SES-focused concerns, letting the magic reference-like type escape exposes something ahead of schedule, before value objects in particular. If there's no need to let this thing escape, then we sholudn't. And in that case it's equivalent to MaybeReference. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Herby Vojčík wrote: That I cannot envision... but Null Pattern object that produces itself for all operations ([[Get]], [[Call]], ...) should not be problematic. You might be surprised (I am) by how seemingly innocent things can become problematic. Just on aesthetic grounds, I bet TC39ers will react to this the way we react to document.all that masquerades as undefined. BTW, Pattern and Null are both not good words to join to name this thing. A pattern matching strawman exists, wherein patterns are special forms, built from destructuring patterns, used in certain syntactic forms but not first-class objects. And Null is to close to null and the ECMA-262 internal Null type. As a Unix hacker I can dig the /dev/null reference, if there is one, but it's too far afield. I do think Smalltalk's nil, even though not identical, suggests a better name. If we were to expose this singleton, we could do worse than call it something the Nil object. But I'm not sold on exposing it. Allen (and Mark if he has time) should weigh in. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Herby Vojčík wrote: That I cannot envision... but Null Pattern object that produces itself for all operations ([[Get]], [[Call]], ...) should not be problematic. You might be surprised (I am) by how seemingly innocent things can become problematic. Just on aesthetic grounds, I bet TC39ers will react to this the way we react to document.all that masquerades as undefined. BTW, Pattern and Null are both not good words to join to name this I just named it on the grounds of the (non-GoF) design pattern which is called Null Object or Null Pattern, if I am not mistaken. But of course naming is not that important. thing. A pattern matching strawman exists, wherein patterns are special forms, built from destructuring patterns, used in certain syntactic forms but not first-class objects. And Null is to close to null and the ECMA-262 internal Null type. As a Unix hacker I can dig the /dev/null reference, if there is one, but it's too far afield. I do think Smalltalk's nil, even though not identical, suggests a better name. If we were to expose this singleton, we could do worse than call it something the Nil object. But I'm not sold on exposing it. Allen (and Mark if he has time) should weigh in. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
I guess the grep work is not easy to do, but I have tried (manually) to find ?. or ?( in coffee script projects, trying to seek into projects of main contributors. Maybe not lucky or not really aware of the most popular projects, but I did not find any up to now. According to my previous posts I am quite convinced it has an interest, I remain perplex regarding the use of ?( , then, I am really curious to see CS's uses, could you please highlight some projects ? Le 21/06/2012 05:54, Jeremy Ashkenas a écrit : As requested, running those rough greps again on the top ten most popular CoffeeScript repos on Github yields: 188 uses of object?.property 32 uses of object?[key] 50 uses of function?(args) 46 uses of variable ?= value ... and the other ones are a bit tricker to grep for. There are at least a handful more uses of the `function?(args)` style but with implicit parentheses: `function? arg1, arg2` ... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 20, 2012, at 7:18 AM, John Tamplin wrote: On Tue, Jun 19, 2012 at 1:34 PM, Jeremy Ashkenas jashke...@gmail.com wrote: Allen asks about when you would want to write `foo?.bar()` ... the only use case I can think of is when `foo` may or may not be defined, and you know that if it *is* defined, it's going to have a `bar` method on it, and if it *is* defined, you want to call `bar` for its side effects. A bit far fetched. It doesn't seem that far-fetched to me -- I seem to constantly write things like this in Java: String name = (person != null) ? person.getName() : null; IIUC, that could just be written as String name = person?.getName() if this operator were avaialble. Maybe you are saying that you don't want to have rigid class structures in JS, but it seems reasonable that if you know person is of type Person it is supposed to have a getName method on it. yes, but in a static Java-like language such as for you example above, the existence of person implies the existence of the getName method. The JS equivalent would likely be something like: name = (person person.getName) ? person.getName() : undefined; using ?. as defined by Brendan this could be: name = (person?.getName) ? person.getName( ) : undefined; I've been arguing that ?. and () could be defined such that the above statement could instead be reduced to: name = person?.getName(); However, by Brendan's semantics this reduced form would be equivalent to: name = (person person.getName) ? person.getName() : throw new TypeError; I was hypothesizing that Brendan's semantics would seldom be the programer's intent for person?.getName() . If an exception was acceptable, why wouldn't you just say: name = person.getName(); Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: I was hypothesizing that Brendan's semantics would seldom be the programer's intent for person?.getName() . If an exception was acceptable, why wouldn't you just say: Because it's rare to have a maybe-method called on a maybe-object, based on CoffeeScript experience and design. Please don't personalize this -- I wrote the strawman to capture what CoffeeScript has user-tested. Any bugs are mine, but they're also not (necessarily) intended. Clearly I did not push the indefinite-null/undefined-soak semantics. That's in CoffeeScript. However, it does not suppress throwing on a call of a non-callable: $ cat /tmp/y.coffee person = {} person?.getName() $ ./bin/coffee -p /tmp/y.coffee (function() { var person; person = {}; if (person != null) { person.getName(); } }).call(this); $ ./bin/coffee /tmp/y.coffee TypeError: Object #Object has no method 'getName' at Object.anonymous (/private/tmp/y.coffee:7:12) at Object.anonymous (/private/tmp/y.coffee:10:4) at Module._compile (module.js:432:26) at Object.run (/Users/brendaneich/Hacking/coffee-script/lib/coffee-script/coffee-script.js:79:25) at /Users/brendaneich/Hacking/coffee-script/lib/coffee-script/command.js:175:29 at /Users/brendaneich/Hacking/coffee-script/lib/coffee-script/command.js:150:18 at [object Object].anonymous (fs.js:114:5) at [object Object].emit (events.js:64:17) at afterRead (fs.js:1081:12) at Object.wrapper [as oncomplete] (fs.js:252:17) Let's look at what CoffeeScript requires to avoid this exception: $ cat /tmp/z.coffee person = {} person?.getName?() $ ./bin/coffee -p /tmp/z.coffee (function() { var person; person = {}; if (person != null) { if (typeof person.getName === function) { person.getName(); } } }).call(this); $ ./bin/coffee /tmp/z.coffee echo no throw no throw Again, I do not see the point in gratuitously differing from CoffeeScript without reason. One might argue that since we cannot use ?( as CS does, we should make ?. soak up call TypeErrors. Could be, but I didn't propose anything for call yet and this discussion seems worth beating into the ground a bit more before I do :-). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 20, 2012, at 10:45 AM, Brendan Eich wrote: Allen Wirfs-Brock wrote: I was hypothesizing that Brendan's semantics would seldom be the programer's intent for person?.getName() . If an exception was acceptable, why wouldn't you just say: Because it's rare to have a maybe-method called on a maybe-object, based on CoffeeScript experience and design. Please don't personalize this -- I wrote the strawman to capture what CoffeeScript has user-tested. Any bugs are mine, but they're also not (necessarily) intended. nothing personal intended, just a sloppy way to refer to your strawman. ... Again, I do not see the point in gratuitously differing from CoffeeScript without reason. One might argue that since we cannot use ?( as CS does, we should make ?. soak up call TypeErrors. Could be, but I didn't propose anything for call yet and this discussion seems worth beating into the ground a bit more before I do :-). yes, that's what I was proposing. I think calls need to be part of the overall discussion for this feature area. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Let's look at what CoffeeScript requires to avoid this exception: $ cat /tmp/z.coffee person = {} person?.getName?() $ ./bin/coffee -p /tmp/z.coffee (function() { var person; person = {}; if (person != null) { if (typeof person.getName === function) { person.getName(); } } }).call(this); $ ./bin/coffee /tmp/z.coffee echo no throw no throw But of course, to the point that it's rare to have a maybe-method called on a maybe-object, the minimum required by CoffeeScript here is just: $ cat /tmp/z.coffee person = {} person.getName?() $ ./bin/coffee -p /tmp/z.coffee (function() { var person; person = {}; if (typeof person.getName === function) { person.getName(); } }).call(this); $ ./bin/coffee /tmp/z.coffee echo no throw no throw /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: yes, that's what I was proposing. I think calls need to be part of the overall discussion for this feature area. Jeremy is kindly grepping more codebases, but just from CoffeeScript (self-hosted) source itself, ?. is 42, ?[ is 7, and ?( is 3 -- so 12:2:1. Supports deferring ?( for now given syntax issue, but the counter-argument is that we might solve syntax holistically a different way. One idea: foo.?bar instead of foo?.bar which enables foo(? args ) instead of foo?( args ) and implies foo[? index ] This is infelicitous compared to putting ? first because it separates the ? from the maybe-nully left operand too much, and looks ugly (to Spanish readers it looks even more wrong). The other idea mooted: foo?:( args ) runs into the X ?: Y problem -- that should mean X ? X : Y per GNU C and intuition, but the : in the middle of ?:( doesn't mean any such thing. My super-flammable straw syntax of foo?.(args) has a similarly inapt dot in the middle. Suggestions welcome. If we must get maybe-call in or at least future-proof the syntax for it a bit, now is the time. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Wed, Jun 20, 2012 at 12:47 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: yes, but in a static Java-like language such as for you example above, the existence of person implies the existence of the getName method. The JS equivalent would likely be something like: Is it really rare to write JS code that assumes objects passed to it have an expected structure? Obviously, you don't have to, but when I have seen object-oriented code written in JS it tends to make such assumptions. If I write something that takes either null or a person object, I assume if it isn't null it really is a person object and I don't write checks to verify it. If someone passes something that doesn't have getName on it to my method, I am perfectly fine with it blowing up. When I expect that it might be null/undefined, then I have to write a bunch of boilerplate to deal with that, and ?. allows removing that boilerplate. -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: This is infelicitous compared to putting ? first because it separates the ? from the maybe-nully left operand too much, and looks ugly (to Spanish readers it looks even more wrong). It's also a loss to deviate from CS, but we can't do ?( so we're half (or 1/14th by the CoffeeScript usage-grep stats) deviated. And putting ? after ( is future-hostile to any ?-unary-prefix operator, but I believe the only viable such prospective syntax is in patterns (destructuring on steroids), so not after a ( that starts an argument list. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Allen Wirfs-Brock wrote: yes, that's what I was proposing. I think calls need to be part of the overall discussion for this feature area. Jeremy is kindly grepping more codebases, but just from CoffeeScript (self-hosted) source itself, ?. is 42, ?[ is 7, and ?( is 3 -- so 12:2:1. Supports deferring ?( for now given syntax issue, but the counter-argument is that we might solve syntax holistically a different way. One idea: foo.?bar instead of foo?.bar which enables foo(? args ) instead of foo?( args ) and implies foo[? index ] This is infelicitous compared to putting ? first because it separates the ? from the maybe-nully left operand too much, and looks ugly (to Spanish readers it looks even more wrong). Let's allow foo.? to denote soft foo, so you get: foo.?.bar // foo == null ? undefined : foo.bar foo.?(bar) // foo == null ? undefined : foo(bar) foo.?[bar] // foo == null ? undefined : foo[bar] but maybe also more esoteric uses, like: for (let key in foo.?) // for (let key in (foo == null ? {} : foo)) foo.? // foo == null ? undefined : foo // sort-of clearing foo.? = bar // foo == null ? undefined : (foo = bar) // this semantics is logical, just don't know // what would be the use case... foo.?.baz = bar // foo == null ? undefined : (foo.baz = bar) // this is usable ... foo.? ... Herby The other idea mooted: foo?:( args ) runs into the X ?: Y problem -- that should mean X ? X : Y per GNU C and intuition, but the : in the middle of ?:( doesn't mean any such thing. My super-flammable straw syntax of foo?.(args) has a similarly inapt dot in the middle. Suggestions welcome. If we must get maybe-call in or at least future-proof the syntax for it a bit, now is the time. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Herby Vojčík wrote: Let's allow foo.? to denote soft foo, so you get: foo.?.bar// foo == null ? undefined : foo.bar foo.?(bar)// foo == null ? undefined : foo(bar) foo.?[bar]// foo == null ? undefined : foo[bar] ?. works as well for these and the main (by use-frequency, so far) form matches CS. If we must have extra dots in the lesser-used forms, I'd put the dot in the middle to keep the question-mark on the left. but maybe also more esoteric uses, like: for (let key in foo.?)// for (let key in (foo == null ? {} : foo)) That is even more of an abuse of dot, and it does not play well with ?: ternaries and the proposed ?? operator. foo.??bar:baz would be legal by maximal munch, parsed as (foo.?)?bar:baz. Beyond this objection, the need for foo.? instead of foo != null is not strong. Worse, you show magic defaulting to {} in the for-in case, but the default result for anything like a suffix-? expression in CS is a boolean boolean result: $ cat /tmp/w.coffee lhs = foo? $ ./bin/coffee -p /tmp/w.coffee (function() { var lhs; lhs = typeof foo !== undefined foo !== null; }).call(this); foo.?// foo == null ? undefined : foo // sort-of clearing See above. foo.? = bar// foo == null ? undefined : (foo = bar) // this semantics is logical, just don't know // what would be the use case... foo.?.baz = bar// foo == null ? undefined : (foo.baz = bar) // this is usable These don't win over ?. in the proposal. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Herby Vojčík wrote: Let's allow foo.? to denote soft foo, so you get: foo.?.bar // foo == null ? undefined : foo.bar foo.?(bar) // foo == null ? undefined : foo(bar) foo.?[bar] // foo == null ? undefined : foo[bar] ?. works as well for these and the main (by use-frequency, so far) form matches CS. If we must have extra dots in the lesser-used forms, I'd put the dot in the middle to keep the question-mark on the left. but maybe also more esoteric uses, like: for (let key in foo.?) // for (let key in (foo == null ? {} : foo)) That is even more of an abuse of dot, and it does not play well with ?: ternaries and the proposed ?? operator. This is usable case. It is not nice to test whether I can use for-in. foo.??bar:baz would be legal by maximal munch, parsed as (foo.?)?bar:baz. C'est la vie. :-) Well, this is something that can be though of, later. I would not put it away because of this edge case (which is just strange, but not incorrect). Beyond this objection, the need for foo.? instead of foo != null is not strong. Worse, you show magic defaulting to {} in the for-in case, but the Well, I though of Object.keys(foo.?) and saw the {} case (or something similar) is in fact a very good case. It can be used for foo.? uniformly (I'll denote the object [[NPO]] as the short for [[NullPatternObject]]: foo.?.bar // (foo == null ? [[NPO]] : foo).bar // [[NPO]] returns [[NPO]] from [[Get]] foo.?(bar) // (foo == null ? [[NPO]] : foo)(bar) // [[NPO]] does nothing when [[Call]], // returns [[NPO]] foo.?[bar] // (foo == null ? [[NPO]] : foo)[bar] // [[NPO]] returns [[NPO]] from [[Get]] for (let key in foo.?) // for (let key in (foo == null ? [[NPO]] : foo)) // [[NPO]] enumerates no keys Object.keys(foo.?) // Object.keys(foo == null ? [[NPO]] : foo) // [[NPO]] has empty key list foo.? // foo == null ? [[NPO]] : foo // [[NPO]] if false if ToBoolean, == null, // == undefined, === [[NPO]], !== undefined, // !== null foo.?.baz = bar // (foo == null ? [[NPO]] : foo).baz = bar // [[NPO]] does nothing when [[Put]] I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. default result for anything like a suffix-? expression in CS is a boolean boolean result: $ cat /tmp/w.coffee lhs = foo? $ ./bin/coffee -p /tmp/w.coffee (function() { var lhs; lhs = typeof foo !== undefined foo !== null; }).call(this); foo.? // foo == null ? undefined : foo // sort-of clearing See above. foo.? = bar // foo == null ? undefined : (foo = bar) // this semantics is logical, just don't know // what would be the use case... foo.?.baz = bar // foo == null ? undefined : (foo.baz = bar) // this is usable These don't win over ?. in the proposal. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Herby Vojčík wrote: I feel there is objection to introduce magical [[NullPatternObject]] into language, but all of CS-style soft-accesses could be solved very cleanly and consistently. No, because (a) the overhead of a new object is too high; (b) with any kind of suffix-? or suffix-.? as you proposed it would be observable that you get a new object instead of short-circuiting to undefined -- the new object is exposed in the language. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
As requested, running those rough greps again on the top ten most popular CoffeeScript repos on Github yields: 188 uses of object?.property 32 uses of object?[key] 50 uses of function?(args) 46 uses of variable ?= value ... and the other ones are a bit tricker to grep for. There are at least a handful more uses of the `function?(args)` style but with implicit parentheses: `function? arg1, arg2` ... ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: This proposal augments the default operator http://wiki.ecmascript.org/doku.php?id=strawman:default_operator by adding syntax to avoid accessing a missing property, specifically |?.| for getting and setting a property from a reference base that might be |undefined| or |null|: [1] The specified semantics of proposal actually does more than avoid accessing a missing property. It also avoids accessing a property of a /missing object. For example,/ / / function f() { var foo; //oops, I forgot to write the initializer expression return foo?.bar;//returns undefined because foo evaluates to undefined. foo.bar would throw } This seems slightly and possibly significantly different from a situation like: function f(foo={ }) { return foo?.bar;//returns value of foo.bar or undefined if property bar does not exist, just like foo.bar } I can't tell if you love it or hate it :-P. Seriously, are you objecting to the reference to the default operator? I can take that out. Adopting CoffeeScript's ?. operator is indeed what I'm proposing. Not because of CoffeeScript or anything magical or any argument from authority. Rather, because it has been user-tested there, in a language with JS's runtime semantics (no change to runtime semantics in CS -- it's just syntax), and found to be good. In particular, it has the affect of possibly propagating the detection of a simple editorial error like a forgotten initializer further from its place of occurrence. Yes, that's why it's not the default behavior of ., revised incompatibly as Aymeric mooted. As an opt-in for writing optional objects or maybe-typed chained expressions, it has its proper uses. At the least, this behavior probably should be clarified in the description Will do, I revised the semantics but not the leading blurb. The inability to use ?. meaningfully in a function call context would seem to make this a only half useful feature. I suspect many people will initially try to write something like foo?.bar() with the expectation that the call will be skipped if bar doesn't exist. That's where CoffeeScript provides foo.bar?(), but of course we can't make that syntax work. I've tried. An ad-hoc backtracking hack is elusive. GLR is not going to fly. With these changes, the following would evaluate to undefined: var foo ={}, foo2; foo?.bar() but foo.bar(); would throw. This misplaces the ?. and deviates from CoffeeScript. Writing foo?.bar() means try to get bar from foo but if foo cannot coerce to object, short-circuit to result in *undefined*. The ?. replaces . and means get or set, depending on whether the IdentifierName after the ?. is the last component in an lvalue (followe by an =), or part of an rvalue (including an lvalue's base). The reason CoffeeScript offers ?( as well as ?. is precisely because, given a maybe-null-or-undefined foo.bar, you can not only further ?. your way to a baz and fail soft with undefined -- you might also want to try to invoke foo.bar as a method and fail soft if it is not invocable (typeof foo.bar != function). This works for an unqualified identifier foo, too: $ cat /tmp/x.coffee f = null f?() $ ./bin/coffee -p /tmp/x.coffee (function() { var f; f = null; if (typeof f === function) { f(); } }).call(this); The basis case of this induction is an unqualified identifier, not something like foo.bar with a dot or question-dot in it. This shows that ?. is not sufficient to avoid a TypeError attempting to invoke a maybe-function. A variant such as ?( is needed after the unqualified identifier. Alas, we can't use CoffeeScript's nice spelling, and I don't see another good way to spell it. However, I believe (survey needed) that the ?( variant is much less used than ?. in practice. Cc'ing Jeremy. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
What about a more generic operator that would be able to silently absorb any error? let greedy = obj.hints?.greedy; would become: let greedy = silent obj.hints.greedy; The semantic would be exactly the same. The syntax is up to debate. Specifically, it would be nice to be able to silence a part of an expression. What about a 'try' without a catch? let greedy = try obj.hints.greedy let greedy = try{ obj.hints.greedy } || 22; This is currently forbidden (I think for 2 reasons, one being that a try must be followed by a catch or finally and the other that try/catch cannot be used as expressions) This idea is partly inspired by typeof which silences ReferenceErrors, which I see as a feature YMMV. It is also intended to make programs potentially more robust more easily. For instance, JSON.stringify can throw errors in the rare case of cyclic references. But very few people know that. To make a robust program using JSON.stringify, one would just need to turn: let s = JSON.stringify(o) into let s = try{ JSON.stringify(o) } || DEFAULT_VALUE; instead of the current: let s; try{ s = JSON.stringify(o) } catch(e){ // I don't care about the error anyway s = DEFAULT_VALUE; } David Le 18/06/2012 07:11, Brendan Eich a écrit : Sorry, meant to start a new thread for: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator As the Syntax section hints, we can't also adopt CoffeeScript's ?( variant, which enables foo.bar?(args, go, here).baz and the like. The C syntax heritage prevails. /be Brendan Eich wrote: David Herman wrote: On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a please default sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined. Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) *or* has a value not coercible to object type (null or undefined). See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
As there is no keyword as 'or' so far, does something like *x = x.value or 5 *sound better? On Tue, Jun 19, 2012 at 3:00 PM, David Bruant bruan...@gmail.com wrote: What about a more generic operator that would be able to silently absorb any error? let greedy = obj.hints?.greedy; would become: let greedy = silent obj.hints.greedy; The semantic would be exactly the same. The syntax is up to debate. Specifically, it would be nice to be able to silence a part of an expression. What about a 'try' without a catch? let greedy = try obj.hints.greedy let greedy = try{ obj.hints.greedy } || 22; This is currently forbidden (I think for 2 reasons, one being that a try must be followed by a catch or finally and the other that try/catch cannot be used as expressions) This idea is partly inspired by typeof which silences ReferenceErrors, which I see as a feature YMMV. It is also intended to make programs potentially more robust more easily. For instance, JSON.stringify can throw errors in the rare case of cyclic references. But very few people know that. To make a robust program using JSON.stringify, one would just need to turn: let s = JSON.stringify(o) into let s = try{ JSON.stringify(o) } || DEFAULT_VALUE; instead of the current: let s; try{ s = JSON.stringify(o) } catch(e){ // I don't care about the error anyway s = DEFAULT_VALUE; } David Le 18/06/2012 07:11, Brendan Eich a écrit : Sorry, meant to start a new thread for: http://wiki.ecmascript.org/**doku.php?id=strawman:**existential_operatorhttp://wiki.ecmascript.org/doku.php?id=strawman:existential_operator As the Syntax section hints, we can't also adopt CoffeeScript's ?( variant, which enables foo.bar?(args, go, here).baz and the like. The C syntax heritage prevails. /be Brendan Eich wrote: David Herman wrote: On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.commailto: dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a please default sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined. Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) *or* has a value not coercible to object type (null or undefined). See http://wiki.ecmascript.org/**doku.php?id=strawman:**existential_operatorhttp://wiki.ecmascript.org/doku.php?id=strawman:existential_operator /be __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss __**_ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/**listinfo/es-discusshttps://mail.mozilla.org/listinfo/es-discuss -- *'I am what I am because of who we all are'* h3manth.com http://www.h3manth.com *-- Hemanth HM * ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 12:44 AM, Brendan Eich wrote: Allen Wirfs-Brock wrote: This proposal augments the default operator http://wiki.ecmascript.org/doku.php?id=strawman:default_operator by adding syntax to avoid accessing a missing property, specifically |?.| for getting and setting a property from a reference base that might be |undefined| or |null|: [1] The specified semantics of proposal actually does more than avoid accessing a missing property. It also avoids accessing a property of a /missing object. For example,/ / / function f() { var foo; //oops, I forgot to write the initializer expression return foo?.bar;//returns undefined because foo evaluates to undefined. foo.bar would throw } This seems slightly and possibly significantly different from a situation like: function f(foo={ }) { return foo?.bar;//returns value of foo.bar or undefined if property bar does not exist, just like foo.bar } I can't tell if you love it or hate it :-P. Seriously, are you objecting to the reference to the default operator? I can take that out. I can't tell either. What I'm concerned about above is the first object reference in a chain of existential operators. I was trying to illustrate a possible issue with your semantics when the existence of a property is conditional but the object that would have the property is expected to exist. For example when foo?.bar is intended to only be conditional on the existence of property bar and not on the existence of an object value of foo. It's all a matter of user intent. Are they thinking access bar if it exists in foo or are they thinking access foo.bar if it exists. Errors such as the missing initializer in my example will be obscured when users are thinking the first way. This is probably an area where feedback from CoffeeScript usage would be informative. We've heard thatCoffeeScript developer have found ?. to have high utility. I haven't heard anything about possible negative experiences, for example ones such as I'm talking about above. Is this because, in practice, it isn't a problem. Or perhaps nobody has spoken up. So I'm asking. CoffeeScript users: has use of ?. created any problems for you? Adopting CoffeeScript's ?. operator is indeed what I'm proposing. Not because of CoffeeScript or anything magical or any argument from authority. Rather, because it has been user-tested there, in a language with JS's runtime semantics (no change to runtime semantics in CS -- it's just syntax), and found to be good. More below, but an issue may be ?. without .() and that combination has not yet been tested and found to be good. In particular, it has the affect of possibly propagating the detection of a simple editorial error like a forgotten initializer further from its place of occurrence. Yes, that's why it's not the default behavior of ., revised incompatibly as Aymeric mooted. As an opt-in for writing optional objects or maybe-typed chained expressions, it has its proper uses. No doubt, but as I'm been trying to express it may also present a hazard. I'm just trying to understand the nature and severity of the hazard and to explore whether there are possible mitigations. At the least, this behavior probably should be clarified in the description Will do, I revised the semantics but not the leading blurb. The inability to use ?. meaningfully in a function call context would seem to make this a only half useful feature. I suspect many people will initially try to write something like foo?.bar() with the expectation that the call will be skipped if bar doesn't exist. That's where CoffeeScript provides foo.bar?(), but of course we can't make that syntax work. I've tried. An ad-hoc backtracking hack is elusive. GLR is not going to fly. And I'm not suggesting such a syntactic solution. I am suggesting that there is a forward value propagation semantics that would have the desired behavior. With these changes, the following would evaluate to undefined: var foo ={}, foo2; foo?.bar() but foo.bar(); would throw. This misplaces the ?. and deviates from CoffeeScript. Writing foo?.bar() means try to get bar from foo but if foo cannot coerce to object, short-circuit to result in *undefined*. The ?. replaces . and means get or set, depending on whether the IdentifierName after the ?. is the last component in an lvalue (followe by an =), or part of an rvalue (including an lvalue's base). You've already deviated from CoffeeScript by not having ?(). Some of the cow paths are now a dead-end, so you need to look at where the cows were going rather than how they got there. When would anybody every write: foo?.bar() and want the call to throw? If that was what they wanted why not say: foo.bar() My proposal may be different from CoffeeScript, but it would seem to exactly reflect
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: On Jun 19, 2012, at 12:44 AM, Brendan Eich wrote: Allen Wirfs-Brock wrote: This proposal augments the default operatorhttp://wiki.ecmascript.org/doku.php?id=strawman:default_operator by adding syntax to avoid accessing a missing property, specifically |?.| for getting and setting a property from a reference base that might be |undefined| or |null|: [1] The specified semantics of proposal actually does more than avoid accessing a missing property. It also avoids accessing a property of a /missing object. For example,/ / / function f() { var foo; //oops, I forgot to write the initializer expression return foo?.bar;//returns undefined because foo evaluates to undefined. foo.bar would throw } This seems slightly and possibly significantly different from a situation like: function f(foo={ }) { return foo?.bar;//returns value of foo.bar or undefined if property bar does not exist, just like foo.bar } I can't tell if you love it or hate it :-P. Seriously, are you objecting to the reference to the default operator? I can take that out. I can't tell either. What I'm concerned about above is the first object reference in a chain of existential operators. I was trying to illustrate a possible issue with your semantics when the existence of a property is conditional but the object that would have the property is expected to exist. For example when foo?.bar is intended to only be conditional on the existence of property bar and not on the existence of an object value of foo. It's all a matter of user intent. Are they thinking access bar if it exists in foo or are they thinking access foo.bar if it exists. Errors such as the missing initializer in my example will be obscured when users are thinking the first way. This is probably an area where feedback from CoffeeScript usage would be informative. We've heard thatCoffeeScript developer have found ?. to have high utility. I haven't heard anything about possible negative experiences, for example ones such as I'm talking about above. Is this because, in practice, it isn't a problem. Or perhaps nobody has spoken up. So I'm asking. CoffeeScript users: has use of ?. created any problems for you? Adopting CoffeeScript's ?. operator is indeed what I'm proposing. Not because of CoffeeScript or anything magical or any argument from authority. Rather, because it has been user-tested there, in a language with JS's runtime semantics (no change to runtime semantics in CS -- it's just syntax), and found to be good. More below, but an issue may be ?. without .() and that combination has not yet been tested and found to be good. In particular, it has the affect of possibly propagating the detection of a simple editorial error like a forgotten initializer further from its place of occurrence. Yes, that's why it's not the default behavior of ., revised incompatibly as Aymeric mooted. As an opt-in for writing optional objects or maybe-typed chained expressions, it has its proper uses. No doubt, but as I'm been trying to express it may also present a hazard. I'm just trying to understand the nature and severity of the hazard and to explore whether there are possible mitigations. At the least, this behavior probably should be clarified in the description Will do, I revised the semantics but not the leading blurb. The inability to use ?. meaningfully in a function call context would seem to make this a only half useful feature. I suspect many people will initially try to write something like foo?.bar() with the expectation that the call will be skipped if bar doesn't exist. That's where CoffeeScript provides foo.bar?(), but of course we can't make that syntax work. I've tried. An ad-hoc backtracking hack is elusive. GLR is not going to fly. And I'm not suggesting such a syntactic solution. I am suggesting that there is a forward value propagation semantics that would have the desired behavior. With these changes, the following would evaluate to undefined: var foo ={}, foo2; foo?.bar() but foo.bar(); would throw. This misplaces the ?. and deviates from CoffeeScript. Writing foo?.bar() means try to get bar from foo but if foo cannot coerce to object, short-circuit to result in *undefined*. The ?. replaces . and means get or set, depending on whether the IdentifierName after the ?. is the last component in an lvalue (followe by an =), or part of an rvalue (including an lvalue's base). You've already deviated from CoffeeScript by not having ?(). Some of the cow paths are now a dead-end, so you need to look at where the cows were going rather than how they got there. When would anybody every write: foo?.bar() and want the call to throw? If that was what they wanted why not say: foo.bar() My proposal may be different from CoffeeScript, but it would seem to exactly reflect what a programmer is likely to want
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 2:30 AM, David Bruant wrote: What about a more generic operator that would be able to silently absorb any error? let greedy = obj.hints?.greedy; would become: let greedy = silent obj.hints.greedy; A hazard with this approach is that it could silence a broader range of errors than the programmer intended. In the above example, the programmer's intent is probably just to not try to access greedy if hints doesn't exist. However, if greedy is an accessor property that throws your silent operator would also mask that throw (while ?. would not). It isn't clear that this would be desirable if the throw is an unexpected behavior. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
David Bruant wrote: What about a more generic operator that would be able to silently absorb any error? let greedy = obj.hints?.greedy; would become: let greedy = silent obj.hints.greedy; Ignoring exact syntax, I don't think we want more general throwing suppression. The goal with existential operators is to suppress exactly the TypeError thrown when trying to get properties from null or undefined. Suppressing errors requires care, that's why ?. is not . (the default). But even with opt-in, exceptional-circumstances syntax, we should prefer a narrower semantics to an over-broad one that will, all else equal, tend to hide bugs and fail to express precise programmer intention. The other point I will make is that we should take the CoffeeScript user testing results to heart, moreso than thought experiments. In this light I invite all CS users to comment. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: I still stand by my alternative semantics as being a way to address the more important use case without have ?() No, the basis cases differ and that is a bug in your alternative. foo?.bar means take bar from foo or undefined if foo == null. foo?.bar() means take bar from foo and throw if foo == null else try to invoke the result if typeof function, else undefined. This is an off-by-one bug. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Allen Wirfs-Brock wrote: I still stand by my alternative semantics as being a way to address the more important use case without have ?() No, the basis cases differ and that is a bug in your alternative. foo?.bar means take bar from foo or undefined if foo == null. foo?.bar() means take bar from foo and throw if foo == null else try to invoke the result if typeof function, else undefined. This is an off-by-one bug. It also uses ?. to mean . and magically applies the ? to the later (). Or if the semantics suppresses a TypeError both for the take bar and invoke it parts, then it's mixing two things in one under syntax located in the wrong place for the second suppression. Mainly, suppression should be precise and at the point of application -- where the dot goes if getting or setting, where the left paren goes if invoking. Also, if you agree that the ?( case in CS is less significant, then we shouldn't add it in haste or mangle ?. semantics to try to cover it. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Sorry -- an old inbox filter caused me to miss this... There were a couple of questions asked in the thread, but I think it might be helpful to summarize the overall rationale first. The existential operator in CoffeeScript (?) is intended to make it easier to ask questions about whether values exist. And to do so in different circumstances where telling the difference might be useful: as a postfix, as a binary operator, as a chained accessor, etc... The existential operator conflates null and undefined because both are the way to say no value in JavaScript. While it's entirely possible to define a JS api that behaves differently when you pass it null instead of undefined, doing so is almost certainly a bad idea. Long-time JavaScripters will tell you that they mean two different things: undefined is a value that has never been created whereas null is a value that has explicitly been removed -- in practice, that distinction is only ever useful for debugging ... you really don't want your code semantics to care about *how* a value came to not exist -- just that it does exist or doesn't. So, given that premise, the operator allows you to ask questions about existence in the following ways: Does the object exist? object? Does the property exist? object.property? Give me the object if it exists, otherwise give me the other value. object ? other Assign the property only if it doesn't already exist. object.property ?= value Call the method if it exists. object.method?(value) And finally, what we're discussing here: Continue accessing into the object only if the property exists. object.property?.other.properties.go.here I'm afraid that I don't quite follow Allen's reasoning from the comments in the previous tickets -- whether it's an object or a property is expected to exist isn't quite the point ... you want to be able to handle either case, or both at once, with equal ease. I was trying to illustrate a possible issue with your semantics when the existence of a property is conditional but the object that would have the property is expected to exist. If the object may not exist: `obj?.property` If the property may not exist: `obj.property?` If both may not exist: `obj?.property?` If ES.Next just does `?.` and not `?()`, that'll work, but will make it impossible to have method calls take part in chains of accesses. Allen asks about when you would want to write `foo?.bar()` ... the only use case I can think of is when `foo` may or may not be defined, and you know that if it *is* defined, it's going to have a `bar` method on it, and if it *is* defined, you want to call `bar` for its side effects. A bit far fetched. The far more common case is: options.success?(response) ... if the user passed a success callback, call it. I hope all that reasoning is first-principles-y enough. For what it's worth, there is one aspect of the existential operator that I'm not satisfied with and still want to change: How the check is stricter when you're calling a function: `func?()`. Everywhere else in the language, `?` means existence (not null or undefined) -- but when used to call a function, the check ensures that the value is callable as well. In a DWIM sense, this makes sense, because the only things you'd ever want to try to call in JavaScript must be callable ... but I think it's strange that the meaning of existence alters itself just for this use case. I opened a ticket talking about rolling it back to null or undefined semantics here: https://github.com/jashkenas/coffee-script/issues/2315 Cheers, Jeremy ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Another problem with your alternative: either it breaks a refactoring equivalence. Let == be equivalence for a program fragment, and != be inequivalence. Then we have in JS today extended with do expressions (and gensym via $tmp): foo.bar() == do {let $tmp = foo.bar; $tmp.call(foo)} Now use ?. used instead of dot. Either the equivalence breaks: foo?.bar() != do {let $tmp = foo?.bar; $tmp.call(foo)} Or else your alternative leaks Reference type values into the language, observably, because if foo?.bar() == do {let $tmp = foo?.bar; ($tmp == null) ? void 0 : $tmp.call(foo)} then var fun = foo?.bar; fun(); should not throw if fun is null or undefined, but there's nothing in the fun() expression to signal this to the implementation or readers. This fun would have as its value a new kind of MaybeReference type. We do not want this sub-alternative. /be Brendan Eich wrote: Brendan Eich wrote: Allen Wirfs-Brock wrote: I still stand by my alternative semantics as being a way to address the more important use case without have ?() No, the basis cases differ and that is a bug in your alternative. foo?.bar means take bar from foo or undefined if foo == null. foo?.bar() means take bar from foo and throw if foo == null else try to invoke the result if typeof function, else undefined. This is an off-by-one bug. It also uses ?. to mean . and magically applies the ? to the later (). Or if the semantics suppresses a TypeError both for the take bar and invoke it parts, then it's mixing two things in one under syntax located in the wrong place for the second suppression. Mainly, suppression should be precise and at the point of application -- where the dot goes if getting or setting, where the left paren goes if invoking. Also, if you agree that the ?( case in CS is less significant, then we shouldn't add it in haste or mangle ?. semantics to try to cover it. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Another problem with your alternative: either it breaks a refactoring equivalence. ... or it leaks maybe-Reference type values into the language. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Jeremy Ashkenas wrote: Everywhere else in the language, `?` means existence (not null or undefined) -- but when used to call a function, the check ensures that the value is callable as well. In a DWIM sense, this makes sense, because the only things you'd ever want to try to call in JavaScript must be callable ... but I think it's strange that the meaning of existence alters itself just for this use case. I opened a ticket talking about rolling it back to null or undefined semantics here: https://github.com/jashkenas/coffee-script/issues/2315 Apart from people misreading the proposal in this issue, it does seem to be removing a bit of utility, but perhaps that's not actually used? Do CS users try to ?(-invoke a maybe-function that is sometimes neither null nor undefined nor typeof-type function, but rather something that coerces to object? The way to get ?( into JS is by a longer spelling: options.success?.(response) Pretty ugly, but it puts the ? magic right where the maybe-test belongs. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
RE: Existential operator (was: ||= is much needed?)
What struck me from Jeremy's explanation was the uniformity of CoffeeScript's ? operator (modulo the small issue he mentioned for function calls). It seems to combine the currently-strawman'ed ??/??= and ?. into one very simple semantic. What about adopting ?? as CoffeeScript's ? operator? Would this solve the lookahead problems? So you could do object.property??.other.properties.go.here object.method??(args) This would unfortunately imply, for uniformity, that object ?? other object ??= other become null + undefined tests instead of just undefined. But that might be worth paying. For the record that leaves object?? as the only unimplemented CoffeeScript counterpart. From: es-discuss-boun...@mozilla.org [es-discuss-boun...@mozilla.org] on behalf of Brendan Eich [bren...@mozilla.org] Sent: Tuesday, June 19, 2012 14:08 To: Jeremy Ashkenas Cc: es-discuss Subject: Re: Existential operator (was: ||= is much needed?) Jeremy Ashkenas wrote: Everywhere else in the language, `?` means existence (not null or undefined) -- but when used to call a function, the check ensures that the value is callable as well. In a DWIM sense, this makes sense, because the only things you'd ever want to try to call in JavaScript must be callable ... but I think it's strange that the meaning of existence alters itself just for this use case. I opened a ticket talking about rolling it back to null or undefined semantics here: https://github.com/jashkenas/coffee-script/issues/2315 Apart from people misreading the proposal in this issue, it does seem to be removing a bit of utility, but perhaps that's not actually used? Do CS users try to ?(-invoke a maybe-function that is sometimes neither null nor undefined nor typeof-type function, but rather something that coerces to object? The way to get ?( into JS is by a longer spelling: options.success?.(response) Pretty ugly, but it puts the ? magic right where the maybe-test belongs. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Jeremy Ashkenas wrote: Everywhere else in the language, `?` means existence (not null or undefined) -- but when used to call a function, the check ensures that the value is callable as well. In a DWIM sense, this makes sense, because the only things you'd ever want to try to call in JavaScript must be callable ... but I think it's strange that the meaning of existence alters itself just for this use case. I opened a ticket talking about rolling it back to null or undefined semantics here: https://github.com/jashkenas/coffee-script/issues/2315 Apart from people misreading the proposal in this issue, it does seem to be removing a bit of utility, but perhaps that's not actually used? Do CS users try to ?(-invoke a maybe-function that is sometimes neither null nor undefined nor typeof-type function, but rather something that coerces to object? The way to get ?( into JS is by a longer spelling: options.success?.(response) Will you include options.success?.[index] then, too? Pretty ugly, but it puts the ? magic right where the maybe-test belongs. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
That's possible but it is a bit ugly, isn't it? Also, as dherman observed, ?. and variations are different from defaulting, in one point of view. That is, avoiding dereferencing a value that does not coerce to object is the purpose of ?. but not necessarily of ??= (or || as used for defaulting today). We could use ?obj as a prefix form for testing whether obj is not null or undefined, but it would then lead to doubled ?? when put in the then part of a ?: ternary. Using ?? as a suffix form is even uglier in a ternary: obj???wut:lol. We already have obj != null for testing whether obj is not null or undefined, so that takes away a lot of the pressure for unary ??. My current thinking is: (a) ?? and ??= as proposed in http://wiki.ecmascript.org/doku.php?id=strawman:default_operator (undefined-only). (b) ||= as a freebie since || is in the language and useful for falsy-defaulting (latent bugs notwithstanding). (c) ?. as proposed in http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator. (d) obj.maybeMethod?.(args) for what CoffeeScript calls ?(. /be Domenic Denicola wrote: What struck me from Jeremy's explanation was the uniformity of CoffeeScript's ? operator (modulo the small issue he mentioned for function calls). It seems to combine the currently-strawman'ed ??/??= and ?. into one very simple semantic. What about adopting ?? as CoffeeScript's ? operator? Would this solve the lookahead problems? So you could do object.property??.other.properties.go.here object.method??(args) This would unfortunately imply, for uniformity, that object ?? other object ??= other become null + undefined tests instead of just undefined. But that might be worth paying. For the record that leaves object?? as the only unimplemented CoffeeScript counterpart. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Herby Vojčík wrote: Will you include options.success?.[index] then, too? I wasn't planning on it. CoffeeScript does not have any such thing (spelling it ?[ would be hard in CS too, due to array literals). Could add it in the future, trying not to overdo the strawman at this point. YAGNI and KISS and when-in-doubt-leave-it-out all are against it. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Tue, Jun 19, 2012 at 2:59 PM, Brendan Eich bren...@mozilla.org wrote: Herby Vojčík wrote: Will you include options.success?.[index] then, too? I wasn't planning on it. CoffeeScript does not have any such thing (spelling it ?[ would be hard in CS too, due to array literals). Could add it in the future, trying not to overdo the strawman at this point. YAGNI and KISS and when-in-doubt-leave-it-out all are against it. Actually, CoffeeScript definitely has it for consistency's sake: http://coffeescript.org/#try:object.property%3F%5Bone%5D ... we don't have a problem with being whitespace-sensitive for situations like this. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 10:31 AM, Brendan Eich wrote: Brendan Eich wrote: Allen Wirfs-Brock wrote: I still stand by my alternative semantics as being a way to address the more important use case without have ?() No, the basis cases differ and that is a bug in your alternative. foo?.bar means take bar from foo or undefined if foo == null. foo?.bar() means take bar from foo and throw if foo == null else try to invoke the result if typeof function, else undefined. This is an off-by-one bug. It also uses ?. to mean . and magically applies the ? to the later (). Or if the semantics suppresses a TypeError both for the take bar and invoke it parts, then it's mixing two things in one under syntax located in the wrong place for the second suppression. Mainly, suppression should be precise and at the point of application -- where the dot goes if getting or setting, where the left paren goes if invoking. I don't agree, probably because I'm look at ?. as an operator that evaluates to a special kind of Reference. Like with References in general, it is the ultimate consumer (usually via GetValue/SetValue, but not always) of the Reference that actually access the value or throws an error if appropriate. If we say that the value Missing represents a Reference to a known to be non-existant value, then the semantics of LHS?.prop can be summarized as: LHS==Result --- Unresolvable Ref Missing undefined/null Missing Missing Missing other non-RefConditionalRef(GetValue(LHS),prop) Reference Missing or ConditionalRef(GetValue(LHS),prop) (both normal and Conditional) This differs from LHS.prop whose corresponding table would be LHS==Result --- Unresolvable throw undefined/null throw Missing throw other non-RefReference(GetValue(LHS),prop) Reference throw or Reference(GetValue(LHS),prop) (both normal and Conditional) In addition, GetValue(V) is extended with these cases: V==Result --- Missing undefined ConditionalRefundefined if referenced property doesn't exist, otherwise same as normal Reference Just like with all References, it is the consumer of a Missing/ConditionalReference value that determines what to do with. Most consumers unconditionally call GetValue however, some like typeof and delete explicitly deal with the Reference in some other manner. All I have done is add function call to the list of operators that have some Reference sensitive semantics. It would have special handling for Missing/ConditionalRefs. I could also add Missing semantics to delete, but it really isn't very important there. Also, if you agree that the ?( case in CS is less significant, then we shouldn't add it in haste or mangle ?. semantics to try to cover it. No, I didn't say that. I said that I suspect that f?() is less significant than foo?.bar?() I suspect that (if you could say them in JS) we would find that g(foo?.bar) and g(foo?.baz?()) are about equally significant and that people will write (or typo) foo?.bar() with the expectation that it means foo?.bar?() The risk is in adding precisely CoffeeScript ?. in haste without thinking through implications of not also having ?(). It may mean a different variant of ?. semantics would work better in our case. Allen /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Jeremy Ashkenas wrote: On Tue, Jun 19, 2012 at 2:59 PM, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: Herby Vojčík wrote: Will you include options.success?.[index] then, too? I wasn't planning on it. CoffeeScript does not have any such thing (spelling it ?[ would be hard in CS too, due to array literals). Could add it in the future, trying not to overdo the strawman at this point. YAGNI and KISS and when-in-doubt-leave-it-out all are against it. Actually, CoffeeScript definitely has it for consistency's sake: http://coffeescript.org/#try:object.property%3F%5Bone%5D ... we don't have a problem with being whitespace-sensitive for situations like this. Oops, missed that somehow. Ok, at this point my attempt to avoid ?.[ hangs only on the need for three chars. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: I don't agree, probably because I'm look at ?. as an operator that evaluates to a special kind of Reference. That your alternative off-by-one in its basis case is bad enough -- it creates two error suppression points from one syntactic extension-point, it will hide bugs, it is gratuitously different from CoffeeScript, and it prevents using the ?( analogue on an unqualified identifier. Worse, instead of leaking an observable ConditionalReference (whew!), you've opted to break the equivalence between foo.bar() and %tmp = foo.bar; %tmp.call(foo) for the case where . is replaced by ?. -- in this case your proposal does not throw while the expansion does. The right extension for what CoffeeScript calls ?( is simply to use an unambiguous and backward-compatible extension, such as ?.( instead. The risk is in adding precisely CoffeeScript ?. in haste without thinking through implications of not also having ?(). It may mean a different variant of ?. semantics would work better in our case. I'm not adding anything in haste, and CoffeeScript has been around, what, three years. The haste here seems to be on the other foot :-|. Also, I do not think we should extend Reference types in the spec if we can help it. These must boil away in optimizing implementations, always. Elaborating them risks leaks or more subtle dependencies happening as unintended consequences. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 10:50 AM, Brendan Eich wrote: Another problem with your alternative: either it breaks a refactoring equivalence. Let == be equivalence for a program fragment, and != be inequivalence. Then we have in JS today extended with do expressions (and gensym via $tmp): foo.bar() == do {let $tmp = foo.bar; $tmp.call(foo)} Now use ?. used instead of dot. Either the equivalence breaks: foo?.bar() != do {let $tmp = foo?.bar; $tmp.call(foo)} Why is it important that this equivalence holds for . and ?. We already have other places using references where similar refactoring aren't equivalent: typeof foo != do(let $tmp = foo /*Reference error if foo unresolvable) */; typeof $tmp) In particular, I'm pretty sure that this refactoring hazard is not going to be as significant as the foo?.bar() //oops I'm really think foo?.bar?() hazard Or else your alternative leaks Reference type values into the language, observably, because if foo?.bar() == do {let $tmp = foo?.bar; ($tmp == null) ? void 0 : $tmp.call(foo)} then var fun = foo?.bar; fun(); should not throw if fun is null or undefined, but there's nothing in the fun() expression to signal this to the implementation or readers. This fun would have as its value a new kind of MaybeReference type. We do not want this sub-alternative. No, of course not. You can't allow References to leak to the user value level! Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Brendan Eich wrote: Worse, instead of leaking an observable ConditionalReference (whew!), you've opted to break the equivalence between foo.bar() and %tmp = foo.bar; %tmp.call(foo) for the case where . is replaced by ?. -- in this case your proposal does not throw while the expansion does. The right extension for what CoffeeScript calls ?( is simply to use an unambiguous and backward-compatible extension, such as ?.( instead. Jeremy pointed out privately that the need for ?( is less acute in practice, and also because of .call via the equivalences: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) But ?.( is shorter. It's awkward to use three chars instead of CoffeeScript's two, and to have a dot in the middle where no get or set is implied. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 12:26 PM, Brendan Eich wrote: Brendan Eich wrote: Worse, instead of leaking an observable ConditionalReference (whew!), you've opted to break the equivalence between foo.bar() and %tmp = foo.bar; %tmp.call(foo) for the case where . is replaced by ?. -- in this case your proposal does not throw while the expansion does. The right extension for what CoffeeScript calls ?( is simply to use an unambiguous and backward-compatible extension, such as ?.( instead. Jeremy pointed out privately that the need for ?( is less acute in practice, and also because of .call via the equivalences: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) How are these equivalent? Won't fun?.call evaluate to undefined if fun is undefined and undefined(undefined,args) will throw... Allen But ?.( is shorter. It's awkward to use three chars instead of CoffeeScript's two, and to have a dot in the middle where no get or set is implied. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Is it possible to do something like foo.bar?:(foo, args) Basically a ternary that allows an empty component, and can tell the future (whether the other result is callable) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Tue, Jun 19, 2012 at 3:33 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) How are these equivalent? Won't fun?.call evaluate to undefined if fun is undefined and undefined(undefined,args) will throw... ... check out the compilation: http://coffeescript.org/#try:fun%3F.call(undefined%2C%20args)%0A%0Awindow.method%3F.call(window%2C%20args) It doesn't eagerly evaluate to undefined ... the value of the *entire* expression is undefined if the chain is broken at the existential operator. That's much of the point of soaks: object.property?.i.can.keep.chaining.in.here.without.throwing.errors.if.property.is.undefined ;) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 12:37 PM, Jeremy Ashkenas wrote: On Tue, Jun 19, 2012 at 3:33 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) How are these equivalent? Won't fun?.call evaluate to undefined if fun is undefined and undefined(undefined,args) will throw... ... check out the compilation: http://coffeescript.org/#try:fun%3F.call(undefined%2C%20args)%0A%0Awindow.method%3F.call(window%2C%20args) Ah, interesting...so this is actually close to what I was advocating for this particular case. However, if I now understand correctly you are saying that fun?.call() produces undefined if fun is null/undefined but will throw if fun is defined as: fun = new Object; because it doesn't have have call property. Also, it isn't clear to me why the second example (window.method?.call(window, args)) is only guarding for null and not undefined. Is it only because you guard for undefined on variable references and not on property references? Basically, I see what the code you generate is doing but the unlying semantics that yields that code is less obvious. It doesn't eagerly evaluate to undefined ... the value of the *entire* expression is undefined if the chain is broken at the existential operator. That's much of the point of soaks: object.property?.i.can.keep.chaining.in.here.without.throwing.errors.if.property.is.undefined ;) Ah, again. I don't think Brendan's strawman will produce that result. The ...?.i is going to get undefined when it does GetValue on the Reference produced for object.property. Then undefined.can will throw in step 5 of 11.2.1 because the LHS is undefined. Getting this behavior seems to requires modifying . as well as defining ?. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Tue, Jun 19, 2012 at 4:35 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: Ah, interesting...so this is actually close to what I was advocating for this particular case. However, if I now understand correctly you are saying that fun?.call() produces undefined if fun is null/undefined but will throw if fun is defined as: fun = new Object; because it doesn't have have call property. Yes, exactly. Also, it isn't clear to me why the second example (window.method?.call(window, args)) is only guarding for null and not undefined. Is it only because you guard for undefined on variable references and not on property references? Ha ha, loose equality strikes again! It's actually guarding for both null and undefined. It's the only place that CoffeeScript purposefully uses the in-all-other-cases-avoided != operator. undefined == null, right? Ah, again. I don't think Brendan's strawman will produce that result. The ...?.i is going to get undefined when it does GetValue on the Reference produced for object.property. Then undefined.can will throw in step 5 of 11.2.1 because the LHS is undefined. Getting this behavior seems to requires modifying . as well as defining ?. I'm afraid I can't speak to the spec language or strawman ... but the basic idea with soaking is to short-circuit evaluation as soon as the soak fails. In the same way that: window || a.b.c ... won't error even if a is entirely undeclared ... window.a?.b.c ... won't error even if a is entirely undeclared. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
On Jun 19, 2012, at 2:15 PM, Jeremy Ashkenas wrote: On Tue, Jun 19, 2012 at 4:35 PM, Allen Wirfs-Brock al...@wirfs-brock.com wrote: ... Ha ha, loose equality strikes again! It's actually guarding for both null and undefined. It's the only place that CoffeeScript purposefully uses the in-all-other-cases-avoided != operator. undefined == null, right? Of course! I'm blind to it because I always try to be explicit and use === tests... Ah, again. I don't think Brendan's strawman will produce that result. The ...?.i is going to get undefined when it does GetValue on the Reference produced for object.property. Then undefined.can will throw in step 5 of 11.2.1 because the LHS is undefined. Getting this behavior seems to requires modifying . as well as defining ?. I'm afraid I can't speak to the spec language or strawman ... but the basic idea with soaking is to short-circuit evaluation as soon as the soak fails. In the same way that: The ES spec. is left recursive so the semantics for MemberExpression :: MemberExpression . IdentifierName has no direct way of knowing that the MemberExpression to the left of the . contained a ?. Similarly if that nested MemberExpression was: MemberExpression :: MemberExpression ?. IdentifierName it has no direct way (other than throwing an exception) to terminate evaluation of the MemberExpression to its right. That is why things like Reference values are used within the specification to transport semantic state around. Of course an actual implementation is not necessarily limited in this manner... Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Allen Wirfs-Brock wrote: On Jun 19, 2012, at 10:50 AM, Brendan Eich wrote: Another problem with your alternative: either it breaks a refactoring equivalence. Let== be equivalence for a program fragment, and!= be inequivalence. Then we have in JS today extended with do expressions (and gensym via $tmp): foo.bar()== do {let $tmp = foo.bar; $tmp.call(foo)} Now use ?. used instead of dot. Either the equivalence breaks: foo?.bar()!= do {let $tmp = foo?.bar; $tmp.call(foo)} Why is it important that this equivalence holds for . and ?. Equivalences are not sacred but they are informative and sometimes normative (as in, a refactoring norm exists in the world). We already have other places using references where similar refactoring aren't equivalent: typeof foo!= do(let $tmp = foo /*Reference error if foo unresolvable) */; typeof $tmp) That's right, and that is considered a botch not to imitate.The fact that typeof x == function testing is so long-winded is indeed one of the motivations for ?(. In particular, I'm pretty sure that this refactoring hazard is not going to be as significant as the foo?.bar() //oops I'm really think foo?.bar?() hazard CoffeeScript has years of use, and this is not something that has caused confusion (ask @jashkenas, see github issues). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Indeed I did not spec this in http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator#semantics -- one step at a time. Also I'm not sure how the indefinite soak will fly with others on TC39. Allen, I agree if we do make a soak and don't spec it as CoffeeScript realizes it (by translation!) then we're looking at elaborating Reference semantics. Still smells, but it's the only plausible path if this is the goal. More when I have time. Thanks for the feedback. /be Jeremy Ashkenas wrote: On Tue, Jun 19, 2012 at 3:33 PM, Allen Wirfs-Brock al...@wirfs-brock.com mailto:al...@wirfs-brock.com wrote: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) How are these equivalent? Won't fun?.call evaluate to undefined if fun is undefined and undefined(undefined,args) will throw... ... check out the compilation: http://coffeescript.org/#try:fun%3F.call(undefined%2C%20args)%0A%0Awindow.method%3F.call(window%2C%20args) http://coffeescript.org/#try:fun%3F.call%28undefined%2C%20args%29%0A%0Awindow.method%3F.call%28window%2C%20args%29 It doesn't eagerly evaluate to undefined ... the value of the *entire* expression is undefined if the chain is broken at the existential operator. That's much of the point of soaks: object.property?.i.can.keep.chaining.in.here.without.throwing.errors.if.property.is.undefined ;) ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Complement for my last sentence : if you are using ?. it means that you don't know if the thing does exist, then you are probably waiting for it to exist (asynchronous environments for example), then once you get it, it is very unlikely that you call it right away, I would like to see some examples Le 20/06/2012 00:36, Aymeric Vitte a écrit : Coffeescript seems to have some radical behavior (a.b?.c.d.e.f) a bit similar to what I suggested (which ok can not be in js) But the discussion here still does not say how much a.b?() or a.b?.call(xxx) is used in coffeescript Personnaly I was thinking that ?. should more allow to check existence rather than both checking and calling it if it exists, difficult to win everywhere Le 19/06/2012 22:35, Allen Wirfs-Brock a écrit : On Jun 19, 2012, at 12:37 PM, Jeremy Ashkenas wrote: On Tue, Jun 19, 2012 at 3:33 PM, Allen Wirfs-Brock al...@wirfs-brock.com mailto:al...@wirfs-brock.com wrote: foo.bar?(args) == foo.bar?.call(foo, args) fun?(args) == fun?.call(undefined, args) How are these equivalent? Won't fun?.call evaluate to undefined if fun is undefined and undefined(undefined,args) will throw... ... check out the compilation: http://coffeescript.org/#try:fun%3F.call(undefined%2C%20args)%0A%0Awindow.method%3F.call(window%2C%20args) http://coffeescript.org/#try:fun?.call%28undefined,%20args%29%0A%0Awindow.method?.call%28window,%20args%29 Ah, interesting...so this is actually close to what I was advocating for this particular case. However, if I now understand correctly you are saying that fun?.call() produces undefined if fun is null/undefined but will throw if fun is defined as: fun = new Object; because it doesn't have have call property. Also, it isn't clear to me why the second example (window.method?.call(window, args)) is only guarding for null and not undefined. Is it only because you guard for undefined on variable references and not on property references? Basically, I see what the code you generate is doing but the unlying semantics that yields that code is less obvious. It doesn't eagerly evaluate to undefined ... the value of the *entire* expression is undefined if the chain is broken at the existential operator. That's much of the point of soaks: object.property?.i.can.keep.chaining.in.here.without.throwing.errors.if.property.is.undefined ;) Ah, again. I don't think Brendan's strawman will produce that result. The ...?.i is going to get undefined when it does GetValue on the Reference produced for object.property. Then undefined.can will throw in step 5 of 11.2.1 because the LHS is undefined. Getting this behavior seems to requires modifying . as well as defining ?. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email :avi...@jcore.fr Web :www.jcore.fr Webble :www.webble.it Extract Widget Mobile :www.extractwidget.com BlimpMe! :www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. Introducing yet another way to think about values in ES is not going to help most programmers. We already have to think about thinks like undefined and falsey -- what's been proposed here is an operator that mysterious works on something halfway between the two. Some folks may not see the need to differentiate between the two, but as somebody who talks to databases with ES -- there is a world of difference between null and undefined. Wes -- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
This is related to what I was trying to figure out in the more fun with undefined thread, maybe it is wrong or have too many impact but I was about to suggest : 8.9.1 GetValue (V) ... 5. If IsUnresolvableReference(V), return undefined 11.2.1 Property Accessors Runtime Semantics: Evaluation ... 3. If baseValue is an abrupt completion or undefined, return baseValue. Why not, instead of adding ? operator ? Le 18/06/2012 07:11, Brendan Eich a écrit : Sorry, meant to start a new thread for: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator As the Syntax section hints, we can't also adopt CoffeeScript's ?( variant, which enables foo.bar?(args, go, here).baz and the like. The C syntax heritage prevails. /be Brendan Eich wrote: David Herman wrote: On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a please default sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined. Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) *or* has a value not coercible to object type (null or undefined). See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
Aymeric Vitte wrote: Why not, instead of adding ? operator ? You mean ?. here, I assume. The answer is because what you propose is an incompatible change to ECMA-262 (all editions) and JS back to its birth, which lets programs that throw currently continue to run, with possibly disastrous consequences (undefined flowing into the bank-balance database as NaN). There is no way that this kind of potentially-bug-hiding behavior should be the default semantics. It must be explicitly opted-into via new syntax. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
OK, ?. is enough and good Le 18/06/2012 16:48, Brendan Eich a écrit : Aymeric Vitte wrote: Why not, instead of adding ? operator ? You mean ?. here, I assume. The answer is because what you propose is an incompatible change to ECMA-262 (all editions) and JS back to its birth, which lets programs that throw currently continue to run, with possibly disastrous consequences (undefined flowing into the bank-balance database as NaN). There is no way that this kind of potentially-bug-hiding behavior should be the default semantics. It must be explicitly opted-into via new syntax. /be -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: Existential operator (was: ||= is much needed?)
This proposal augments the default operator by adding syntax to avoid accessing a missing property, specifically ?. for getting and setting a property from a reference base that might be undefined or null: [1] The specified semantics of proposal actually does more than avoid accessing a missing property. It also avoids accessing a property of a missing object. For example, function f() { var foo; //oops, I forgot to write the initializer expression return foo?.bar;//returns undefined because foo evaluates to undefined. foo.bar would throw } This seems slightly and possibly significantly different from a situation like: function f(foo={ }) { return foo?.bar;//returns value of foo.bar or undefined if property bar does not exist, just like foo.bar } In particular, it has the affect of possibly propagating the detection of a simple editorial error like a forgotten initializer further from its place of occurrence. At the least, this behavior probably should be clarified in the description The inability to use ?. meaningfully in a function call context would seem to make this a only half useful feature. I suspect many people will initially try to write something like foo?.bar() with the expectation that the call will be skipped if bar doesn't exist. These may be an alternative semantics that might address both of the above issues. Consider: The semantics of ?. could be defined in terms of a new Reference variant (a Conditiional Reference): Let baseReference be the result of evaluating MemberExpression. If Type(baseReference) is Reference and IsConditionalReference(baseReference) is true, then let baseValue be GetUnconditionalValueOrMissing(baseReference) Else let baseValue be GetValue(baseReference). If baseValue is null or undefined, then throw a TypeError exception. Let propertyName be the result of evaluating IdentifierName. If the syntactic production that is being evaluated is contained in strict mode code, let strict be true, else let strict be false. Return a value of type Conditional Reference whose base value is baseValue and whose referenced name is propertyName, and whose strict mode flag is strict. Missing is an internal value that designates an attempt to access a missing value. GetUnconditionalValueOrMissing(R) where R is a Reference is defined as Let value be GetValue(R). If value is null or undefined then if IsConditionalReference(R) is true hen return Missing. Return value. and GetValue would get the following new steps: 2.5 If IsConditionalReference(V) is true then If base is Missing then then return undefined. Function call semantics (11.2.3) could then be modified with the existing step 2 replaced with 2.1 Let func be GetUnconditionalValueorMIssing(ref). 2.2 If func is MIssing, then return undefined. With these changes, the following would evaluate to undefined: var foo ={}, foo2; foo?.bar() but foo.bar(); would throw. But note that both foo2.bar() foo2?.bar() would throw reference error exceptions because of line 4 of the ?. semantics n (and the existing .). In other words, a variable reference that resolves to undefined or null when used as a base of ?. doesn't be a pass. However, the two above changes a separable with want one, but not the other. Allen [1]: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
David Herman wrote: On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a please default sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined. Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) *or* has a value not coercible to object type (null or undefined). See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Existential operator (was: ||= is much needed?)
Sorry, meant to start a new thread for: http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator As the Syntax section hints, we can't also adopt CoffeeScript's ?( variant, which enables foo.bar?(args, go, here).baz and the like. The C syntax heritage prevails. /be Brendan Eich wrote: David Herman wrote: On Jun 15, 2012, at 5:57 PM, satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. I think you could make a case for ?. defaulting for both but ?? defaulting only undefined. The case goes something like this: - The purpose of ?? is to provide a default value when no value was provided. The way to say no value in JavaScript is undefined. - The purpose of ?. is to fail soft when doing a property lookup. Both null and undefined throw when doing a property lookup. Agreed. This is one choice, it's plausible because of the distinction between defaulting (which requires intentional passing of a please default sentinel value, or not passing a trailing actual argument) and soaking up null-or-undefined. Yes, we could make ?? and ??= do the same for null as for undefined. I'm not sure that's the right choice, but it's a choice. For foo.bar?.baz, though, the clearer choice is to avoid throwing, which means evaluating to undefined if foo.bar is missing (evaluates to undefined) *or* has a value not coercible to object type (null or undefined). See http://wiki.ecmascript.org/doku.php?id=strawman:existential_operator /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Yes, what I mean is that I did not see since a long time something like a===null?b:c or if (a===null)||b, and except for specific use like Object.create(null) I don't see a lot of null being used, then making the distinction for ??, ?: and others looks too subtle Le 15/06/2012 04:20, Brendan Eich a écrit : On Jun 14, 2012, at 6:38 PM, Aymeric Vittevitteayme...@gmail.com wrote: Maybe I missed it, never saw the use of null since a long time, but I can be wrong As Allen pointed out, null is specified in ECMA-262, e.g. Object.getPrototypeOf. /be -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 14, 2012, at 1:45 PM, Brendan Eich wrote: I can see adding ?? and ??= (undefined-only, not undefined-or-null). I think ?? is the highest priority. Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind. Given ||= is there any oxygen left in the room for ??=? ??= is strictly less error-prone than ||= so I can't see why we would favor ||= if we were choosing just one. As I see it, the biggest issue with ??= and ||= is that -- unlike other compound assignment forms -- they are short-circuiting. All the existing compound assignment forms evaluate both sides no matter what. IIRC, back in the ES4 days, this is why we rejected ||=. I'm still not against it, though. It's obvious what it means. It's obviously useful. So I favor ?? as well as both ||= and ??=. As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. But I think by sticking to the simpler semantics it will help clarify the distinction. The JS semantics currently treats only undefined as no value and it would continue to do so. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
David Herman wrote: So I favor ?? as well as both ||= and ??=. As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. But I think by sticking to the simpler semantics it will help clarify the distinction. The JS semantics currently treats only undefined as no value and it would continue to do so. I agree on all this. I'll update the strawman soon. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 15, 2012, at 12:33 PM, David Herman wrote: So I favor ?? as well as both ||= and ??=. Adding ||= and ??= without = will cause my symmetry-reflex to twitch, despite not seeing a purpose for it I may find it hard to resist supporting that too. ;-) G. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
satyr wrote: On Sat, Jun 16, 2012 at 4:33 AM, David Herman dher...@mozilla.com mailto:dher...@mozilla.com wrote: As for null, I can see how there's confusion about whether to use null vs undefined, and so I can see why CoffeeScript would just try to blur the distinction between them. Not just for blurring. Rejecting `null` is essential for CoffeeScript's existence due to `?.`, the soak/safe access operator. Can you give a real-world example where null rather than undefined is soaked up? I'm guessing DOM but guessing is bad (cf. Sherlock Holmes). /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Fri, Jun 15, 2012 at 6:00 PM, Brendan Eich bren...@mozilla.com wrote: Can you give a real-world example where null rather than undefined is soaked up? I'm guessing DOM but guessing is bad (cf. Sherlock Holmes). Wouldn't any case where you return null to mean explicitly no object be such a case? Ie: var bar = lookupFoo(key)?.bar(); -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Maybe, probably, of course ;-). I'm still looking for real-world use-cases, code that actually exists (in CoffeeScript or JS) that needs to soak up null-or-undefined, not just undefined. /be John Tamplin wrote: On Fri, Jun 15, 2012 at 6:00 PM, Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote: Can you give a real-world example where null rather than undefined is soaked up? I'm guessing DOM but guessing is bad (cf. Sherlock Holmes). Wouldn't any case where you return null to mean explicitly no object be such a case? Ie: var bar = lookupFoo(key)?.bar(); -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Confusion: at no point has the http://wiki.ecmascript.org/doku.php?id=strawman:default_operator strawman removed the infix operator originally proposed as ?? and currently spelled ?: -- everyone agrees on having both OP and OP=, whatever the spelling of OP. I agree on reflection with Wes and others who've objected that A ?: B has the simplest interpretation as A ? A : B and therefore should not be used for anything like (A !== undefined) ? A : B or (A != null) ? A : B. I noted this as an open issue but I'm almost ready to flip the strawman back to ?? and ??=. Comments on syntax? On semantics: CoffeeScript's use of != null to equate null and undefined matches some users' habits, and helps to conceal the awkward fact of two bottom-types in JS (@jashkenas just averred that was the goal). But such concealment can never be perfect and other users will either want to distinguish, or (what is more worrisome) will accidentally distinguish (e.g. with !==) null from undefined. If only we didn't have both null and undefined! I blame Java (after myself, of course). But we're stuck with both and we have to make the best of this situation. I still don't see a lot of intentional use of null to mean undefined, e.g. as a no argument, please default value passed into APIs. But null or any falsy value would work fine for APIs whose implementations default using ||, so it is possible null is used widely by convention, and I just haven't seen it. Whatever we do, we should do the same for parameter default values. CoffeeScript is consistent in equating null and undefined and triggering parameter defaulting as if by its ?= assignment op: f = (x, y=1, z=2) - console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath. /be David Herman wrote: On Jun 12, 2012, at 10:52 PM, Brendan Eich wrote: People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see foo(arg1 || callers_idea_of_default_arg1_value); I'm sure it's more rare than the assignment form, but that's partly because the assignment form is needed to make up for lack of pdv's. whereas we all see function foo(a, b, c) { a = a || default_a; b.x = b.x || default_b_x; b.y = b.y || default_b_y; c.z = function (w) { // long body here } ... } Well, you wouldn't argue against having || in the language. Yes, I know it serves other roles as well. But only providing the assignment form strikes me as over-specialization. Operators are a straightforward generalization of assignments. When you specialize the syntax to provide an assignment form only, you force people to create temporary variables when they aren't needed. Compound expressions are good things! And why break the pattern of compound assignments being based on binary operators? Why should ?= or ??= be different from +=, -=, *=, /=, %=,=,=,=,=, |=, ^=? It just seems like a pointless restriction. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 14, 2012, at 10:10 AM, Brendan Eich wrote: On semantics: CoffeeScript's use of != null to equate null and undefined matches some users' habits, and helps to conceal the awkward fact of two bottom-types in JS (@jashkenas just averred that was the goal). But such concealment can never be perfect and other users will either want to distinguish, or (what is more worrisome) will accidentally distinguish (e.g. with !==) null from undefined. If only we didn't have both null and undefined! I blame Java (after myself, of course). But we're stuck with both and we have to make the best of this situation. +1 (except Java doesn't have the equivalent of undefined as a manifest value) I still don't see a lot of intentional use of null to mean undefined, e.g. as a no argument, please default value passed into APIs. But null or any falsy value would work fine for APIs whose implementations default using ||, so it is possible null is used widely by convention, and I just haven't seen it. Whatever we do, we should do the same for parameter default values. CoffeeScript is consistent in equating null and undefined and triggering parameter defaulting as if by its ?= assignment op: I think treating null as not provided, use the default in parameters is a bad thing that would be going down the path of concealment that is rejected above. While some (many??) people use null and undefined interchangeably, other are no doubt using them closer to the original intention (uninitialized/missing value vs. no object). To cause null to trigger parameter (and destructuring) default values wound break that current valid usage pattern. While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be. f = (x, y=1, z=2) - console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath. sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
T.J. Crowder wrote: On 14 June 2012 18:10, Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote: I agree on reflection with Wes and others who've objected that A ?: B has the simplest interpretation as A ? A : B and therefore should not be used for anything like (A !== undefined) ? A : B or (A != null) ? A : B. I noted this as an open issue but I'm almost ready to flip the strawman back to ?? and ??=. Comments on syntax? Do people see sufficient value in a second ternary operator that uses the same semantics for what's a non-value? E.g.: a = b ?? c : d; meaning a = b !== undefined ? c : d; No, too thin. Also preempts ?? as an infix operator, which has been proposed for quite a while as the default operator. If people *don't* see sufficient value in the second ternary (and the use cases are pretty limited), ?? and ??= are great. Ship 'em. Not in ES6, but I'm working on the strawman to get them into Harmony, so they can be prototyped, user-tested, and standardized in due course. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Allen Wirfs-Brock wrote: While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be. Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly. f = (x, y=1, z=2) - console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath. sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. That's a reductio ad absurdum, nothing to do with why I wrote what I wrote. We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Brendan Eich wrote: Allen Wirfs-Brock wrote: While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be. Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly. f = (x, y=1, z=2) - console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath. sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. That's a reductio ad absurdum, nothing to do with why I wrote what I wrote. We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? If I can add my own, I use || (because it's short, and if (foo) pattern desensitivised me), but if there would be an operator for undefined, I'll switch to use it immediately (I always see it as undefined, knowing I do sin when using ||). Btw, |if(foo)| also needs replacement in that case, though if ?? will be there, |if (foo??true)| (or |if (foo??1)|) would serve the case well. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Herby Vojčík wrote: Brendan Eich wrote: Allen Wirfs-Brock wrote: While I'm less than enthusiastic about explicitly provided undefined values triggering default value usages, I don't think it is particularly harmful. I think treating null equivalently would be. Noted, but you have not responded to the argument, made by Sam Tobin-Hochstadt based on Racket experience, Tab Atkins in Common Lisp, and others, that failing to treat explicit undefined as a defaulting trigger creates an anti-modular, combinatorial explosion when wrapping and delegating. This is the sole reason undefined (or undefined and null, separate issue) as defaulting trigger is proposed. Please respond to it directly. f = (x, y=1, z=2) - console.log(x, y, z) f(0, null, undefined) generates f = function(x, y, z) { if (y == null) { y = 1; } if (z == null) { z = 2; } return console.log(x, y, z); }; f(0, null, void 0); We could certainly do worse than to pave this cowpath. sure, for example, by having any falsy value trigger default value usage. But just because there are worse things doesn't make the a good idea. That's a reductio ad absurdum, nothing to do with why I wrote what I wrote. We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? If I can add my own, I use || (because it's short, and if (foo) pattern desensitivised me), but if there would be an operator for undefined, I'll switch to use it immediately (I always see it as undefined, knowing I do sin when using ||). Btw, |if(foo)| also needs replacement in that case, though if ?? will be there, |if (foo??true)| (or |if (foo??1)|) would serve the case well. Well, sorry, not. This is wrong. ?? can't help. |foo ?? 1 : 0| would, but it's different matter. === undefined is too long, though. /be Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On 14 June 2012 19:01, Brendan Eich bren...@mozilla.com wrote: The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. Not quite. I use || whenever I can in my defaulting code, and I can use it a lot (e.g., when the optional item must be an object). I only use the long-winded version if I have to because 0, , false, or null is a valid possible value -- which is surprisingly rare. Hugely looking forward to using ?? uniformly instead, but it's not accurate to say that we who don't want undefined and null equated in this context are therefore not using ||. -- T.J. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 11:01 AM, Brendan Eich bren...@mozilla.com wrote: We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? I don't claim to be typical in cases like this, but my experience is similar to Herby's - I use || most of the time just because it's short and easy, but switch to x === undefined with a trinary if x might be falsey. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Tab Atkins Jr. wrote: On Thu, Jun 14, 2012 at 11:01 AM, Brendan Eichbren...@mozilla.com wrote: We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? I don't claim to be typical in cases like this, but my experience is similar to Herby's - I use || most of the time just because it's short and easy, but switch to x === undefined with a trinary if x might be falsey. Yeah, I switch, too. If I see it is needed, and don't forget it. That is why || is uneasy, ?? would remove the fear (in Kent-and-Ward TDD sense). ~TJ Herby ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
T.J. Crowder wrote: On 14 June 2012 19:01, Brendan Eich bren...@mozilla.com mailto:bren...@mozilla.com wrote: The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. Not quite. I use || whenever I can in my defaulting code, and I can use it a lot (e.g., when the optional item must be an object). I only use the long-winded version if I have to because 0, , false, or null is a valid possible value -- which is surprisingly rare. Hugely looking forward to using ?? uniformly instead, but it's not accurate to say that we who don't want undefined and null equated in this context are therefore not using ||. Good point, when you are dealing with an object or variable that you know will be either undefined or a well-typed value, you can use ||. But how do you know what is a possible value? Wes testified elsewhere that he had latent bugs. I suspect many APIs whose impls use || do. /be ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 14, 2012, at 11:01 AM, Brendan Eich wrote: ... We have a problem with || indeed. The question is whether the solution should equate null and undefined. CoffeeScript chose the conceal-the-difference path and it has users. The users who want null to be distinct from undefined are neither CoffeeScript users, nor || users (in their defaulting code). They must be doing === undefined test. That is rare too (not quite as rare as passing null instead of undefined as intentional default trigger in my experience). What is your reason for preferring === undefined over == null, since we have a dilemma and users often use an even looser (falsy, viz ||) test than == null, but some use == null and others use === undefined, for the defaulting trigger? I guess my concern is that there are significant existing subsystems where null is distinguished from undefined or where null has a specifically defined meaning that does not apply to undefined. For example: [[Prototype]] manipulation (Object.create, Object.getPrototypeOf, __proto__) RegExp exec and derived APIs JSON stringify/parse the DOM (WebIDL, provides lots of options vis [TreatUndefinedAs]] to explicitly control the mapping of undefined) Any of these might yield null values that downstream might want to be distinguished from an unintentional undefined (result of a bogus property access) or explicitly empty parameter slot. My sense is that equating undefined and null for the purpose of supplying default values is going to preclude default value usage in any context where null has a specific meaning. Equating null and undefined in the sole form of default seems value assignment seems to be a bigger commitment to the path of generally trying to conceal the distinction between null and undefined. If we want to commit to that path, then we probably should be explicit about it and make sure that we generally try to avoid new use cases that distinguish them. For example, for class definitions I have a draft spec. such that (class extends undefined { }) means the same things as (class {}) which means something different from than (class extends null { }. If our goal is generally to conceal the difference between undefined and null, I would probably change that equivalence. Note that this all would probably also have implications for reflective APIs that someone might build in support of classes. One way to have it both ways is to have multiple syntactic forms for default value initializers. EG: function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical. Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 2:39 PM, Allen Wirfs-Brock al...@wirfs-brock.comwrote: snip I guess my concern is that there are significant existing subsystems where null is distinguished from undefined or where null has a specifically defined meaning that does not apply to undefined. For example: [[Prototype]] manipulation (Object.create, Object.getPrototypeOf, __proto__) RegExp exec and derived APIs JSON stringify/parse the DOM (WebIDL, provides lots of options vis [TreatUndefinedAs]] to explicitly control the mapping of undefined) More examples... event objects created by DOM APIs use null as the initial value of any data property whose value won't be known until an actual event has occurred. See: http://www.w3.org/TR/webmessaging/ http://www.w3.org/TR/2012/WD-DOM-Level-3-Events-20120614/ snip One way to have it both ways is to have multiple syntactic forms for default value initializers. EG: function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical. I agree with this entirely. ||= is complementary to || and makes sense - developers will embrace this as is. ?? and ??= seem like something is unknown and unknown things can otherwise be described as undefined. Definitively, |null| is intentional -- which implies something known and therefore cannot qualify as undefined. I think sticking to undefined will help to fix the abused == null patterns in extant code (I'm thinking in the long term of course) If null testing is needed: a = a != null ? a : default; I realize that the strawman currently spells it ?:, consider this message an opposition to that. Rick Allen ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 4:04 PM, Rick Waldron waldron.r...@gmail.comwrote: I realize that the strawman currently spells it ?:, consider this message an opposition to that. This has been an extension to C for quite some time, and it means specifically to use the condition value if it is truthy (and is itself derived from the behavior of a ? a : b). I think it would be a mistake to change that behavior from what is expected. -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Rick Waldron wrote: One way to have it both ways is to have multiple syntactic forms for default value initializers. EG: function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical. I agree with this entirely. Including the part where Allen is not convinced to add all these forms? I can see adding ?? and ??= (undefined-only, not undefined-or-null). Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind. Given ||= is there any oxygen left in the room for ??=? /be ||= is complementary to || and makes sense - developers will embrace this as is. ?? and ??= seem like something is unknown and unknown things can otherwise be described as undefined. Definitively, |null| is intentional -- which implies something known and therefore cannot qualify as undefined. I think sticking to undefined will help to fix the abused == null patterns in extant code (I'm thinking in the long term of course) If null testing is needed: a = a != null ? a : default; ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 5:32 PM, T.J. Crowder t...@crowdersoftware.comwrote: Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind. Nice-to-have. The fact it doesn't assign if the left side is truthy is the only reason for having it, surely? Plus not even evaluating the RHS if the LHS is truthy -- useful if the default is an expensive calculation. -- John A. Tamplin Software Engineer (GWT), Google ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 6:06 PM, Aymeric Vitte vitteayme...@gmail.comwrote: This discussion I think is going into a useless complexity. Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here There doesn't need to be an explicit check for undefined - anytime null is used as an intentional place holder and its value would be _otherwise_ undefined counts as well. And for your information, I am not w3c and I use null frequently (the same way w3c uses it). Rick Le 14/06/2012 23:16, Rick Waldron a écrit : On Thu, Jun 14, 2012 at 3:45 PM, Brendan Eich bren...@mozilla.com wrote: Rick Waldron wrote: One way to have it both ways is to have multiple syntactic forms for default value initializers. EG: function f(a = 1, b ??= 2, c ||= 3) { } //assuming ??= is undefined or null defaulting guard and ||= is falsy I'm not particularly convinced that the additional complexity is warranted but it would place the choice into ES programmers hands rather us trying to anticipate the typical intent and disadvantaging the untypical. I agree with this entirely. Including the part where Allen is not convinced to add all these forms? Yes. ...But it felt useful to note that ||= would compliment || and immediately understood by devs I can see adding ?? and ??= (undefined-only, not undefined-or-null). Yes, absolutely. Is ||= really worth it? It would not assign if the left side is truthy, but perhaps no one will mind. That makes complete sense to me, but again - it might not be worth adding, because a = b || c isn't that painful. Given ||= is there any oxygen left in the room for ??=? Right now, I believe the whole set compliment the current language and its operators nicely - but if it came down to one or the other, I would prefer seeing the new addition of ?? and ??= Rick /be ||= is complementary to || and makes sense - developers will embrace this as is. ?? and ??= seem like something is unknown and unknown things can otherwise be described as undefined. Definitively, |null| is intentional -- which implies something known and therefore cannot qualify as undefined. I think sticking to undefined will help to fix the abused == null patterns in extant code (I'm thinking in the long term of course) If null testing is needed: a = a != null ? a : default; ___ es-discuss mailing listes-discuss@mozilla.orghttps://mail.mozilla.org/listinfo/es-discuss -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Thu, Jun 14, 2012 at 4:06 PM, Aymeric Vitte vitteayme...@gmail.com wrote: Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here Your experience isn't necessarily universal. I've used null before to mean something different than undefined. ~TJ ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Just clarifying -- we all agree that any such thing is too late for ES6, right? On this assumption, I'm postponing engaging in this thread until I have time. On Fri, Jun 15, 2012 at 4:43 AM, Brendan Eich bren...@mozilla.com wrote: Yes, I'm about to bail back to ??. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Before... I put Rick's answer below too, in strict/correct code it can be used but what examples (except yours) ? Maybe I missed it, never saw the use of null since a long time, but I can be wrong Do you think it does worth the complexity for the operators we are talking about ? w3c is forced to define something as null, would look strange and not serious to define it as undefined in specs, but in reality this is let to the appreciation of developers (who usually don't care), and for comparisons/default, null will, I think, never be used, then it should probably behave the same as undefined Le 15/06/2012 01:12, Tab Atkins Jr. a écrit : On Thu, Jun 14, 2012 at 4:06 PM, Aymeric Vittevitteayme...@gmail.com wrote: Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here Your experience isn't necessarily universal. I've used null before to mean something different than undefined. ~TJ There doesn't need to be an explicit check for undefined - anytime null is used as an intentional place holder and its value would be _otherwise_ undefined counts as well. And for your information, I am not w3c and I use null frequently (the same way w3c uses it). -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Just to be clear I am talking about the use of null in the scope of the current discussion (ie operators/default) only Le 15/06/2012 01:37, Aymeric Vitte a écrit : Before... I put Rick's answer below too, in strict/correct code it can be used but what examples (except yours) ? Maybe I missed it, never saw the use of null since a long time, but I can be wrong The difference is known, do you think it does worth the complexity for the operators we are talking about ? w3c is forced to define something as null, would look strange and not serious to define it as undefined in specs, but in reality this is let to the appreciation of developers (who usually don't care), and for comparisons/default, null will, I think, never be used, then it should probably behave the same as undefined Le 15/06/2012 01:12, Tab Atkins Jr. a écrit : On Thu, Jun 14, 2012 at 4:06 PM, Aymeric Vittevitteayme...@gmail.com wrote: Nobody (except w3c) is using null, or when someone is using it, it is the same way as undefined, and it is not explicit (ie a||b or a==b, not a===null), I remind some old code where we could see the use of null but can not find a single example of recent code, then the new operator(s) should treat it the same way I believe, the problem is 0 here Your experience isn't necessarily universal. I've used null before to mean something different than undefined. ~TJ There doesn't need to be an explicit check for undefined - anytime null is used as an intentional place holder and its value would be _otherwise_ undefined counts as well. And for your information, I am not w3c and I use null frequently (the same way w3c uses it). -- jCore Email :avi...@jcore.fr Web :www.jcore.fr Webble :www.webble.it Extract Widget Mobile :www.extractwidget.com BlimpMe! :www.blimpme.com -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
I don't think it matters yet, this is fair game for es-discuss as a harmony strawman. But it does connect to parameter default values, where we have open issues that come up here too. Worth skimming IMHO. /be On Jun 14, 2012, at 6:35 PM, Mark S. Miller erig...@google.com wrote: Just clarifying -- we all agree that any such thing is too late for ES6, right? On this assumption, I'm postponing engaging in this thread until I have time. On Fri, Jun 15, 2012 at 4:43 AM, Brendan Eich bren...@mozilla.com wrote: Yes, I'm about to bail back to ??. -- Cheers, --MarkM ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On 13 June 2012 06:52, Brendan Eich bren...@mozilla.org wrote: People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see I'm with Dave on this, I do it fairly regularly, usually when a function turns around and calls another one with the arg and has no other use for the arg: function doSomethingNifty(a, b) { return doSomethingVerbose({ x: 1, y: a, z: b ?: 5 // ... }); } ?= looks great, and Wes' point about confusion re ||= (or even |||=) and boolean logical operators definitely kills my preferred ||| for the non-assignment form if there's going to be an assignment form -- and we all want an assignment form. Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message: a = b ?? c : d; meaning a = b !== undefined ? c : d; Or that we want it (now, or in reserve) for something else? Because if not, I'd prefer to see ?? rather than ?:. It's easier to type and the double ??calls back to the related ||. But again, only if we don't want ?? (now, or in reserve) for something else. Very much looking forward to ?: (however we spell it) and ?=. -- T.J. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Indeed, maybe both should be included. What about this case : if (typeof(api)==undefined) {try later} else if (!api.a) {try later} else if (!api.a.b)) {try later} else if (etc...) which can be written : if (!(((typeof(api)!=undefined?api.a:undefined)?api.a.b:undefined)?api.a.b.c:undefined)) {try later} but can't be written with ?: The best in that case would be to be able to do : if (!api.a.b.c) {try later} Why in accessors the attempt to access a property of |undefined| could not return |undefined| itself ? Le 13/06/2012 09:45, T.J. Crowder a écrit : On 13 June 2012 06:52, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see I'm with Dave on this, I do it fairly regularly, usually when a function turns around and calls another one with the arg and has no other use for the arg: function doSomethingNifty(a, b) { return doSomethingVerbose({ x: 1, y: a, z: b ?: 5 // ... }); } ?= looks great, and Wes' point about confusion re ||= (or even |||=) and boolean logical operators definitely kills my preferred ||| for the non-assignment form if there's going to be an assignment form -- and we all want an assignment form. Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message: a = b ?? c : d; meaning a = b !== undefined ? c : d; Or that we want it (now, or in reserve) for something else? Because if not, I'd prefer to see ?? rather than ?:. It's easier to type and the double ?? calls back to the related ||. But again, only if we don't want ?? (now, or in reserve) for something else. Very much looking forward to ?: (however we spell it) and ?=. -- T.J. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On 13 June 2012 03:45, T.J. Crowder t...@crowdersoftware.com wrote: Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message: Something else to consider; if we use (a ?: b), it would have to be equivalent to (a ? a : b) with the exception that a is only evaluated once, just as it is in gcc. Any other meaning would be confusing to end users, due to the strong resemblance to the ternary operator. The use-case here seems to be that it would have the value a whenever a is undefined, not when a is truey. This is a tricky enough difference that I think it mandates a different operator, like ??. That said, I don't think I have ever seen code like that in the field, where the caller sorts out the default values instead of the callee.* * later edit: I thought this was true, but see that I have been unwittingly using this idiom myself for years, see examples below. Very much looking forward to ?: (however we spell it) and ?=. Me too. They are all over my C code and Makefiles. Random usage (food for thought): memcpy(newHnd-buffer, thisHnd-buffer, min(length, newHnd-length ?: length)); const char *filename = gpsee_programRelativeFilename(cx, report-filename) ?: unknown filename; JS_SetGCParameter(rt, JSGC_MAX_BYTES, (size_t)strtol(rc_default_value(rc, gpsee_gc_maxbytes, 0), NULL, 0) ?: (size_t)-1); So, as you can see above, I tend to use ?: to supply default behaviour to functions when necessary, particularly when they are library functions out of my control. GPSEE_SRC_DIR ?= $(shell pwd) GREP ?= grep EGREP ?= egrep MAKEDEPEND?= gcc -E -MM -MG NCURSES_LIB_NAME ?= ncurses BIN_DIR?= $(GPSEE_PREFIX_DIR)/bin I use the ?= idiom quite heavily in my Makefiles as we don't use autoconf. We simply have a configure script which generates an include file of stuff that's different for this platform, which gets included before the stuff that's assigned with the ?=. Also, the ?= allows the developer to override particular variables from environment variables passed to make, i.e. to install into a different target directory, use a different version of gcc, etc. This is idiom is especially powerful with Make's late evaluation of variables, but I don't think we should go there in ES. Wes -- Wesley W. Garland Director, Product Development PageMail, Inc. +1 613 542 2787 x 102 ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
Typo below, I meant which can be written : if (!(((typeof(api)!=undefined??api.a:undefined)??api.a.b:undefined)??api.a.b.c:undefined)) {try later} Le 13/06/2012 12:12, Aymeric Vitte a écrit : Indeed, maybe both should be included. What about this case : if (typeof(api)==undefined) {try later} else if (!api.a) {try later} else if (!api.a.b)) {try later} else if (etc...) which can be written : if (!(((typeof(api)!=undefined?api.a:undefined)?api.a.b:undefined)?api.a.b.c:undefined)) {try later} but can't be written with ?: The best in that case would be to be able to do : if (!api.a.b.c) {try later} Why in accessors the attempt to access a property of |undefined| could not return |undefined| itself ? Le 13/06/2012 09:45, T.J. Crowder a écrit : On 13 June 2012 06:52, Brendan Eich bren...@mozilla.org mailto:bren...@mozilla.org wrote: People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see I'm with Dave on this, I do it fairly regularly, usually when a function turns around and calls another one with the arg and has no other use for the arg: function doSomethingNifty(a, b) { return doSomethingVerbose({ x: 1, y: a, z: b ?: 5 // ... }); } ?= looks great, and Wes' point about confusion re ||= (or even |||=) and boolean logical operators definitely kills my preferred ||| for the non-assignment form if there's going to be an assignment form -- and we all want an assignment form. Is the reason for using ?: rather than ?? because we may want it for my desired second ternary? E.g., from my other message: a = b ?? c : d; meaning a = b !== undefined ? c : d; Or that we want it (now, or in reserve) for something else? Because if not, I'd prefer to see ?? rather than ?:. It's easier to type and the double ?? calls back to the related ||. But again, only if we don't want ?? (now, or in reserve) for something else. Very much looking forward to ?: (however we spell it) and ?=. -- T.J. ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss -- jCore Email :avi...@jcore.fr Web :www.jcore.fr Webble :www.webble.it Extract Widget Mobile :www.extractwidget.com BlimpMe! :www.blimpme.com -- jCore Email : avi...@jcore.fr Web :www.jcore.fr Webble : www.webble.it Extract Widget Mobile : www.extractwidget.com BlimpMe! : www.blimpme.com ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss
Re: ||= is much needed?
On Jun 12, 2012, at 10:52 PM, Brendan Eich wrote: People don't default on the caller side (at the callsite) much, in my experience. Dave may be seeing other sources, but it's extremely rare in my experience to see foo(arg1 || callers_idea_of_default_arg1_value); I'm sure it's more rare than the assignment form, but that's partly because the assignment form is needed to make up for lack of pdv's. whereas we all see function foo(a, b, c) { a = a || default_a; b.x = b.x || default_b_x; b.y = b.y || default_b_y; c.z = function (w) { // long body here } ... } Well, you wouldn't argue against having || in the language. Yes, I know it serves other roles as well. But only providing the assignment form strikes me as over-specialization. Operators are a straightforward generalization of assignments. When you specialize the syntax to provide an assignment form only, you force people to create temporary variables when they aren't needed. Compound expressions are good things! And why break the pattern of compound assignments being based on binary operators? Why should ?= or ??= be different from +=, -=, *=, /=, %=, =, =, =, =, |=, ^=? It just seems like a pointless restriction. Dave ___ es-discuss mailing list es-discuss@mozilla.org https://mail.mozilla.org/listinfo/es-discuss