Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Sam Ruby
On Tue, Jun 2, 2015 at 1:31 PM, Sander Deryckere sander...@gmail.com wrote:


 2015-06-02 18:57 GMT+02:00 Brendan Eich bren...@mozilla.org:

 You might hope for that, but as we both noted, `?[` is not going to fly.
 Don't break the (minified) Web.


 Which is why my proposal was about `??`. I believe there's currently no
 valid way to use a double question mark in  JS, so even `??[` should be easy
 to figure out what it means.


 The prefix idea generalizes:

 ?obj[key]
 obj[?key]
 obj[key1][?key2]

 and if you are not using computed property names, rather literal ones:

 obj.?prop1
 etc.

 I found this syntax to conflict with itself. As Andreas Rossberg says, what
 does `orders[?client.key].price` mean? Does it mean check if the client
 exists, and if not, return the price of the null order, or does it mean
 check if the order for this client exists, and return null if it doesn't?
 I don't see a way how both meanings can be made possible with this form of
 prefix notation.

Um, if I'm reading Brenden correctly, neither?

check if the client exists, and if not, return the price of the null order

===  orders[client.?key].price

check if the order for this client exists, and return null if it doesn't

=== orders[client.key].?price

I would suggest a third interpretation for `orders[?client.key].price`:

=== (orders ? orders[client.key] : null).price

I think that the problem here isn't that it is ambiguous, it is that
it isn't obvious.  Something that might be more obvious but requires
an additional character: `orders.?[client.key].price`.

More precisely, the suggestion is to standardize on .? and allow it to
be followed by either a simple name, a square bracket, or a left
paren.

 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss

- Sam Ruby
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Brendan Eich

Sam Ruby wrote:

I think that the problem here isn't that it is ambiguous, it is that
it isn't obvious.


Fair point!


Something that might be more obvious but requires
an additional character: `orders.?[client.key].price`.


That's not bad. The whole proposal may founder, though, on grawlix 
objections.


And some still want the ?obj.foo.bar to soak null/undefined obj and 
missing foo or null/undefined value of foo. CoffeeScript fans for sure, 
but it's in principle and practice at least as valid a use-case as 
obj.?foo is.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Fixing `Promise.resolve()`

2015-06-02 Thread C. Scott Ananian
Thanks!  It looks like core-js has already patched in the new spec:
https://github.com/zloirock/core-js/issues/75

I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim,
and I'll see if I can get a patch together for it.

I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against
Mozilla.
I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8.

Allen: Will this be an errata to ES6, part of ES7, or something else?
  --scott
​
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Maybe we need a reflect API to iterate over instance members

2015-06-02 Thread Tom Van Cutsem
2015-06-01 20:36 GMT+02:00 Alexander Jones a...@weej.com:


 On Monday, June 1, 2015, Tom Van Cutsem tomvc...@gmail.com wrote:


 Or since Proxy traps correspond 1-to-1 to the internal methods in the
 spec, the primary goal of the Reflect API was to expose the essential
 methods that make up Javascript's object model as defined by the spec.


 I like this definition. Is it written down? (I need ammunition for
 Reflect.type(x)!)


There's some rationale on the original wiki page for the reflect API: 
http://wiki.ecmascript.org/doku.php?id=harmony:reflect_api#purpose.

We also had a related short debate on this list 3 months ago, see 
https://esdiscuss.org/topic/reflect-getownpropertysymbols#content-0, in
particular, Allen's comment: In ES6, the primary role of the Reflect
object is to provide direct access to an object's essential internal
methods.

Regards,
Tom
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: How can I synchronously determine a JavaScript Promise's state? (Domenic Denicola)

2015-06-02 Thread Ron Waldon
Apologies if this is a duplicate: I'm new to mailing lists and got a little
bit muddled.

## legacy use case

I am maintaining an existing API that includes asynchronous functions (mix
of callbacks and Promises) and synchronous functions. After some
asynchronous initialisation, the internal state settles and it is perfectly
safe to use the synchronous functions as expected.

So, I'd like to emit warnings when these synchronous functions are called
prior to a Promise being settled. That way, downstream developers will
know that they should be waiting for the Promise to settle before using
such functions.

This actually isn't too different to the XHR / Fetch APIs conceptually. We
get the ball rolling with an asynchronous API call, but there are
deterministic blocks within which we can synchronously interrogate
progress, etc.

## activity indicator use case

I use a Promise to represent a network transaction. I wish to alter the
visual state of my web app to reflect the state of this network
transaction. I can, for example, show an indeterminate progress bar whilst
the Promise is not settled.

If I am using requestAnimationFrame, or a framework like React, then the
state would be synchronously mapped to the DOM / canvas during each
execution of my render function.

I can track the state of the Promise using additional variables (as others
have suggested), but those state values already exist somewhere private per
the functioning of a Promise. I'd be duplicating work that the JavaScript
engine is already performing internally, at the risk of introducing errors
in my code.

## third-party popular libraries

The following libraries implement some form of Promise and all expose such
synchronous inspection capabilities:

- jQuery: http://api.jquery.com/deferred.state/
- Bluebird:
https://github.com/petkaantonov/bluebird/blob/master/API.md#synchronous-inspection
- Q:
https://github.com/kriskowal/q/wiki/API-Reference#state-inspection-methods
- Lie: https://github.com/calvinmetcalf/lie/blob/master/lib/promise.js#L17



 On Tue, 2 Jun 2015 at 07:31 Domenic Denicola d...@domenic.me wrote:

 I will repeat to you what I said on Specifiction:

  To get a standard API for this, you'll need to convince the JavaScript
 standard committee, as well as the browser vendors, that your use case is
 widespread and important enough to be worth the standardization and
 implementation burden, and that it cannot be achieved in any other possible
 way.
 
  So ... go!

 Looking forward to your use cases, preferably with examples showing code
 in popular libraries or apps that would benefit to illustrate how
 wide-spread those use cases are.


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Fixing `Promise.resolve()`

2015-06-02 Thread Mark S. Miller
Hi Scott,

If the change is as simple as it appears, it seems it will go into ES6
itself!

Thanks for pushing this forward.


On Tue, Jun 2, 2015 at 1:25 PM, C. Scott Ananian ecmascr...@cscott.net
wrote:

 Thanks!  It looks like core-js has already patched in the new spec:
 https://github.com/zloirock/core-js/issues/75

 I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim,
 and I'll see if I can get a patch together for it.

 I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against
 Mozilla.
 I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8.

 Allen: Will this be an errata to ES6, part of ES7, or something else?
   --scott
 ​




-- 
Cheers,
--MarkM
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Reflect.type

2015-06-02 Thread Alexander Jones
For some strange reason esdiscuss.org has garbled that link! For the
benefit of those readers:

https://github.com/alex-weej/es-reflect-type-proposal

(Apologies for spam)

On 2 June 2015 at 23:10, Alexander Jones a...@weej.com wrote:

 I've written this up as a strawman. It's available at
 https://github.com/alex-weej/es-reflect-type-proposal

 Thanks

 On 15 May 2015 at 00:37, Alexander Jones a...@weej.com wrote:

 I'm sure there will evolve some other nomenclature for that in due
 course. From http://www.slideshare.net/BrendanEich/value-objects2 it
 sounds as if it would be reasonable to define `Type(x)` to be `Value`, and
 thus `Reflect.type(x)` to be `Reflect.types.value`.

 Agree with the Symbol labels.


 On 14 May 2015 at 18:50, Andrea Giammarchi andrea.giammar...@gmail.com
 wrote:

 FWIW, I think whatever contains type in modern JS should consider
 `int32`, `float64`, and all TypedArrays plus it would be awesome to have a
 way to define own types.

 In any case, if your idea will be implemented, I think it should have
 named Symbols for debugging sake.

 ```js
 Symbol('undefined'),
 Symbol('null'),
 Symbol('boolean')
 ```

 This would be at least consistent with current implementations of
 `Symbol.iterator` and friends.

 Best Regards




 On Thu, May 14, 2015 at 5:29 PM, Alexander Jones a...@weej.com wrote:

 Just an idea, if it doesn't already exist somewhere.

 Reflect.type(x) would match the spec's Type(x) function, in that it
 would basically be a better, more convenient typeof, i.e.

 Reflect.types = {
 undefined: Symbol(),
 null: Symbol(),
 boolean: Symbol(),
 string: Symbol(),
 symbol: Symbol(),
 number: Symbol(),
 object: Symbol(),
 }

 Reflect.type(null) === Reflect.types.null
 Reflect.type(function() {}) === Reflect.types.object

 We weren't able to fix typeof null in harmony, but this seems like a
 good opportunity to introduce something new. Haven't thought about the
 repercussions of future support for new value types...

 Any thoughts?

 ___
 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: Reflect.type

2015-06-02 Thread Alexander Jones
I've written this up as a strawman. It's available at
https://github.com/alex-weej/es-reflect-type-proposal

Thanks

On 15 May 2015 at 00:37, Alexander Jones a...@weej.com wrote:

 I'm sure there will evolve some other nomenclature for that in due course.
 From http://www.slideshare.net/BrendanEich/value-objects2 it sounds as if
 it would be reasonable to define `Type(x)` to be `Value`, and thus
 `Reflect.type(x)` to be `Reflect.types.value`.

 Agree with the Symbol labels.


 On 14 May 2015 at 18:50, Andrea Giammarchi andrea.giammar...@gmail.com
 wrote:

 FWIW, I think whatever contains type in modern JS should consider
 `int32`, `float64`, and all TypedArrays plus it would be awesome to have a
 way to define own types.

 In any case, if your idea will be implemented, I think it should have
 named Symbols for debugging sake.

 ```js
 Symbol('undefined'),
 Symbol('null'),
 Symbol('boolean')
 ```

 This would be at least consistent with current implementations of
 `Symbol.iterator` and friends.

 Best Regards




 On Thu, May 14, 2015 at 5:29 PM, Alexander Jones a...@weej.com wrote:

 Just an idea, if it doesn't already exist somewhere.

 Reflect.type(x) would match the spec's Type(x) function, in that it
 would basically be a better, more convenient typeof, i.e.

 Reflect.types = {
 undefined: Symbol(),
 null: Symbol(),
 boolean: Symbol(),
 string: Symbol(),
 symbol: Symbol(),
 number: Symbol(),
 object: Symbol(),
 }

 Reflect.type(null) === Reflect.types.null
 Reflect.type(function() {}) === Reflect.types.object

 We weren't able to fix typeof null in harmony, but this seems like a
 good opportunity to introduce something new. Haven't thought about the
 repercussions of future support for new value types...

 Any thoughts?

 ___
 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: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Sebastian McKenzie
This is a limitation of Babel and not at all a reflection of the actual 
specification. This restriction is imposed order to follow ES2015 semantics of 
not being able to reference `this` before `super()`. It does a pretty dumb 
check of only allowing it to be strictly after the call (ie. not before or 
inside it). Note that this is also the behaviour of Traceur and TypeScript so 
Babel is not alone with this decision. You can see extensive discussion of this 
in the issue: https://github.com/babel/babel/issues/1131

On Tue, Jun 2, 2015 at 11:36 PM, Matthew Robb matthewwr...@gmail.com
wrote:

 I was trying to demonstrate a simple method of exposing resolve and reject
 functions to someone and noticed in Babel at least you cannot do this. It
 seems as though in this case when the arrow function is called it will have
 been AFTER the call to super.
 Can someone help me understand what's going on here?
 - Matthew Robb___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Fixing `Promise.resolve()`

2015-06-02 Thread Allen Wirfs-Brock

On Jun 2, 2015, at 2:01 PM, Mark S. Miller wrote:

 Hi Scott,
 
 If the change is as simple as it appears, it seems it will go into ES6 itself!

The fix has already been made to the production copy that will be released in a 
couple weeks when we have ECMA GA approval

Allen



 
 Thanks for pushing this forward.
 
 
 On Tue, Jun 2, 2015 at 1:25 PM, C. Scott Ananian ecmascr...@cscott.net 
 wrote:
 Thanks!  It looks like core-js has already patched in the new spec: 
 https://github.com/zloirock/core-js/issues/75
 
 I've opened https://github.com/paulmillr/es6-shim/issues/344 on es6-shim, and 
 I'll see if I can get a patch together for it.
 
 I've filed https://bugzilla.mozilla.org/show_bug.cgi?id=1170742 against 
 Mozilla.
 I've filed https://code.google.com/p/v8/issues/detail?id=4161 against v8.
 
 Allen: Will this be an errata to ES6, part of ES7, or something else?
   --scott
 ​
 
 
 
 -- 
 Cheers,
 --MarkM

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Matthew Robb
I was trying to demonstrate a simple method of exposing resolve and reject
functions to someone and noticed in Babel at least you cannot do this. It
seems as though in this case when the arrow function is called it will have
been AFTER the call to super.

Can someone help me understand what's going on here?

- Matthew Robb
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Domenic Denicola
Hmm I am pretty sure Babel et al. are correct here in not allowing this. The 
super call needs to *finish* before you can use `this`. Chrome also works this 
way.

The correct workaround is

```js
let resolve, reject;
super((a, b) = {
  resolve = a;
  reject = b;
});

// use this
```

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


RE: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Sebastian McKenzie
Ah, completely right. At first glance I thought it was this similar but 
separate issue:



```js


class Foo {

  constructor(callback) {

    this.callback = callback; // just storing it!

  }

}




class Bar extends Foo {

  constructor() {

    super(() = this); // reference to `this` will throw since the behaviour of 
the super class can’t be easily inferred

  }

}



```




Shifting runtime errors to compile time isn’t always the most reliable.

On Tue, Jun 2, 2015 at 11:43 PM, Domenic Denicola d...@domenic.me wrote:

 Hmm I am pretty sure Babel et al. are correct here in not allowing this. The 
 super call needs to *finish* before you can use `this`. Chrome also works 
 this way.
 The correct workaround is
 ```js
 let resolve, reject;
 super((a, b) = {
   resolve = a;
   reject = b;
 });
 // use this
 ```___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Matthew Robb
If I thought I could make any money then I would most definitely bet that
the changes made to classes that are at the root of this problem will be
the undoing of es classes and I find myself feeling more and more like
avoiding them is the easiest thing to do.

This use-case is a perfect example of something that is EXTREMELY
unexpected which is funny because the changes are supposed to be supporting
subclassing of built-ins.

Very disheartened :(


- Matthew Robb

On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me wrote:

 Hmm I am pretty sure Babel et al. are correct here in not allowing this.
 The super call needs to *finish* before you can use `this`. Chrome also
 works this way.

 The correct workaround is

 ```js
 let resolve, reject;
 super((a, b) = {
   resolve = a;
   reject = b;
 });

 // use this
 ```


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


When should we define a function as async

2015-06-02 Thread Gray Zhang
I asked it on StackOverflow but they say it is not best fit for SO, so I tried 
to get some help here

If one of my function:

Returns a promise

Do not need to await any other functions
Do not create promise itself, it just return a promise returned by another 
function
Do not call then or catch on promises so it does not involve further async flows
Should this function be async?

For example:

async function updateUser(user) {
return await fetch('/some/url', {body: JSON.stringify(data)});
}

function growUp1(user) {
user.age++;
return updateUser(user);
}

async function growUp2(user) {
user.age++;
return await updateUser(user);
}
I think the growUp1 is more simple and have neater code with better performance 
after babel transformation (since less async generators are involved), and 
growUp2 is more robust when updateUser switches between async and sync.

Should we possibly enforce:

If a function is returning Promise, it MUST be async
If a function depends on an async function, it **MUST be async
A further question could be, if one function only contains some simple then 
calls to promise, should it become an async function and use await in all 
possible cases to eliminate then calls?



Best regards

Gray Zhang


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Logan Smyth
To clarify things, since I don't think it's been made abundantly clear, the
example that Sebastian gave would work in a standard ES6 environment,
correct? It is only if the callback were executed synchronously that the
exception would be thrown since the `this` binding has not yet been
initialized?
Transpilers however have elected to prevent this to err on the side of
ensuring that invalid ES6 allowed through because adding runtime checking
for the `this` binding would be difficult?



On Tue, Jun 2, 2015 at 7:37 PM, Brendan Eich bren...@mozilla.org wrote:

 With best intentions I must say that you are overreacting. The
 subject-line code (h/t Mark Miller for pointing me at it!) in context of
 the superclass constructor uses `this` before `super` has returned. That's
 a no-no for pretty-good reason.

 If you have a better alternative design, we needed it last month. As
 things stand, this is a thing to learn, with a workaround. What's the big
 deal?

 /be


 Matthew Robb wrote:

 If I thought I could make any money then I would most definitely bet that
 the changes made to classes that are at the root of this problem will be
 the undoing of es classes and I find myself feeling more and more like
 avoiding them is the easiest thing to do.

 This use-case is a perfect example of something that is EXTREMELY
 unexpected which is funny because the changes are supposed to be supporting
 subclassing of built-ins.

 Very disheartened :(


 - Matthew Robb

 On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto:
 d...@domenic.me wrote:

 Hmm I am pretty sure Babel et al. are correct here in not allowing
 this. The super call needs to *finish* before you can use `this`.
 Chrome also works this way.

 The correct workaround is

 ```js
 let resolve, reject;
 super((a, b) = {
   resolve = a;
   reject = b;
 });

 // use this
 ```


 ___
 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: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Kevin Smith
Hi Logan - that's correct.

On Tue, Jun 2, 2015 at 11:08 PM Logan Smyth loganfsm...@gmail.com wrote:

 To clarify things, since I don't think it's been made abundantly clear,
 the example that Sebastian gave would work in a standard ES6 environment,
 correct? It is only if the callback were executed synchronously that the
 exception would be thrown since the `this` binding has not yet been
 initialized?
 Transpilers however have elected to prevent this to err on the side of
 ensuring that invalid ES6 allowed through because adding runtime checking
 for the `this` binding would be difficult?



 On Tue, Jun 2, 2015 at 7:37 PM, Brendan Eich bren...@mozilla.org wrote:

 With best intentions I must say that you are overreacting. The
 subject-line code (h/t Mark Miller for pointing me at it!) in context of
 the superclass constructor uses `this` before `super` has returned. That's
 a no-no for pretty-good reason.

 If you have a better alternative design, we needed it last month. As
 things stand, this is a thing to learn, with a workaround. What's the big
 deal?

 /be


 Matthew Robb wrote:

 If I thought I could make any money then I would most definitely bet
 that the changes made to classes that are at the root of this problem will
 be the undoing of es classes and I find myself feeling more and more like
 avoiding them is the easiest thing to do.

 This use-case is a perfect example of something that is EXTREMELY
 unexpected which is funny because the changes are supposed to be supporting
 subclassing of built-ins.

 Very disheartened :(


 - Matthew Robb

 On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me mailto:
 d...@domenic.me wrote:

 Hmm I am pretty sure Babel et al. are correct here in not allowing
 this. The super call needs to *finish* before you can use `this`.
 Chrome also works this way.

 The correct workaround is

 ```js
 let resolve, reject;
 super((a, b) = {
   resolve = a;
   reject = b;
 });

 // use this
 ```


 ___
 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

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise sub-class: super((resolve, reject) = this) ?

2015-06-02 Thread Brendan Eich
With best intentions I must say that you are overreacting. The 
subject-line code (h/t Mark Miller for pointing me at it!) in context of 
the superclass constructor uses `this` before `super` has returned. 
That's a no-no for pretty-good reason.


If you have a better alternative design, we needed it last month. As 
things stand, this is a thing to learn, with a workaround. What's the 
big deal?


/be


Matthew Robb wrote:
If I thought I could make any money then I would most definitely bet 
that the changes made to classes that are at the root of this problem 
will be the undoing of es classes and I find myself feeling more and 
more like avoiding them is the easiest thing to do.


This use-case is a perfect example of something that is EXTREMELY 
unexpected which is funny because the changes are supposed to be 
supporting subclassing of built-ins.


Very disheartened :(


- Matthew Robb

On Tue, Jun 2, 2015 at 6:43 PM, Domenic Denicola d...@domenic.me 
mailto:d...@domenic.me wrote:


Hmm I am pretty sure Babel et al. are correct here in not allowing
this. The super call needs to *finish* before you can use `this`.
Chrome also works this way.

The correct workaround is

```js
let resolve, reject;
super((a, b) = {
  resolve = a;
  reject = b;
});

// use this
```


___
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 / Null Propagation Operator

2015-06-02 Thread Sander Deryckere
(I hope this arrives in the right thread, it's meant as a reply for
https://esdiscuss.org/topic/existential-operator-null-propagation-operator )

I very much like the proposal, our JS code is full with cases where certain
components can be null, but we need to execute an action with the component
when it's not null.

However, the collisions with existing syntax is indeed troublesome. So far,
I liked the `?.`, `?[` and `?(` operators the most.

But what should be done with cases like `obj?[1]?[2]:[3]`. Does it test
`obj?[1]` and returns `[2]` or `[3]` depending on the result, or does it
test `obj` and return `[1]?[2]` or `[3]` depending on the result.

A similar case with functions: `func1?(func2)?(func3):(func4)`. Does it
test `func1?(func2)`, or can it return `(func2)?(func3)`?

Both cases depend on the binding to the `:` of the ternary operator. Which
might cause too many changes to the spec, and too many exceptions to keep
the language compatible.

The `.?` operator seems to have no alternative for variable keys
(`obj[key]`), which is IMO the most usefull use-case (testing explicitly
for null is most likely to happen when you don't know a lot about the
object when writing the code, so likely you also don't know the key). As
such `.?` isn't an option for me.

For the prefix operator, it's unclear to me how you would do the following:
Say you know `obj` is non-null, you want to test if it has a key `k1`, but
if `k1` exists, you know it will also have a key `k2` a level deeper. With
the suffix operator, this would be `obj[k1]?[k2]`, but with the prefix
operator, it could be `obj?[k1][k2]` (which again has the same problems as
first described with the `?[` operator), while it could also be
`obj[?k1][k2]` (which even conflicts with itself, as it could also test if
`k1` as a variable is non-null).

As such, all these proposals have at least as many issues as `?.`. And `?.`
already has too many issues to implement it.

So, I'd like to propose another operator: `??` (with `??[` and `??(`)

In current syntax, the `?` is only used for the ternary operator, and
requires something else before and after it. Which means that any code that
has `??` is currently invalid.

We currently sometimes use the logical  to test nullness of a value, and
access its properties. Like:

`var result = obj  obj.key;`

Which tests if `obj` exists (assuming obj is an object when defined), and
returns `obj.key` if it does. With the `??` operator, it can be simplified
to

`var result = obj??key;`

Combined with `arr??[idx]` and `func??(arg)`, I think this will work very
fine.

Regards,
Sander
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Actual WeakSet Use Cases

2015-06-02 Thread Caitlin Potter
You could use it to avoid bugs involving circular references when iterating, 
for example:

```js
function iterate(O, fn) {
  if (O == null) return O;
  let objects = new WeakSet();
  iterate_inner(‘’, O, objects, fn);
  return O;

  function iterate_inner(name, O, objects, fn) {
for (let key of Reflect.ownKeys(O)) {
  let value = O[key];
  let niceName = name ? `${name}.${key}` : key;

  if (typeof value === “object”  value) {
// Avoid recursing into circular reference
if (objects.has(value)) {
  continue;
} else {
   fn(value, niceName);
   objects.add(value);
   iterate_inner(niceName, value, objects, fn);
}
  } else {
fn(value, niceName);
  }
}
  }
}
```

 On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me wrote:
 
 WeakSets are perfect for branding and are how I would expect web platform 
 class branding to be explained.
 
 ```js
 const foos = new WeakSet();
 
 class Foo {
  constructor() {
foos.add(this);
  }
 
  method() {
if (!foos.has(this)) {
  throw new TypeError(Foo.prototype.method called on an incompatible 
 object!);
}
  }
 }
 ```
 
 ___
 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: Actual WeakSet Use Cases

2015-06-02 Thread Erik Arvidsson
Caitlin, in that example a normal Set works just as well. It can get gc'ed
when you leave the iterate function.

On Tue, Jun 2, 2015, 11:25 Caitlin Potter caitpotte...@gmail.com wrote:

 You could use it to avoid bugs involving circular references when
 iterating, for example:

 ```js
 function iterate(O, fn) {
   if (O == null) return O;
   let objects = new WeakSet();
   iterate_inner(‘’, O, objects, fn);
   return O;

   function iterate_inner(name, O, objects, fn) {
 for (let key of Reflect.ownKeys(O)) {
   let value = O[key];
   let niceName = name ? `${name}.${key}` : key;

   if (typeof value === “object”  value) {
 // Avoid recursing into circular reference
 if (objects.has(value)) {
   continue;
 } else {
fn(value, niceName);
objects.add(value);
iterate_inner(niceName, value, objects, fn);
 }
   } else {
 fn(value, niceName);
   }
 }
   }
 }
 ```

  On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me wrote:
 
  WeakSets are perfect for branding and are how I would expect web
 platform class branding to be explained.
 
  ```js
  const foos = new WeakSet();
 
  class Foo {
   constructor() {
 foos.add(this);
   }
 
   method() {
 if (!foos.has(this)) {
   throw new TypeError(Foo.prototype.method called on an incompatible
 object!);
 }
   }
  }
  ```
 
  ___
  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: Actual WeakSet Use Cases

2015-06-02 Thread Domenic Denicola
WeakSets are perfect for branding and are how I would expect web platform class 
branding to be explained.

```js
const foos = new WeakSet();

class Foo {
  constructor() {
foos.add(this);
  }
  
  method() {
if (!foos.has(this)) {
  throw new TypeError(Foo.prototype.method called on an incompatible 
object!);
}
  }
}
```

___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Actual WeakSet Use Cases

2015-06-02 Thread Benjamin Gruenaum
So umm... not to be annoying but I've been digging through esdiscuss and
various blog posts online. I couldn't really find any use case for WeakSet
(plenty of threads about naming things :P).

Most material about it online fails to distinguish it from what one would
use a regular Set for. All the use cases I know for `WeakSet` for tagging
objects aren't really relevant in JS (for example - in shared memory
threading scenarios).

Can someone show me a convincing actual use case for WeakSet that can't
better be solved without it?

Thanks, and sorry,
Benjamin
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Actual WeakSet Use Cases

2015-06-02 Thread Caitlin Potter
Yes, we had that discussion on #whatwg already, I haven’t had my coffee yet =)


 On Jun 2, 2015, at 11:33 AM, Erik Arvidsson erik.arvids...@gmail.com wrote:
 
 Caitlin, in that example a normal Set works just as well. It can get gc'ed 
 when you leave the iterate function.
 
 
 On Tue, Jun 2, 2015, 11:25 Caitlin Potter caitpotte...@gmail.com 
 mailto:caitpotte...@gmail.com wrote:
 You could use it to avoid bugs involving circular references when iterating, 
 for example:
 
 ```js
 function iterate(O, fn) {
   if (O == null) return O;
   let objects = new WeakSet();
   iterate_inner(‘’, O, objects, fn);
   return O;
 
   function iterate_inner(name, O, objects, fn) {
 for (let key of Reflect.ownKeys(O)) {
   let value = O[key];
   let niceName = name ? `${name}.${key}` : key;
 
   if (typeof value === “object”  value) {
 // Avoid recursing into circular reference
 if (objects.has(value)) {
   continue;
 } else {
fn(value, niceName);
objects.add(value);
iterate_inner(niceName, value, objects, fn);
 }
   } else {
 fn(value, niceName);
   }
 }
   }
 }
 ```
 
  On Jun 2, 2015, at 11:14 AM, Domenic Denicola d...@domenic.me 
  mailto:d...@domenic.me wrote:
 
  WeakSets are perfect for branding and are how I would expect web platform 
  class branding to be explained.
 
  ```js
  const foos = new WeakSet();
 
  class Foo {
   constructor() {
 foos.add(this);
   }
 
   method() {
 if (!foos.has(this)) {
   throw new TypeError(Foo.prototype.method called on an incompatible 
  object!);
 }
   }
  }
  ```
 
  ___
  es-discuss mailing list
  es-discuss@mozilla.org mailto:es-discuss@mozilla.org
  https://mail.mozilla.org/listinfo/es-discuss 
  https://mail.mozilla.org/listinfo/es-discuss
 
 ___
 es-discuss mailing list
 es-discuss@mozilla.org mailto:es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss 
 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 / Null Propagation Operator

2015-06-02 Thread Brendan Eich

Sander Deryckere wrote:
For the prefix operator, it's unclear to me how you would do the 
following: Say you know `obj` is non-null, you want to test if it has 
a key `k1`, but if `k1` exists, you know it will also have a key `k2` 
a level deeper. With the suffix operator, this would be 
`obj[k1]?[k2]`, but with the prefix operator, it could be `obj?[k1][k2]`


You circled back to the incompatible syntax, `?[`, but the prefix idea 
would have `?obj[k1][k2]`. The `?` goes in front at the start of an 
operand, and is thus unambiguous with respect to the ternary operator.


/be
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Actual WeakSet Use Cases

2015-06-02 Thread Benjamin Gruenaum
Thanks Domenic,

Elaborating on your example with more details. Let's say you need to make
sure at a certain point that an object has not been tinkered with by user
code (for security reasons). You can't check the prototype or a symbol
since those can be faked and you can't keep a regular `Set` because that
would prevent any `Foo` object from ever being garbage collected.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Actual WeakSet Use Cases

2015-06-02 Thread Tab Atkins Jr.
On Tue, Jun 2, 2015 at 8:45 AM, Benjamin Gruenaum benjami...@gmail.com wrote:
 Thanks Domenic,

 Elaborating on your example with more details. Let's say you need to make
 sure at a certain point that an object has not been tinkered with by user
 code (for security reasons). You can't check the prototype or a symbol since
 those can be faked and you can't keep a regular `Set` because that would
 prevent any `Foo` object from ever being garbage collected.

Exactly.  WeakSet's use-cases are all in the same family as WeakMap,
just with a simpler set-up - rather than associating arbitrary data
with the object, you just associate is in this set with it.

~TJ
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Sander Deryckere
2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org:

 Sander Deryckere wrote:

 For the prefix operator, it's unclear to me how you would do the
 following: Say you know `obj` is non-null, you want to test if it has a key
 `k1`, but if `k1` exists, you know it will also have a key `k2` a level
 deeper. With the suffix operator, this would be `obj[k1]?[k2]`, but with
 the prefix operator, it could be `obj?[k1][k2]`


 You circled back to the incompatible syntax, `?[`, but the prefix idea
 would have `?obj[k1][k2]`. The `?` goes in front at the start of an
 operand, and is thus unambiguous with respect to the ternary operator.


The question is not about the existence of `obj`, but if `obj` has a key
`k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, which I
don't need in this example. To test the existence of a key inside `obj`, a
prefix operator should come somewhere before the key.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Brendan Eich

Sander Deryckere wrote:
2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org 
mailto:bren...@mozilla.org:


Sander Deryckere wrote:

For the prefix operator, it's unclear to me how you would do
the following: Say you know `obj` is non-null, you want to
test if it has a key `k1`, but if `k1` exists, you know it
will also have a key `k2` a level deeper. With the suffix
operator, this would be `obj[k1]?[k2]`, but with the prefix
operator, it could be `obj?[k1][k2]`


You circled back to the incompatible syntax, `?[`, but the prefix
idea would have `?obj[k1][k2]`. The `?` goes in front at the start
of an operand, and is thus unambiguous with respect to the ternary
operator.


The question is not about the existence of `obj`, but if `obj` has a 
key `k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, 
which I don't need in this example. To test the existence of a key 
inside `obj`, a prefix operator should come somewhere before the key.


You might hope for that, but as we both noted, `?[` is not going to fly. 
Don't break the (minified) Web.


The prefix idea generalizes:

?obj[key]
obj[?key]
obj[key1][?key2]

and if you are not using computed property names, rather literal ones:

obj.?prop1
etc.

/be


___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Andreas Rossberg
On 2 June 2015 at 18:57, Brendan Eich bren...@mozilla.org wrote:

 Sander Deryckere wrote:

 2015-06-02 17:49 GMT+02:00 Brendan Eich bren...@mozilla.org mailto:
 bren...@mozilla.org:


 Sander Deryckere wrote:

 For the prefix operator, it's unclear to me how you would do
 the following: Say you know `obj` is non-null, you want to
 test if it has a key `k1`, but if `k1` exists, you know it
 will also have a key `k2` a level deeper. With the suffix
 operator, this would be `obj[k1]?[k2]`, but with the prefix
 operator, it could be `obj?[k1][k2]`


 You circled back to the incompatible syntax, `?[`, but the prefix
 idea would have `?obj[k1][k2]`. The `?` goes in front at the start
 of an operand, and is thus unambiguous with respect to the ternary
 operator.


 The question is not about the existence of `obj`, but if `obj` has a key
 `k1`. AFAICS, `?obj[k1][k2]` would test the existence of `obj`, which I
 don't need in this example. To test the existence of a key inside `obj`, a
 prefix operator should come somewhere before the key.


 You might hope for that, but as we both noted, `?[` is not going to fly.
 Don't break the (minified) Web.

 The prefix idea generalizes:

 ?obj[key]
 obj[?key]
 obj[key1][?key2]


Hm, what's the meaning of

a[?b[c]]

?

/Andreas
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Existential Operator / Null Propagation Operator

2015-06-02 Thread Sander Deryckere
2015-06-02 18:57 GMT+02:00 Brendan Eich bren...@mozilla.org:

 You might hope for that, but as we both noted, `?[` is not going to fly.
 Don't break the (minified) Web.


Which is why my proposal was about `??`. I believe there's currently no
valid way to use a double question mark in  JS, so even `??[` should be
easy to figure out what it means.


 The prefix idea generalizes:

 ?obj[key]
 obj[?key]
 obj[key1][?key2]

 and if you are not using computed property names, rather literal ones:

 obj.?prop1
 etc.


I found this syntax to conflict with itself. As Andreas Rossberg says, what
does `orders[?client.key].price` mean? Does it mean check if the client
exists, and if not, return the price of the null order, or does it mean
check if the order for this client exists, and return null if it doesn't?
I don't see a way how both meanings can be made possible with this form of
prefix notation.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss