Re: Promise capability support

2018-07-19 Thread kai zhu
my use-case is the exact opposite.  in integration-level javascript,
its impractical to have independent rejectors/error-handlers for
dozens of integrated-components.  its much easier to debug/refactor
integration-code with a single, universal rejector/error-handler (all
it does is log the error-stack and return a 404/500 to the
server-request, or crash the app if client-side).

on server-side, you can't do much except 404/500 if the db-request
times-out, JSON.parse fails, etc.

on client-side, crashing the app (and notifying user an error occured,
and retry the request)  is pretty much the only thing you can do when
the server 404/500's.

On 7/20/18, Bob Myers  wrote:
> I've used this pattern exactly twice in the large-scale app I'm working on
> now.
> One of those I was able to eliminate after I thought harder about the
> problem.
> The other I eventually replaced with the following kind of pattern:
>
> ```
> function createPromise(resolver, rejector) {
>   return new Promise((resolve, reject) {
> resolver.then(resolve);
> rejector.then(reject);
> });
> }
> ```
>
> Obviously the way this works it that to create a promise "controllable"
> from "the outside",
> you create your own resolver and rejector promises to pass to
> `createPromise`,
> such that they trigger when you need them to.
> To put it a different way, instead of getting back and passing around
> deferred-like objects,
> which seems to be a massive anti-pattern to me,
> the client creates their own promise-controlling promises designed to
> trigger at the right time.
>
> Bob
>
> On Fri, Jul 20, 2018 at 9:07 AM Jordan Harband  wrote:
>
>> I don't think the Deferred pattern is a good primitive to have in the
>> language, and it's a pretty trivial primitive to write yourself if you
>> need
>> it.
>>
>> On Thu, Jul 19, 2018 at 6:13 PM, Isiah Meadows 
>> wrote:
>>
>>> Sometimes, it's *very* convenient to have those `resolve`/`reject`
>>> functions as separate functions. However, when logic gets complex
>>> enough and you need to send them elsewhere, save a continuation, etc.,
>>> it'd be much more convenient to just have a capability object exposed
>>> more directly rather than go through the overhead and boilerplate of
>>> going through the constructor with all its callback stuff and
>>> everything.
>>>
>>> It's surprisingly not as uncommon as you'd expect for me to do this:
>>>
>>> ```js
>>> let resolve, reject
>>> let promise = new Promise((res, rej) => {
>>> resolve = res
>>> reject = rej
>>> })
>>> ```
>>>
>>> But doing this repeatedly gets *old*, especially when you've had to
>>> write it several dozen times already. And it comes up frequently when
>>> you're writing lower-level async utilities that require saving promise
>>> state and resolving it in a way that's decoupled from the promise
>>> itself.
>>>
>>> -
>>>
>>> So here's what I propose:
>>>
>>> - `Promise.newCapability()` - This basically returns the result of
>>> [this][1], just wrapped in a suitable object whose prototype is
>>> %PromiseCapabilityPrototype% (internal, no direct constructor). It's
>>> subclass-safe, so you can do it with subclasses as appropriate, too.
>>> - `capability.resolve(value)` - This invokes the implicit resolver
>>> created for it, spec'd as [[Resolve]].
>>> - `capability.reject(value)` - This invokes the implicit rejector
>>> created for it, spec'd as [[Reject]].
>>> - `capability.promise` - This returns the newly created promise.
>>>
>>> Yes, this is effectively a deferred API, but revealing constructors
>>> are a bit too rigid and wasteful for some use cases.
>>>
>>> [1]: https://tc39.github.io/ecma262/#sec-newpromisecapability
>>>
>>> -
>>>
>>> Isiah Meadows
>>> m...@isiahmeadows.com
>>> www.isiahmeadows.com
>>> ___
>>> 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 capability support

2018-07-19 Thread Bob Myers
I've used this pattern exactly twice in the large-scale app I'm working on
now.
One of those I was able to eliminate after I thought harder about the
problem.
The other I eventually replaced with the following kind of pattern:

```
function createPromise(resolver, rejector) {
  return new Promise((resolve, reject) {
resolver.then(resolve);
rejector.then(reject);
});
}
```

Obviously the way this works it that to create a promise "controllable"
from "the outside",
you create your own resolver and rejector promises to pass to
`createPromise`,
such that they trigger when you need them to.
To put it a different way, instead of getting back and passing around
deferred-like objects,
which seems to be a massive anti-pattern to me,
the client creates their own promise-controlling promises designed to
trigger at the right time.

Bob

On Fri, Jul 20, 2018 at 9:07 AM Jordan Harband  wrote:

> I don't think the Deferred pattern is a good primitive to have in the
> language, and it's a pretty trivial primitive to write yourself if you need
> it.
>
> On Thu, Jul 19, 2018 at 6:13 PM, Isiah Meadows 
> wrote:
>
>> Sometimes, it's *very* convenient to have those `resolve`/`reject`
>> functions as separate functions. However, when logic gets complex
>> enough and you need to send them elsewhere, save a continuation, etc.,
>> it'd be much more convenient to just have a capability object exposed
>> more directly rather than go through the overhead and boilerplate of
>> going through the constructor with all its callback stuff and
>> everything.
>>
>> It's surprisingly not as uncommon as you'd expect for me to do this:
>>
>> ```js
>> let resolve, reject
>> let promise = new Promise((res, rej) => {
>> resolve = res
>> reject = rej
>> })
>> ```
>>
>> But doing this repeatedly gets *old*, especially when you've had to
>> write it several dozen times already. And it comes up frequently when
>> you're writing lower-level async utilities that require saving promise
>> state and resolving it in a way that's decoupled from the promise
>> itself.
>>
>> -
>>
>> So here's what I propose:
>>
>> - `Promise.newCapability()` - This basically returns the result of
>> [this][1], just wrapped in a suitable object whose prototype is
>> %PromiseCapabilityPrototype% (internal, no direct constructor). It's
>> subclass-safe, so you can do it with subclasses as appropriate, too.
>> - `capability.resolve(value)` - This invokes the implicit resolver
>> created for it, spec'd as [[Resolve]].
>> - `capability.reject(value)` - This invokes the implicit rejector
>> created for it, spec'd as [[Reject]].
>> - `capability.promise` - This returns the newly created promise.
>>
>> Yes, this is effectively a deferred API, but revealing constructors
>> are a bit too rigid and wasteful for some use cases.
>>
>> [1]: https://tc39.github.io/ecma262/#sec-newpromisecapability
>>
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>> ___
>> 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 capability support

2018-07-19 Thread Jordan Harband
I don't think the Deferred pattern is a good primitive to have in the
language, and it's a pretty trivial primitive to write yourself if you need
it.

On Thu, Jul 19, 2018 at 6:13 PM, Isiah Meadows 
wrote:

> Sometimes, it's *very* convenient to have those `resolve`/`reject`
> functions as separate functions. However, when logic gets complex
> enough and you need to send them elsewhere, save a continuation, etc.,
> it'd be much more convenient to just have a capability object exposed
> more directly rather than go through the overhead and boilerplate of
> going through the constructor with all its callback stuff and
> everything.
>
> It's surprisingly not as uncommon as you'd expect for me to do this:
>
> ```js
> let resolve, reject
> let promise = new Promise((res, rej) => {
> resolve = res
> reject = rej
> })
> ```
>
> But doing this repeatedly gets *old*, especially when you've had to
> write it several dozen times already. And it comes up frequently when
> you're writing lower-level async utilities that require saving promise
> state and resolving it in a way that's decoupled from the promise
> itself.
>
> -
>
> So here's what I propose:
>
> - `Promise.newCapability()` - This basically returns the result of
> [this][1], just wrapped in a suitable object whose prototype is
> %PromiseCapabilityPrototype% (internal, no direct constructor). It's
> subclass-safe, so you can do it with subclasses as appropriate, too.
> - `capability.resolve(value)` - This invokes the implicit resolver
> created for it, spec'd as [[Resolve]].
> - `capability.reject(value)` - This invokes the implicit rejector
> created for it, spec'd as [[Reject]].
> - `capability.promise` - This returns the newly created promise.
>
> Yes, this is effectively a deferred API, but revealing constructors
> are a bit too rigid and wasteful for some use cases.
>
> [1]: https://tc39.github.io/ecma262/#sec-newpromisecapability
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
> ___
> 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


Promise capability support

2018-07-19 Thread Isiah Meadows
Sometimes, it's *very* convenient to have those `resolve`/`reject`
functions as separate functions. However, when logic gets complex
enough and you need to send them elsewhere, save a continuation, etc.,
it'd be much more convenient to just have a capability object exposed
more directly rather than go through the overhead and boilerplate of
going through the constructor with all its callback stuff and
everything.

It's surprisingly not as uncommon as you'd expect for me to do this:

```js
let resolve, reject
let promise = new Promise((res, rej) => {
resolve = res
reject = rej
})
```

But doing this repeatedly gets *old*, especially when you've had to
write it several dozen times already. And it comes up frequently when
you're writing lower-level async utilities that require saving promise
state and resolving it in a way that's decoupled from the promise
itself.

-

So here's what I propose:

- `Promise.newCapability()` - This basically returns the result of
[this][1], just wrapped in a suitable object whose prototype is
%PromiseCapabilityPrototype% (internal, no direct constructor). It's
subclass-safe, so you can do it with subclasses as appropriate, too.
- `capability.resolve(value)` - This invokes the implicit resolver
created for it, spec'd as [[Resolve]].
- `capability.reject(value)` - This invokes the implicit rejector
created for it, spec'd as [[Reject]].
- `capability.promise` - This returns the newly created promise.

Yes, this is effectively a deferred API, but revealing constructors
are a bit too rigid and wasteful for some use cases.

[1]: https://tc39.github.io/ecma262/#sec-newpromisecapability

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Small Proposal "!in"

2018-07-19 Thread Jacob Pratt
> Throwing another operator name out there: what about `obj has "foo"`
instead?

As someone who has just been casually following this issue, I'd much prefer
`has` over `on`. I was going to stay quiet, but only because I didn't have
a better alternative.

jhpratt

On Thu, Jul 19, 2018 at 8:56 PM, Isiah Meadows 
wrote:

> > "on" is a good name.  Agree on separate.
>
> Throwing another operator name out there: what about `obj has "foo"`
> instead?
>
> Either way, it's a new context-sensitive keyword in a very awkward
> position.
>
> > * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> > overwrite existing properties in the assignee.
>
> Could this be a new built-in function instead? Maybe, `Object.defaults`?
>
> Of course, this is a pretty hard tangent from the original thread.
>
> > Many use cases for hasOwnProperty could be better supported by Map, Set,
> and
> > Object.create(null) including:
> > ...
> > * Configuration objects.
> > * Function options bundles.
>
> Not sure these would work well as maps, since it's far easier to just
> use dictionary objects as named arguments. Clojure and Ruby are the
> two main languages I know that use hash maps exclusively for named
> parameters with any frequency, and that's because map/hash lookup is
> as easy as property lookup.
>
> - Java and C++ use builders. (Java separates the two, while C++ merges
> them.)
> - C and Rust use structs.
> - JavaScript and Lua use simple untyped objects.
> - Kotlin, Scala, Swift, C#, Python, and Objective C use native named
> arguments that are resolved internally.
> - Even Ruby added sugar to support its common idiomatic use of hashes
> as named arguments.
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Thu, Jul 19, 2018 at 1:03 PM, Mike Samuel  wrote:
> >
> >
> > On Thu, Jul 19, 2018 at 11:56 AM Michael Theriot
> >  wrote:
> 
>  For me, `hasOwn` with the different operand order isn't a problem, but
>  others may take a different view. Trying to keep the same order takes
> us
>  down a route like `inOwn` which I can't say I care for.
> >>>
> >>>
> >>> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
> >>> footgun (especially for Colemak users) and maybe isn't clear enough
> about
> >>> its semantics.  I would argue that operators aren't camel cased in JS
> >>> though, so `hasown`/`inown`.
> >>
> >>
> >> For what it's worth I was also thinking of an "on" operator when reading
> >> this message, so this is intuitive to me. I also think that is a
> separate
> >> idea to propose though.
> >
> >
> > "on" is a good name.  Agree on separate.
> >
> >
> 
>  Of couse the usage of `in` is most of the time is not recommended, but
>  it has it place.
> >>>
> >>>
> >>> What places does it have?
> >>> I remain unconvinced that `in` has significant enough use cases to
> >>> warrant high-level ergonomics
> >>> were it being proposed today.
> >>>
> >>> It exists, and it'll probably never be removed from the language, but I
> >>> don't think it should be taught
> >>> as a good part of the language, and linters should probably flag it.
> >>
> >>
> >> Maybe a radical thought, but does this not apply to hasOwnProperty? If
> you
> >> have strong type management why test for a property? The one case I can
> >> think of is parsing JSON but I handle that with destructuring. Are there
> >> significant use cases for it? Should linters flag it?
> >
> >
> > Good questions.
> > Linters should flag
> >x.hasOwnProperty(y)
> > since if you're unsure whether x has an own property y you're probably
> > unsure whether x has an own property 'hasOwnProperty'.
> >
> > IIRC, destructuring traverses prototypes so see caveat about library code
> > and monkeypatching below.
> > const { toString: f } = {}
> > typeof f // 'funciton'
> >
> > You're right that in the middle of an application an instance's type
> should
> > determine whether a property is present.
> > There are use cases at the periphery.
> >
> > Use cases in bleeding edge JS include
> > * As you noted, operations on parsed JSON.  Even if you use revivers to
> > parse JSON to Maps instead of Objects
> >   you either need own property checks or Object.setPrototypeOf(parsed,
> null)
> > when populating the Map.
> > * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> > overwrite existing properties in the assignee.
> > * Reliable hole detection in arrays: (1 !on [0, , 2])
> > * Adapters that use naming conventions between JS objects and external
> > systems, like between database field names and JS property names.
> > * Distinguishing between user-code-defined properties on a host object
> like
> > an HTML element and readonly host properties.
> >
> > Many use cases for hasOwnProperty could be better supported by Map, Set,
> and
> > Object.create(null) including:
> > * Objects used as lookup tables.
> > * Lookup tables with special purpose fallback logic like message bundles
> > that 

Re: Small Proposal "!in"

2018-07-19 Thread Isiah Meadows
> "on" is a good name.  Agree on separate.

Throwing another operator name out there: what about `obj has "foo"` instead?

Either way, it's a new context-sensitive keyword in a very awkward position.

> * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> overwrite existing properties in the assignee.

Could this be a new built-in function instead? Maybe, `Object.defaults`?

Of course, this is a pretty hard tangent from the original thread.

> Many use cases for hasOwnProperty could be better supported by Map, Set, and
> Object.create(null) including:
> ...
> * Configuration objects.
> * Function options bundles.

Not sure these would work well as maps, since it's far easier to just
use dictionary objects as named arguments. Clojure and Ruby are the
two main languages I know that use hash maps exclusively for named
parameters with any frequency, and that's because map/hash lookup is
as easy as property lookup.

- Java and C++ use builders. (Java separates the two, while C++ merges them.)
- C and Rust use structs.
- JavaScript and Lua use simple untyped objects.
- Kotlin, Scala, Swift, C#, Python, and Objective C use native named
arguments that are resolved internally.
- Even Ruby added sugar to support its common idiomatic use of hashes
as named arguments.

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Thu, Jul 19, 2018 at 1:03 PM, Mike Samuel  wrote:
>
>
> On Thu, Jul 19, 2018 at 11:56 AM Michael Theriot
>  wrote:

 For me, `hasOwn` with the different operand order isn't a problem, but
 others may take a different view. Trying to keep the same order takes us
 down a route like `inOwn` which I can't say I care for.
>>>
>>>
>>> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
>>> footgun (especially for Colemak users) and maybe isn't clear enough about
>>> its semantics.  I would argue that operators aren't camel cased in JS
>>> though, so `hasown`/`inown`.
>>
>>
>> For what it's worth I was also thinking of an "on" operator when reading
>> this message, so this is intuitive to me. I also think that is a separate
>> idea to propose though.
>
>
> "on" is a good name.  Agree on separate.
>
>

 Of couse the usage of `in` is most of the time is not recommended, but
 it has it place.
>>>
>>>
>>> What places does it have?
>>> I remain unconvinced that `in` has significant enough use cases to
>>> warrant high-level ergonomics
>>> were it being proposed today.
>>>
>>> It exists, and it'll probably never be removed from the language, but I
>>> don't think it should be taught
>>> as a good part of the language, and linters should probably flag it.
>>
>>
>> Maybe a radical thought, but does this not apply to hasOwnProperty? If you
>> have strong type management why test for a property? The one case I can
>> think of is parsing JSON but I handle that with destructuring. Are there
>> significant use cases for it? Should linters flag it?
>
>
> Good questions.
> Linters should flag
>x.hasOwnProperty(y)
> since if you're unsure whether x has an own property y you're probably
> unsure whether x has an own property 'hasOwnProperty'.
>
> IIRC, destructuring traverses prototypes so see caveat about library code
> and monkeypatching below.
> const { toString: f } = {}
> typeof f // 'funciton'
>
> You're right that in the middle of an application an instance's type should
> determine whether a property is present.
> There are use cases at the periphery.
>
> Use cases in bleeding edge JS include
> * As you noted, operations on parsed JSON.  Even if you use revivers to
> parse JSON to Maps instead of Objects
>   you either need own property checks or Object.setPrototypeOf(parsed, null)
> when populating the Map.
> * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> overwrite existing properties in the assignee.
> * Reliable hole detection in arrays: (1 !on [0, , 2])
> * Adapters that use naming conventions between JS objects and external
> systems, like between database field names and JS property names.
> * Distinguishing between user-code-defined properties on a host object like
> an HTML element and readonly host properties.
>
> Many use cases for hasOwnProperty could be better supported by Map, Set, and
> Object.create(null) including:
> * Objects used as lookup tables.
> * Lookup tables with special purpose fallback logic like message bundles
> that fall back from locale 'aa-BB' to 'aa'.
> * Configuration objects.
> * Function options bundles.
> but idiomatic JS hasn't caught up and some library code has to run on old
> interpreters, so a transpiling `on` would be nice.
> The last two are mostly an issue in library code that needs to be resilient
> when loaded alongside monkeypatched prototypes.
>
> Honorable mention:
> * for(...in...) iteration broken
> solved by for(...of...):
>
>
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> 

Re: Feature proposal

2018-07-19 Thread Isiah Meadows
I'm not a fan of the "Iteratable" object - it doesn't align with the
corresponding existing concept of "iterables", and the iterable
protocol is just an interface - there's no named object that
corresponds to that type.

What we really need is that pipeline operator to finally get figured
out: https://github.com/tc39/proposal-pipeline-operator

That wil address the primary need for things like these, without
running you into issues of namespace collision.

-

Isiah Meadows
m...@isiahmeadows.com
www.isiahmeadows.com


On Thu, Jul 19, 2018 at 11:38 AM, Nicolas B. Pierron
 wrote:
> On Thu, Jul 19, 2018 at 12:53 PM, Nicolas B. Pierron
>  wrote:
>>> On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron
>>>  wrote:
 Stupid question, but why are some of these methods implemented on
 String, Array, TypedArray, Map and Set, while all of them are
 Iteratable?
>>>
>> Among list of nice Iteratable property that one might add, and which
>> might not be part of the standard are things like:
>>   chain, take, skip, takeWhile, skipWhile, repeat, zip, enumerate,
>> range, stepBy, …
>
> Apparently this already exists as a JS library:
> https://fitzgen.github.io/wu.js/
>
> --
> Nicolas B. Pierron
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
> one without precedent in the language

that's how languages move forward, right?

> It also means you can't `Promise.resolve.call(SubPromise)`

you can make it more complex and yet have a fallback to the invoker, not a
real issue, just more rules to write down.

```js
const withLazyBoundObjects = new WeakMap;
const withLazyBoundMethods = obj => {
  const descriptors = Object.getOwnPropertyDescriptors(obj);
  Object.keys(descriptors).forEach(key => {
const desc = descriptors[key];
const {value} = desc;
if (desc.configurable && typeof value === 'function') {
  delete desc.value;
  delete desc.writable;
  desc.get = function () {"use strict";
const self = this || obj;
let methods = withLazyBoundObjects.get(self);
if (!methods)
  withLazyBoundObjects.set(self, methods = Object.create(null));
return methods[key] || (methods[key] = function () {
  return value.apply(this || self, arguments);
});
  };
}
  });
  return Object.defineProperties(obj, descriptors);
};

withLazyBoundMethods(Promise);

class SubPromise extends Promise {}

console.log([
  (0,Promise.resolve)() instanceof SubPromise,
  Promise.resolve() instanceof SubPromise,
  (0,SubPromise.resolve)() instanceof SubPromise,
  SubPromise.resolve() instanceof SubPromise,
  Promise.resolve.call(SubPromise) instanceof SubPromise
]);

// [false, false, true, true, true]
```



On Fri, Jul 20, 2018 at 1:59 AM Jordan Harband  wrote:

> That's certainly a clever solution, but one without precedent in the
> language. It also means you can't `Promise.resolve.call(SubPromise)`,
> although perhaps you could avoid that by skipping `.bind` and creating a
> normal function wrapper inside the getter - I'm curious how that might be
> implemented as well as specified.
>
> On Thu, Jul 19, 2018 at 4:54 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> My code doesn't suffer what Domenic says.
>>
>> Once again:
>>
>> ```js
>> const withLazyBoundObjects = new WeakMap;
>> const withLazyBoundMethods = obj => {
>>   const descriptors = Object.getOwnPropertyDescriptors(obj);
>>   Object.keys(descriptors).forEach(key => {
>> const desc = descriptors[key];
>> const {value} = desc;
>> if (desc.configurable && typeof value === 'function') {
>>   delete desc.value;
>>   delete desc.writable;
>>   desc.get = function (...args) {
>> let methods = withLazyBoundObjects.get(this || obj);
>> if (!methods)
>>   withLazyBoundObjects.set(this, methods = Object.create(null));
>> return methods[key] || (methods[key] = value.bind(this));
>>   };
>> }
>>   });
>>   return Object.defineProperties(obj, descriptors);
>> };
>>
>> // patch the Promise
>> withLazyBoundMethods(Promise);
>>
>> // have a class that extends Promise
>> class SubPromise extends Promise {}
>>
>> // test inheritance
>> SubPromise.resolve() instanceof SubPromise; // true
>> (0,SubPromise.resolve)() instanceof SubPromise; // true
>>
>> // even the Promise ?
>> Promise.resolve() instanceof SubPromise; // false, it's Promise
>> (0,Promise.resolve)() instanceof SubPromise; // false, it's Promise
>> ```
>>
>> So, why cannot we have above behavior in core?
>>
>>
>>
>> On Fri, Jul 20, 2018 at 1:36 AM Jordan Harband  wrote:
>>
>>> > TL;DR why aren't public static methods that need context **all**
>>> lazily defined as bound (once) on demand? That would make every single
>>> public static method consistent, accordingly with the Class you extracted
>>> them from, right? That's not clever, that's usually developers expectations
>>> because historically all public static methods don't need the Class to work.
>>>
>>> I believe
>>> https://github.com/tc39/ecma262/issues/544#issuecomment-236487230
>>> answers this - specifically, expressing that the claimed better design is
>>> for *nothing* to be bound.
>>>
>>> On Thu, Jul 19, 2018 at 4:22 PM, Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
 Reading that looks like nobody answered my question, explained through
 some code that wouldn't have any issue with subclassing.

 So no, there's no answer to my latest question in there, unless I've
 missed it.

 On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband 
 wrote:

> This question has been answered here:
> https://github.com/tc39/ecma262/issues/544
>
> On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> > Per the KISS principle, let’s avoid to be clever.
>>
>> I think my next code example is less clever, but the only reason I've
>> written hacks or code was not to be advocated or adopted, just to explain
>> what could happen internally.
>>
>> TL;DR why aren't public static methods that need context **all**
>> lazily defined as bound (once) on demand? That would make every single
>> public static method consistent, accordingly 

Re: const {resolve} = Promise; // fails

2018-07-19 Thread Jordan Harband
That's certainly a clever solution, but one without precedent in the
language. It also means you can't `Promise.resolve.call(SubPromise)`,
although perhaps you could avoid that by skipping `.bind` and creating a
normal function wrapper inside the getter - I'm curious how that might be
implemented as well as specified.

On Thu, Jul 19, 2018 at 4:54 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> My code doesn't suffer what Domenic says.
>
> Once again:
>
> ```js
> const withLazyBoundObjects = new WeakMap;
> const withLazyBoundMethods = obj => {
>   const descriptors = Object.getOwnPropertyDescriptors(obj);
>   Object.keys(descriptors).forEach(key => {
> const desc = descriptors[key];
> const {value} = desc;
> if (desc.configurable && typeof value === 'function') {
>   delete desc.value;
>   delete desc.writable;
>   desc.get = function (...args) {
> let methods = withLazyBoundObjects.get(this || obj);
> if (!methods)
>   withLazyBoundObjects.set(this, methods = Object.create(null));
> return methods[key] || (methods[key] = value.bind(this));
>   };
> }
>   });
>   return Object.defineProperties(obj, descriptors);
> };
>
> // patch the Promise
> withLazyBoundMethods(Promise);
>
> // have a class that extends Promise
> class SubPromise extends Promise {}
>
> // test inheritance
> SubPromise.resolve() instanceof SubPromise; // true
> (0,SubPromise.resolve)() instanceof SubPromise; // true
>
> // even the Promise ?
> Promise.resolve() instanceof SubPromise; // false, it's Promise
> (0,Promise.resolve)() instanceof SubPromise; // false, it's Promise
> ```
>
> So, why cannot we have above behavior in core?
>
>
>
> On Fri, Jul 20, 2018 at 1:36 AM Jordan Harband  wrote:
>
>> > TL;DR why aren't public static methods that need context **all**
>> lazily defined as bound (once) on demand? That would make every single
>> public static method consistent, accordingly with the Class you extracted
>> them from, right? That's not clever, that's usually developers expectations
>> because historically all public static methods don't need the Class to work.
>>
>> I believe https://github.com/tc39/ecma262/issues/544#
>> issuecomment-236487230 answers this - specifically, expressing that the
>> claimed better design is for *nothing* to be bound.
>>
>> On Thu, Jul 19, 2018 at 4:22 PM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Reading that looks like nobody answered my question, explained through
>>> some code that wouldn't have any issue with subclassing.
>>>
>>> So no, there's no answer to my latest question in there, unless I've
>>> missed it.
>>>
>>> On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband  wrote:
>>>
 This question has been answered here: https://github.com/tc39/
 ecma262/issues/544

 On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
 andrea.giammar...@gmail.com> wrote:

> > Per the KISS principle, let’s avoid to be clever.
>
> I think my next code example is less clever, but the only reason I've
> written hacks or code was not to be advocated or adopted, just to explain
> what could happen internally.
>
> TL;DR why aren't public static methods that need context **all**
> lazily defined as bound (once) on demand? That would make every single
> public static method consistent, accordingly with the Class you extracted
> them from, right? That's not clever, that's usually developers 
> expectations
> because historically all public static methods don't need the Class to 
> work.
>
> On Thu, Jul 19, 2018 at 5:23 PM Claude Pache 
> wrote:
>
>>
>>
>> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> a écrit :
>> >
>> > I know it's about subclassing, which is why I've asked why, once
>> there's no context, the default/base one is not considered, but since
>> everyone came back with the subclassing issue, which is actually what 
>> I've
>> said myself on twitter about the current state, how about changing all
>> public static methods that need it, to be getters ?
>> >
>> > ```js
>> > class Promise {
>> >   #resolve(...args) {
>> > return this.nativeImplementation(...args);
>> >   }
>> >   get resolve() {
>> > return #resolve.bind(this);
>> >   }
>> > }
>> > ```
>> >
>> > we could argue `Promise.resolve === Promise.resolve` should be
>> preserved, as behavior, so that we need a lazy defined getter ... **but**
>> why not making public static restructuring from known constructors work
>> regardless, under all circumstances ?
>> >
>>
>> Nice hack... But it imposes all subclasses of `Promise` that override
>> the `resolve` method to use a similar trick, because the following will
>> break:
>>
>> ```js
>> class MyPromise extends Promise {
>> static 

Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
My code doesn't suffer what Domenic says.

Once again:

```js
const withLazyBoundObjects = new WeakMap;
const withLazyBoundMethods = obj => {
  const descriptors = Object.getOwnPropertyDescriptors(obj);
  Object.keys(descriptors).forEach(key => {
const desc = descriptors[key];
const {value} = desc;
if (desc.configurable && typeof value === 'function') {
  delete desc.value;
  delete desc.writable;
  desc.get = function (...args) {
let methods = withLazyBoundObjects.get(this || obj);
if (!methods)
  withLazyBoundObjects.set(this, methods = Object.create(null));
return methods[key] || (methods[key] = value.bind(this));
  };
}
  });
  return Object.defineProperties(obj, descriptors);
};

// patch the Promise
withLazyBoundMethods(Promise);

// have a class that extends Promise
class SubPromise extends Promise {}

// test inheritance
SubPromise.resolve() instanceof SubPromise; // true
(0,SubPromise.resolve)() instanceof SubPromise; // true

// even the Promise ?
Promise.resolve() instanceof SubPromise; // false, it's Promise
(0,Promise.resolve)() instanceof SubPromise; // false, it's Promise
```

So, why cannot we have above behavior in core?



On Fri, Jul 20, 2018 at 1:36 AM Jordan Harband  wrote:

> > TL;DR why aren't public static methods that need context **all** lazily
> defined as bound (once) on demand? That would make every single public
> static method consistent, accordingly with the Class you extracted them
> from, right? That's not clever, that's usually developers expectations
> because historically all public static methods don't need the Class to work.
>
> I believe
> https://github.com/tc39/ecma262/issues/544#issuecomment-236487230 answers
> this - specifically, expressing that the claimed better design is for
> *nothing* to be bound.
>
> On Thu, Jul 19, 2018 at 4:22 PM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> Reading that looks like nobody answered my question, explained through
>> some code that wouldn't have any issue with subclassing.
>>
>> So no, there's no answer to my latest question in there, unless I've
>> missed it.
>>
>> On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband  wrote:
>>
>>> This question has been answered here:
>>> https://github.com/tc39/ecma262/issues/544
>>>
>>> On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
 > Per the KISS principle, let’s avoid to be clever.

 I think my next code example is less clever, but the only reason I've
 written hacks or code was not to be advocated or adopted, just to explain
 what could happen internally.

 TL;DR why aren't public static methods that need context **all** lazily
 defined as bound (once) on demand? That would make every single public
 static method consistent, accordingly with the Class you extracted them
 from, right? That's not clever, that's usually developers expectations
 because historically all public static methods don't need the Class to 
 work.

 On Thu, Jul 19, 2018 at 5:23 PM Claude Pache 
 wrote:

>
>
> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi <
> andrea.giammar...@gmail.com> a écrit :
> >
> > I know it's about subclassing, which is why I've asked why, once
> there's no context, the default/base one is not considered, but since
> everyone came back with the subclassing issue, which is actually what I've
> said myself on twitter about the current state, how about changing all
> public static methods that need it, to be getters ?
> >
> > ```js
> > class Promise {
> >   #resolve(...args) {
> > return this.nativeImplementation(...args);
> >   }
> >   get resolve() {
> > return #resolve.bind(this);
> >   }
> > }
> > ```
> >
> > we could argue `Promise.resolve === Promise.resolve` should be
> preserved, as behavior, so that we need a lazy defined getter ... **but**
> why not making public static restructuring from known constructors work
> regardless, under all circumstances ?
> >
>
> Nice hack... But it imposes all subclasses of `Promise` that override
> the `resolve` method to use a similar trick, because the following will
> break:
>
> ```js
> class MyPromise extends Promise {
> static resolve() {
> // do fancy stuff
> return super.resolve()
> }
> }
>
> const {resolve} = MyPromise
>
> resolve() // TypeError: undefined is not an object
> ```
>
> Per the KISS principle, let’s avoid to be clever.
>
> —Claude
>
>
 ___
 es-discuss mailing list
 es-discuss@mozilla.org
 https://mail.mozilla.org/listinfo/es-discuss


>>>
>
___
es-discuss mailing list
es-discuss@mozilla.org

Re: JSON support for BigInt in Chrome/V8

2018-07-19 Thread Jordan Harband
I'm not sure why anything needs remembering - with no other knowledge
except "how the thing you're trying to create is used", I'd hope that it's
apparent whether it's an object or a primitive.

On Thu, Jul 19, 2018 at 2:43 PM, kai zhu  wrote:

> reposting due to previous mail-rejection (vpn issue with gmail in china)
>
> >You already can't use `new` with `Symbol`, and you don't ever want to use
> `new` with a primitive's constructor anyways.
>
> this rule would be *okay* if we limit the number of primitive-types in
> the language to a small-number (maybe add BigDecimal, but that's it),
> so its easy to remember.  i'm already concerned that we have one too
> many needless primitives (Symbol should've been an object similar to
> Promise, and even more so since its use-case is marginal).
>
> adding more primitives at this point, will only make this
> pedantic-rule look more like a wart, and trip-up beginners (and their
> prejudice on the language's inconsistencies).  it also complicates
> integration-work on web-projects, due to difficulty baton-passing new
> primitives around via JSON, and having to continually refactor
> type-checks that rely on typeof.
>
>
>
> On 7/17/18, Andrea Giammarchi  wrote:
> > fair enough, so everything that is not `object` or `null` should never
> use
> > `new`. Is this somehow an indirect rule based on current specs or
> actually
> > part of the specification?
> >
> >
> >
> > On Tue, Jul 17, 2018 at 11:12 AM J Decker  wrote:
> >
> >>
> >>
> >> On Tue, Jul 17, 2018 at 1:48 AM Andrea Giammarchi <
> >> andrea.giammar...@gmail.com> wrote:
> >>
> >>> We miss a fundamental feature in JS, the ability to understand if a
> >>> native constructor can be used with `new` or not.
> >>>
> >>> BigInt("553");
> >>> 553n
> >>>
> >>> new BigInt("553");
> >>> VM51:1 Uncaught TypeError: BigInt is not a constructor
> >>>
> >>>
> >> ```
> >> typeof(5n)
> >> "bigint"
> >>  ```
> >>
> >> Uint8Array([])
> >>> VM54:1 Uncaught TypeError: Constructor Uint8Array requires 'new'
> >>>
> >>> new Uint8Array([])
> >>> Uint8Array []
> >>>
> >>> Without that knowledge, any attempt to even think about a solution that
> >>> would scale not only with BigInt but with everything else, is kinda
> >>> futile.
> >>>
> >>> Best Regards.
> ___
> 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: const {resolve} = Promise; // fails

2018-07-19 Thread Jordan Harband
> TL;DR why aren't public static methods that need context **all** lazily
defined as bound (once) on demand? That would make every single public
static method consistent, accordingly with the Class you extracted them
from, right? That's not clever, that's usually developers expectations
because historically all public static methods don't need the Class to work.

I believe https://github.com/tc39/ecma262/issues/544#issuecomment-236487230
answers this - specifically, expressing that the claimed better design is
for *nothing* to be bound.

On Thu, Jul 19, 2018 at 4:22 PM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> Reading that looks like nobody answered my question, explained through
> some code that wouldn't have any issue with subclassing.
>
> So no, there's no answer to my latest question in there, unless I've
> missed it.
>
> On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband  wrote:
>
>> This question has been answered here: https://github.com/tc39/
>> ecma262/issues/544
>>
>> On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> > Per the KISS principle, let’s avoid to be clever.
>>>
>>> I think my next code example is less clever, but the only reason I've
>>> written hacks or code was not to be advocated or adopted, just to explain
>>> what could happen internally.
>>>
>>> TL;DR why aren't public static methods that need context **all** lazily
>>> defined as bound (once) on demand? That would make every single public
>>> static method consistent, accordingly with the Class you extracted them
>>> from, right? That's not clever, that's usually developers expectations
>>> because historically all public static methods don't need the Class to work.
>>>
>>> On Thu, Jul 19, 2018 at 5:23 PM Claude Pache 
>>> wrote:
>>>


 > Le 19 juil. 2018 à 16:32, Andrea Giammarchi <
 andrea.giammar...@gmail.com> a écrit :
 >
 > I know it's about subclassing, which is why I've asked why, once
 there's no context, the default/base one is not considered, but since
 everyone came back with the subclassing issue, which is actually what I've
 said myself on twitter about the current state, how about changing all
 public static methods that need it, to be getters ?
 >
 > ```js
 > class Promise {
 >   #resolve(...args) {
 > return this.nativeImplementation(...args);
 >   }
 >   get resolve() {
 > return #resolve.bind(this);
 >   }
 > }
 > ```
 >
 > we could argue `Promise.resolve === Promise.resolve` should be
 preserved, as behavior, so that we need a lazy defined getter ... **but**
 why not making public static restructuring from known constructors work
 regardless, under all circumstances ?
 >

 Nice hack... But it imposes all subclasses of `Promise` that override
 the `resolve` method to use a similar trick, because the following will
 break:

 ```js
 class MyPromise extends Promise {
 static resolve() {
 // do fancy stuff
 return super.resolve()
 }
 }

 const {resolve} = MyPromise

 resolve() // TypeError: undefined is not an object
 ```

 Per the KISS principle, let’s avoid to be clever.

 —Claude


>>> ___
>>> 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: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
Reading that looks like nobody answered my question, explained through some
code that wouldn't have any issue with subclassing.

So no, there's no answer to my latest question in there, unless I've missed
it.

On Thu, Jul 19, 2018 at 7:56 PM Jordan Harband  wrote:

> This question has been answered here:
> https://github.com/tc39/ecma262/issues/544
>
> On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> > Per the KISS principle, let’s avoid to be clever.
>>
>> I think my next code example is less clever, but the only reason I've
>> written hacks or code was not to be advocated or adopted, just to explain
>> what could happen internally.
>>
>> TL;DR why aren't public static methods that need context **all** lazily
>> defined as bound (once) on demand? That would make every single public
>> static method consistent, accordingly with the Class you extracted them
>> from, right? That's not clever, that's usually developers expectations
>> because historically all public static methods don't need the Class to work.
>>
>> On Thu, Jul 19, 2018 at 5:23 PM Claude Pache 
>> wrote:
>>
>>>
>>>
>>> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> a écrit :
>>> >
>>> > I know it's about subclassing, which is why I've asked why, once
>>> there's no context, the default/base one is not considered, but since
>>> everyone came back with the subclassing issue, which is actually what I've
>>> said myself on twitter about the current state, how about changing all
>>> public static methods that need it, to be getters ?
>>> >
>>> > ```js
>>> > class Promise {
>>> >   #resolve(...args) {
>>> > return this.nativeImplementation(...args);
>>> >   }
>>> >   get resolve() {
>>> > return #resolve.bind(this);
>>> >   }
>>> > }
>>> > ```
>>> >
>>> > we could argue `Promise.resolve === Promise.resolve` should be
>>> preserved, as behavior, so that we need a lazy defined getter ... **but**
>>> why not making public static restructuring from known constructors work
>>> regardless, under all circumstances ?
>>> >
>>>
>>> Nice hack... But it imposes all subclasses of `Promise` that override
>>> the `resolve` method to use a similar trick, because the following will
>>> break:
>>>
>>> ```js
>>> class MyPromise extends Promise {
>>> static resolve() {
>>> // do fancy stuff
>>> return super.resolve()
>>> }
>>> }
>>>
>>> const {resolve} = MyPromise
>>>
>>> resolve() // TypeError: undefined is not an object
>>> ```
>>>
>>> Per the KISS principle, let’s avoid to be clever.
>>>
>>> —Claude
>>>
>>>
>> ___
>> 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: JSON support for BigInt in Chrome/V8

2018-07-19 Thread kai zhu
reposting due to previous mail-rejection (vpn issue with gmail in china)

>You already can't use `new` with `Symbol`, and you don't ever want to use 
>`new` with a primitive's constructor anyways.

this rule would be *okay* if we limit the number of primitive-types in
the language to a small-number (maybe add BigDecimal, but that's it),
so its easy to remember.  i'm already concerned that we have one too
many needless primitives (Symbol should've been an object similar to
Promise, and even more so since its use-case is marginal).

adding more primitives at this point, will only make this
pedantic-rule look more like a wart, and trip-up beginners (and their
prejudice on the language's inconsistencies).  it also complicates
integration-work on web-projects, due to difficulty baton-passing new
primitives around via JSON, and having to continually refactor
type-checks that rely on typeof.



On 7/17/18, Andrea Giammarchi  wrote:
> fair enough, so everything that is not `object` or `null` should never use
> `new`. Is this somehow an indirect rule based on current specs or actually
> part of the specification?
>
>
>
> On Tue, Jul 17, 2018 at 11:12 AM J Decker  wrote:
>
>>
>>
>> On Tue, Jul 17, 2018 at 1:48 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> We miss a fundamental feature in JS, the ability to understand if a
>>> native constructor can be used with `new` or not.
>>>
>>> BigInt("553");
>>> 553n
>>>
>>> new BigInt("553");
>>> VM51:1 Uncaught TypeError: BigInt is not a constructor
>>>
>>>
>> ```
>> typeof(5n)
>> "bigint"
>>  ```
>>
>> Uint8Array([])
>>> VM54:1 Uncaught TypeError: Constructor Uint8Array requires 'new'
>>>
>>> new Uint8Array([])
>>> Uint8Array []
>>>
>>> Without that knowledge, any attempt to even think about a solution that
>>> would scale not only with BigInt but with everything else, is kinda
>>> futile.
>>>
>>> Best Regards.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Jordan Harband
This question has been answered here:
https://github.com/tc39/ecma262/issues/544

On Thu, Jul 19, 2018 at 9:27 AM, Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> > Per the KISS principle, let’s avoid to be clever.
>
> I think my next code example is less clever, but the only reason I've
> written hacks or code was not to be advocated or adopted, just to explain
> what could happen internally.
>
> TL;DR why aren't public static methods that need context **all** lazily
> defined as bound (once) on demand? That would make every single public
> static method consistent, accordingly with the Class you extracted them
> from, right? That's not clever, that's usually developers expectations
> because historically all public static methods don't need the Class to work.
>
> On Thu, Jul 19, 2018 at 5:23 PM Claude Pache 
> wrote:
>
>>
>>
>> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi <
>> andrea.giammar...@gmail.com> a écrit :
>> >
>> > I know it's about subclassing, which is why I've asked why, once
>> there's no context, the default/base one is not considered, but since
>> everyone came back with the subclassing issue, which is actually what I've
>> said myself on twitter about the current state, how about changing all
>> public static methods that need it, to be getters ?
>> >
>> > ```js
>> > class Promise {
>> >   #resolve(...args) {
>> > return this.nativeImplementation(...args);
>> >   }
>> >   get resolve() {
>> > return #resolve.bind(this);
>> >   }
>> > }
>> > ```
>> >
>> > we could argue `Promise.resolve === Promise.resolve` should be
>> preserved, as behavior, so that we need a lazy defined getter ... **but**
>> why not making public static restructuring from known constructors work
>> regardless, under all circumstances ?
>> >
>>
>> Nice hack... But it imposes all subclasses of `Promise` that override the
>> `resolve` method to use a similar trick, because the following will break:
>>
>> ```js
>> class MyPromise extends Promise {
>> static resolve() {
>> // do fancy stuff
>> return super.resolve()
>> }
>> }
>>
>> const {resolve} = MyPromise
>>
>> resolve() // TypeError: undefined is not an object
>> ```
>>
>> Per the KISS principle, let’s avoid to be clever.
>>
>> —Claude
>>
>>
> ___
> 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: Small Proposal "!in"

2018-07-19 Thread Mike Samuel
On Thu, Jul 19, 2018 at 11:56 AM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> For me, `hasOwn` with the different operand order isn't a problem, but
>>> others may take a different view. Trying to keep the same order takes us
>>> down a route like `inOwn` which I can't say I care for.
>>>
>>
>> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
>> footgun (especially for Colemak users) and maybe isn't clear enough about
>> its semantics.  I would argue that operators aren't camel cased in JS
>> though, so `hasown`/`inown`.
>>
>
> For what it's worth I was also thinking of an "on" operator when reading
> this message, so this is intuitive to me. I also think that is a separate
> idea to propose though.
>

"on" is a good name.  Agree on separate.



> Of couse the usage of `in` is most of the time is not recommended, but it
>>> has it place.
>>>
>>
>> What places does it have?
>> I remain unconvinced that `in` has significant enough use cases to
>> warrant high-level ergonomics
>> were it being proposed today.
>>
>> It exists, and it'll probably never be removed from the language, but I
>> don't think it should be taught
>> as a good part of the language, and linters should probably flag it.
>>
>
> Maybe a radical thought, but does this not apply to hasOwnProperty? If you
> have strong type management why test for a property? The one case I can
> think of is parsing JSON but I handle that with destructuring. Are there
> significant use cases for it? Should linters flag it?
>

Good questions.
Linters should flag
   x.hasOwnProperty(y)
since if you're unsure whether x has an own property y you're probably
unsure whether x has an own property 'hasOwnProperty'.

IIRC, destructuring traverses prototypes so see caveat about library code
and monkeypatching below.
const { toString: f } = {}
typeof f // 'funciton'

You're right that in the middle of an application an instance's type should
determine whether a property is present.
There are use cases at the periphery.

Use cases in bleeding edge JS include
* As you noted, operations on parsed JSON.  Even if you use revivers to
parse JSON to Maps instead of Objects
  you either need own property checks or Object.setPrototypeOf(parsed,
null) when populating the Map.
* Non-clobbering mass assignment.  Like Object.assign but that doesn't
overwrite existing properties in the assignee.
* Reliable hole detection in arrays: (1 !on [0, , 2])
* Adapters that use naming conventions between JS objects and external
systems, like between database field names and JS property names.
* Distinguishing between user-code-defined properties on a host object like
an HTML element and readonly host properties.

Many use cases for hasOwnProperty could be better supported by Map, Set,
and Object.create(null) including:
* Objects used as lookup tables.
* Lookup tables with special purpose fallback logic like message bundles
that fall back from locale 'aa-BB' to 'aa'.
* Configuration objects.
* Function options bundles.
but idiomatic JS hasn't caught up and some library code has to run on old
interpreters, so a transpiling `on` would be nice.
The last two are mostly an issue in library code that needs to be resilient
when loaded alongside monkeypatched prototypes.

Honorable mention:
* for(...in...) iteration broken
solved by for(...of...):
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
> Per the KISS principle, let’s avoid to be clever.

I think my next code example is less clever, but the only reason I've
written hacks or code was not to be advocated or adopted, just to explain
what could happen internally.

TL;DR why aren't public static methods that need context **all** lazily
defined as bound (once) on demand? That would make every single public
static method consistent, accordingly with the Class you extracted them
from, right? That's not clever, that's usually developers expectations
because historically all public static methods don't need the Class to work.

On Thu, Jul 19, 2018 at 5:23 PM Claude Pache  wrote:

>
>
> > Le 19 juil. 2018 à 16:32, Andrea Giammarchi 
> a écrit :
> >
> > I know it's about subclassing, which is why I've asked why, once there's
> no context, the default/base one is not considered, but since everyone came
> back with the subclassing issue, which is actually what I've said myself on
> twitter about the current state, how about changing all public static
> methods that need it, to be getters ?
> >
> > ```js
> > class Promise {
> >   #resolve(...args) {
> > return this.nativeImplementation(...args);
> >   }
> >   get resolve() {
> > return #resolve.bind(this);
> >   }
> > }
> > ```
> >
> > we could argue `Promise.resolve === Promise.resolve` should be
> preserved, as behavior, so that we need a lazy defined getter ... **but**
> why not making public static restructuring from known constructors work
> regardless, under all circumstances ?
> >
>
> Nice hack... But it imposes all subclasses of `Promise` that override the
> `resolve` method to use a similar trick, because the following will break:
>
> ```js
> class MyPromise extends Promise {
> static resolve() {
> // do fancy stuff
> return super.resolve()
> }
> }
>
> const {resolve} = MyPromise
>
> resolve() // TypeError: undefined is not an object
> ```
>
> Per the KISS principle, let’s avoid to be clever.
>
> —Claude
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
Yes Michael, the `::` operator is the best thing ever proposed and got
killed / pseudo replaced by another, completely different, operator that
won't solve problems `::` would: the `|>` pipe one.

I'm a big fan of the `::` operator, and if it were there, I would quite
possibly also like the "per context" restructuring.



On Thu, Jul 19, 2018 at 5:12 PM Michael Luder-Rosefield <
rosyatran...@gmail.com> wrote:

> At this point I can't ignore how much overlap there is between this and
> the this-binding operator proposal
> https://github.com/tc39/proposal-bind-operator
>
> ```
> const resolve = ::Promise.resolve; // takes and binds
> ```
>
> As someone who often extracts functions with deconstruction, I'd love for
> there to be an extension to this proposal to handle this case.
>
> ```
> const { resolve, reject } = ::Promise; // ?
> ```
>
> That would leave the question though of what to do with nesting:
>
> ```
> const { fn1, foo: { fn2 } } = ::bar; // fn1 is bound to bar. Is fn2 bound
> to bar, or foo?
> ```
>
> On Thu, 19 Jul 2018 at 15:58 Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> I guess one example would be more explicative: why cannot public static
>> methods be defined in a similar manner?
>>
>> ```js
>> const withLazyBoundObjects = new WeakMap;
>> const withLazyBoundMethods = obj => {
>>   const descriptors = Object.getOwnPropertyDescriptors(obj);
>>   Object.keys(descriptors).forEach(key => {
>> const desc = descriptors[key];
>> const {value} = desc;
>> if (desc.configurable && typeof value === 'function') {
>>   delete desc.value;
>>   delete desc.writable;
>>   desc.get = function (...args) {
>> let methods = withLazyBoundObjects.get(this || obj);
>> if (!methods)
>>   withLazyBoundObjects.set(this, methods = Object.create(null));
>> return methods[key] || (methods[key] = value.bind(this));
>>   };
>> }
>>   });
>>   return Object.defineProperties(obj, descriptors);
>> };
>>
>> // example
>> const {resolve, reject} = withLazyBoundMethods(Promise);
>> resolve(123).then(console.log);
>> ```
>>
>> On Thu, Jul 19, 2018 at 4:33 PM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> sorry, that'd be `public get resolve()` and also `public #resolve()` so
>>> nobody should be confused about the fact I'm talking about public static
>>> methods.
>>>
>>> On Thu, Jul 19, 2018 at 4:32 PM Andrea Giammarchi <
>>> andrea.giammar...@gmail.com> wrote:
>>>
 I know it's about subclassing, which is why I've asked why, once
 there's no context, the default/base one is not considered, but since
 everyone came back with the subclassing issue, which is actually what I've
 said myself on twitter about the current state, how about changing all
 public static methods that need it, to be getters ?

 ```js
 class Promise {
   #resolve(...args) {
 return this.nativeImplementation(...args);
   }
   get resolve() {
 return #resolve.bind(this);
   }
 }
 ```

 we could argue `Promise.resolve === Promise.resolve` should be
 preserved, as behavior, so that we need a lazy defined getter ... **but**
 why not making public static restructuring from known constructors work
 regardless, under all circumstances ?


 On Thu, Jul 19, 2018 at 4:11 PM T.J. Crowder <
 tj.crow...@farsightsoftware.com> wrote:

> On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
>  wrote:
> > Why cannot Promise methods fallback to Promise constructor when the
> > class/context is not available?
>
> That sounds reasonable on first glance, but I'd be concerned about
> what happens when you do it after subclassing:
>
> ```js
> class MyPromise extends Promise {
> // ...and adds some important feature...
> }
> // ...
> const {resolve, reject} = MyPromise;
> const p = resolve();
> p.someImportantFeature(/*...*/); // TypeError: undefined is not a
> function
> ```
>
> ...since `resolve` fell back to `Promise`. That feels like a footgun.
> Either subclassers would have to handle that, which they will forget to 
> do,
> or it has to be a bit more complicated than just a simple fallback to `
> Promise` (I don't immediately know what that "more complicated"
> answer would be.)
>
> -- T.J. Crowder
>
> ___
>> 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: Small Proposal "!in"

2018-07-19 Thread Michael Theriot
>
> For me, `hasOwn` with the different operand order isn't a problem, but
>> others may take a different view. Trying to keep the same order takes us
>> down a route like `inOwn` which I can't say I care for.
>>
>
> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
> footgun (especially for Colemak users) and maybe isn't clear enough about
> its semantics.  I would argue that operators aren't camel cased in JS
> though, so `hasown`/`inown`.
>

For what it's worth I was also thinking of an "on" operator when reading
this message, so this is intuitive to me. I also think that is a separate
idea to propose though.

Of couse the usage of `in` is most of the time is not recommended, but it
>> has it place.
>>
>
> What places does it have?
> I remain unconvinced that `in` has significant enough use cases to warrant
> high-level ergonomics
> were it being proposed today.
>
> It exists, and it'll probably never be removed from the language, but I
> don't think it should be taught
> as a good part of the language, and linters should probably flag it.
>

Maybe a radical thought, but does this not apply to hasOwnProperty? If you
have strong type management why test for a property? The one case I can
think of is parsing JSON but I handle that with destructuring. Are there
significant use cases for it? Should linters flag it?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Feature proposal

2018-07-19 Thread Nicolas B. Pierron
On Thu, Jul 19, 2018 at 12:53 PM, Nicolas B. Pierron
 wrote:
>> On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron
>>  wrote:
>>> Stupid question, but why are some of these methods implemented on
>>> String, Array, TypedArray, Map and Set, while all of them are
>>> Iteratable?
>>
> Among list of nice Iteratable property that one might add, and which
> might not be part of the standard are things like:
>   chain, take, skip, takeWhile, skipWhile, repeat, zip, enumerate,
> range, stepBy, …

Apparently this already exists as a JS library:
https://fitzgen.github.io/wu.js/

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


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Claude Pache


> Le 19 juil. 2018 à 16:32, Andrea Giammarchi  a 
> écrit :
> 
> I know it's about subclassing, which is why I've asked why, once there's no 
> context, the default/base one is not considered, but since everyone came back 
> with the subclassing issue, which is actually what I've said myself on 
> twitter about the current state, how about changing all public static methods 
> that need it, to be getters ?
> 
> ```js
> class Promise {
>   #resolve(...args) {
> return this.nativeImplementation(...args);
>   }
>   get resolve() {
> return #resolve.bind(this);
>   }
> }
> ```
> 
> we could argue `Promise.resolve === Promise.resolve` should be preserved, as 
> behavior, so that we need a lazy defined getter ... **but** why not making 
> public static restructuring from known constructors work regardless, under 
> all circumstances ?
> 

Nice hack... But it imposes all subclasses of `Promise` that override the 
`resolve` method to use a similar trick, because the following will break:

```js
class MyPromise extends Promise {
static resolve() {
// do fancy stuff
return super.resolve()
}
}

const {resolve} = MyPromise

resolve() // TypeError: undefined is not an object
```

Per the KISS principle, let’s avoid to be clever.

—Claude

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


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Michael Luder-Rosefield
At this point I can't ignore how much overlap there is between this and the
this-binding operator proposal
https://github.com/tc39/proposal-bind-operator

```
const resolve = ::Promise.resolve; // takes and binds
```

As someone who often extracts functions with deconstruction, I'd love for
there to be an extension to this proposal to handle this case.

```
const { resolve, reject } = ::Promise; // ?
```

That would leave the question though of what to do with nesting:

```
const { fn1, foo: { fn2 } } = ::bar; // fn1 is bound to bar. Is fn2 bound
to bar, or foo?
```

On Thu, 19 Jul 2018 at 15:58 Andrea Giammarchi 
wrote:

> I guess one example would be more explicative: why cannot public static
> methods be defined in a similar manner?
>
> ```js
> const withLazyBoundObjects = new WeakMap;
> const withLazyBoundMethods = obj => {
>   const descriptors = Object.getOwnPropertyDescriptors(obj);
>   Object.keys(descriptors).forEach(key => {
> const desc = descriptors[key];
> const {value} = desc;
> if (desc.configurable && typeof value === 'function') {
>   delete desc.value;
>   delete desc.writable;
>   desc.get = function (...args) {
> let methods = withLazyBoundObjects.get(this || obj);
> if (!methods)
>   withLazyBoundObjects.set(this, methods = Object.create(null));
> return methods[key] || (methods[key] = value.bind(this));
>   };
> }
>   });
>   return Object.defineProperties(obj, descriptors);
> };
>
> // example
> const {resolve, reject} = withLazyBoundMethods(Promise);
> resolve(123).then(console.log);
> ```
>
> On Thu, Jul 19, 2018 at 4:33 PM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> sorry, that'd be `public get resolve()` and also `public #resolve()` so
>> nobody should be confused about the fact I'm talking about public static
>> methods.
>>
>> On Thu, Jul 19, 2018 at 4:32 PM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> I know it's about subclassing, which is why I've asked why, once there's
>>> no context, the default/base one is not considered, but since everyone came
>>> back with the subclassing issue, which is actually what I've said myself on
>>> twitter about the current state, how about changing all public static
>>> methods that need it, to be getters ?
>>>
>>> ```js
>>> class Promise {
>>>   #resolve(...args) {
>>> return this.nativeImplementation(...args);
>>>   }
>>>   get resolve() {
>>> return #resolve.bind(this);
>>>   }
>>> }
>>> ```
>>>
>>> we could argue `Promise.resolve === Promise.resolve` should be
>>> preserved, as behavior, so that we need a lazy defined getter ... **but**
>>> why not making public static restructuring from known constructors work
>>> regardless, under all circumstances ?
>>>
>>>
>>> On Thu, Jul 19, 2018 at 4:11 PM T.J. Crowder <
>>> tj.crow...@farsightsoftware.com> wrote:
>>>
 On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
  wrote:
 > Why cannot Promise methods fallback to Promise constructor when the
 > class/context is not available?

 That sounds reasonable on first glance, but I'd be concerned about what
 happens when you do it after subclassing:

 ```js
 class MyPromise extends Promise {
 // ...and adds some important feature...
 }
 // ...
 const {resolve, reject} = MyPromise;
 const p = resolve();
 p.someImportantFeature(/*...*/); // TypeError: undefined is not a
 function
 ```

 ...since `resolve` fell back to `Promise`. That feels like a footgun.
 Either subclassers would have to handle that, which they will forget to do,
 or it has to be a bit more complicated than just a simple fallback to `
 Promise` (I don't immediately know what that "more complicated" answer
 would be.)

 -- T.J. Crowder

 ___
> 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: Feature proposal

2018-07-19 Thread Mike Samuel
On Thu, Jul 19, 2018 at 8:54 AM Nicolas B. Pierron <
nicolas.b.pier...@mozilla.com> wrote:

> On Wed, Jul 18, 2018 at 6:43 PM, Mike Samuel  wrote:
> > Reverse is problematic on String.  The index of a codepoint can't be
> > subtracted from String.length since length is not the count of
> codepoints.
>
> Don't take me wrong, I was not suggesting to add a `reverse` property.
> I was suggesting to add the Iteratable object in the prototype chain
> such that someone can implement extra property on the Iteratable /
> Iteratable.prototype object.
>

My mistake.  I assumed a goal was to allow implementing a generic
findLastIndex in
terms of find and reverse iterators.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Small Proposal "!in"

2018-07-19 Thread Mike Samuel
On Thu, Jul 19, 2018 at 10:40 AM Augusto Moura 
wrote:

> Of couse the usage of `in` is most of the time is not recommended, but it
> has it place.
>

What places does it have?
I remain unconvinced that `in` has significant enough use cases to warrant
high-level ergonomics
were it being proposed today.

It exists, and it'll probably never be removed from the language, but I
don't think it should be taught
as a good part of the language, and linters should probably flag it.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
I guess one example would be more explicative: why cannot public static
methods be defined in a similar manner?

```js
const withLazyBoundObjects = new WeakMap;
const withLazyBoundMethods = obj => {
  const descriptors = Object.getOwnPropertyDescriptors(obj);
  Object.keys(descriptors).forEach(key => {
const desc = descriptors[key];
const {value} = desc;
if (desc.configurable && typeof value === 'function') {
  delete desc.value;
  delete desc.writable;
  desc.get = function (...args) {
let methods = withLazyBoundObjects.get(this || obj);
if (!methods)
  withLazyBoundObjects.set(this, methods = Object.create(null));
return methods[key] || (methods[key] = value.bind(this));
  };
}
  });
  return Object.defineProperties(obj, descriptors);
};

// example
const {resolve, reject} = withLazyBoundMethods(Promise);
resolve(123).then(console.log);
```

On Thu, Jul 19, 2018 at 4:33 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> sorry, that'd be `public get resolve()` and also `public #resolve()` so
> nobody should be confused about the fact I'm talking about public static
> methods.
>
> On Thu, Jul 19, 2018 at 4:32 PM Andrea Giammarchi <
> andrea.giammar...@gmail.com> wrote:
>
>> I know it's about subclassing, which is why I've asked why, once there's
>> no context, the default/base one is not considered, but since everyone came
>> back with the subclassing issue, which is actually what I've said myself on
>> twitter about the current state, how about changing all public static
>> methods that need it, to be getters ?
>>
>> ```js
>> class Promise {
>>   #resolve(...args) {
>> return this.nativeImplementation(...args);
>>   }
>>   get resolve() {
>> return #resolve.bind(this);
>>   }
>> }
>> ```
>>
>> we could argue `Promise.resolve === Promise.resolve` should be preserved,
>> as behavior, so that we need a lazy defined getter ... **but** why not
>> making public static restructuring from known constructors work regardless,
>> under all circumstances ?
>>
>>
>> On Thu, Jul 19, 2018 at 4:11 PM T.J. Crowder <
>> tj.crow...@farsightsoftware.com> wrote:
>>
>>> On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
>>>  wrote:
>>> > Why cannot Promise methods fallback to Promise constructor when the
>>> > class/context is not available?
>>>
>>> That sounds reasonable on first glance, but I'd be concerned about what
>>> happens when you do it after subclassing:
>>>
>>> ```js
>>> class MyPromise extends Promise {
>>> // ...and adds some important feature...
>>> }
>>> // ...
>>> const {resolve, reject} = MyPromise;
>>> const p = resolve();
>>> p.someImportantFeature(/*...*/); // TypeError: undefined is not a
>>> function
>>> ```
>>>
>>> ...since `resolve` fell back to `Promise`. That feels like a footgun.
>>> Either subclassers would have to handle that, which they will forget to do,
>>> or it has to be a bit more complicated than just a simple fallback to `
>>> Promise` (I don't immediately know what that "more complicated" answer
>>> would be.)
>>>
>>> -- T.J. Crowder
>>>
>>>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Small Proposal "!in"

2018-07-19 Thread Augusto Moura
In most of the use cases of checking if a property is in the prototype
chain (checking a protocol for example) you *do* want to trigger getters
and Proxy traps. When interfacing with a object a developer doesn't need to
be concerned with the implementation behind, if a getter or proxy trap does
a intensive computation or has side effects, it's all bad class/object
design fault. A common example when you want to check a property "return"
rather than it's existence it's virtual properties or class refactoring:
``` js
// old implementation
class Foo {
  constructor() {
this.foo = 46;
  }
}

// post refactoring
class Foo {
  // implements something different

  // Product of refactoring, undefined it's a placeholder here
  //it can be any value that makes sense in the refactoring
  get foo() { return undefined; }
  set foo(_) {}
}
```
Of course there's some use cases to use property check without triggering
side effects (mostly when working with property descriptors), but the
majority of "property existence check" lays on interface assertion and a
typeof check it's ~generally~ the right choice.

About the `!in` operator, I don't see any problem in it. Of couse the usage
of `in` is most of the time is not recommended, but it has it place. Also
it puts precedence to future operators (like the `hasOwn` proposed here).

Em qui, 19 de jul de 2018 às 10:26, Michael Theriot <
michael.lee.ther...@gmail.com> escreveu:

> > 'string' === typeof document.createElement('input').type
> > // true
>
> It should be noted this is a "loose check"; it does not determine whether
> or not the property exists when its value equals undefined. It also
> triggers getters, whereas `in` reports whether or not the property exists
> without triggering a getter.
> ___
> es-discuss mailing list
> es-discuss@mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
-- 
Augusto Moura
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
sorry, that'd be `public get resolve()` and also `public #resolve()` so
nobody should be confused about the fact I'm talking about public static
methods.

On Thu, Jul 19, 2018 at 4:32 PM Andrea Giammarchi <
andrea.giammar...@gmail.com> wrote:

> I know it's about subclassing, which is why I've asked why, once there's
> no context, the default/base one is not considered, but since everyone came
> back with the subclassing issue, which is actually what I've said myself on
> twitter about the current state, how about changing all public static
> methods that need it, to be getters ?
>
> ```js
> class Promise {
>   #resolve(...args) {
> return this.nativeImplementation(...args);
>   }
>   get resolve() {
> return #resolve.bind(this);
>   }
> }
> ```
>
> we could argue `Promise.resolve === Promise.resolve` should be preserved,
> as behavior, so that we need a lazy defined getter ... **but** why not
> making public static restructuring from known constructors work regardless,
> under all circumstances ?
>
>
> On Thu, Jul 19, 2018 at 4:11 PM T.J. Crowder <
> tj.crow...@farsightsoftware.com> wrote:
>
>> On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
>>  wrote:
>> > Why cannot Promise methods fallback to Promise constructor when the
>> > class/context is not available?
>>
>> That sounds reasonable on first glance, but I'd be concerned about what
>> happens when you do it after subclassing:
>>
>> ```js
>> class MyPromise extends Promise {
>> // ...and adds some important feature...
>> }
>> // ...
>> const {resolve, reject} = MyPromise;
>> const p = resolve();
>> p.someImportantFeature(/*...*/); // TypeError: undefined is not a function
>> ```
>>
>> ...since `resolve` fell back to `Promise`. That feels like a footgun.
>> Either subclassers would have to handle that, which they will forget to do,
>> or it has to be a bit more complicated than just a simple fallback to `
>> Promise` (I don't immediately know what that "more complicated" answer
>> would be.)
>>
>> -- T.J. Crowder
>>
>>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
I know it's about subclassing, which is why I've asked why, once there's no
context, the default/base one is not considered, but since everyone came
back with the subclassing issue, which is actually what I've said myself on
twitter about the current state, how about changing all public static
methods that need it, to be getters ?

```js
class Promise {
  #resolve(...args) {
return this.nativeImplementation(...args);
  }
  get resolve() {
return #resolve.bind(this);
  }
}
```

we could argue `Promise.resolve === Promise.resolve` should be preserved,
as behavior, so that we need a lazy defined getter ... **but** why not
making public static restructuring from known constructors work regardless,
under all circumstances ?


On Thu, Jul 19, 2018 at 4:11 PM T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:

> On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
>  wrote:
> > Why cannot Promise methods fallback to Promise constructor when the
> > class/context is not available?
>
> That sounds reasonable on first glance, but I'd be concerned about what
> happens when you do it after subclassing:
>
> ```js
> class MyPromise extends Promise {
> // ...and adds some important feature...
> }
> // ...
> const {resolve, reject} = MyPromise;
> const p = resolve();
> p.someImportantFeature(/*...*/); // TypeError: undefined is not a function
> ```
>
> ...since `resolve` fell back to `Promise`. That feels like a footgun.
> Either subclassers would have to handle that, which they will forget to do,
> or it has to be a bit more complicated than just a simple fallback to `
> Promise` (I don't immediately know what that "more complicated" answer
> would be.)
>
> -- T.J. Crowder
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Small Proposal "!in"

2018-07-19 Thread Andy Earnshaw
On Thu, 19 Jul 2018 at 14:48 Mike Samuel  wrote:

> On Thu, Jul 19, 2018 at 9:26 AM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> > 'string' === typeof document.createElement('input').type
>> > // true
>>
>> It should be noted this is a "loose check"; it does not determine whether
>> or not the property exists when its value equals undefined. It also
>> triggers getters, whereas `in` reports whether or not the property exists
>> without triggering a getter.
>>
>
> Good point.   `in` does trigger "has" proxy handlers though, so neither is
> side-effect free.
>

Except I'd argue this is a desirable side effect in the case of `in` and
less so in the case of a getter.  Getters are more likely to be an
intensive operation (for example, innerHTML) than a proxy `has` operation
generally overriding the expected behaviour of the target object.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: const {resolve} = Promise; // fails

2018-07-19 Thread T.J. Crowder
On Thu, Jul 19, 2018 at 12:56 PM, Andrea Giammarchi
 wrote:
> Why cannot Promise methods fallback to Promise constructor when the
> class/context is not available?

That sounds reasonable on first glance, but I'd be concerned about what
happens when you do it after subclassing:

```js
class MyPromise extends Promise {
// ...and adds some important feature...
}
// ...
const {resolve, reject} = MyPromise;
const p = resolve();
p.someImportantFeature(/*...*/); // TypeError: undefined is not a function
```

...since `resolve` fell back to `Promise`. That feels like a footgun.
Either subclassers would have to handle that, which they will forget to do,
or it has to be a bit more complicated than just a simple fallback to `
Promise` (I don't immediately know what that "more complicated" answer
would be.)

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


Re: Small Proposal "!in"

2018-07-19 Thread Andy Earnshaw
On Thu, 19 Jul 2018 at 14:44 T.J. Crowder 
wrote:

> On Thu, Jul 19, 2018 at 12:32 PM, Andy Earnshaw
>  wrote:
> > Although I support the idea of `!in` (for the same reasons as T.J.
> Crowder
> > mentioned, plus it's useful for duck typing), what some browsers do
> isn't a
> > great argument as modern browsers follow the spec more closely with
> regards
> > to inherited accessors like this and you'd never be able to use `!in`
> for an
> > older browser.
>
> Well, there's transpiling.
>

Good point.


> > `!in` and `!instanceof` would be great additions to the operator sets.
>
> AND, agreeing with Mike Samuel, an ergonomic operator for `hasOwnProperty`
> (that doesn't have the issues of being overridden, not being inherited
> because `Object.prototype` isn't in the object's prototype chain, etc.)
> would be a great addition. I don't see any reason they couldn't all be
> part of the same proposal as they touch the same parts of the spec and
> implementations. And agree that the own property ones would be the more
> useful ones, but there are use cases for both.
>
> The immediate temptation is `hasOwn` and `!hasOwn`. My only concern is
> that their operands would be in the opposite order to `in` and `!in`:
>

I'm not against this at all.  I just think the arguments against `!in`
aren't really arguments against it.  Adding `!hasOwn` would give even more
weight to an `!in` proposal, I think.


> For me, `hasOwn` with the different operand order isn't a problem, but
> others may take a different view. Trying to keep the same order takes us
> down a route like `inOwn` which I can't say I care for.
>

Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
footgun (especially for Colemak users) and maybe isn't clear enough about
its semantics.  I would argue that operators aren't camel cased in JS
though, so `hasown`/`inown`.


>
> But I wonder if all of this discussion is useful. If someone *did* take
> the time to work out the naming and do a proper draft proposal, perhaps a
> Babel plugin, is there really any likelihood of someone championing it? I'd
> see these contents:
>
> * `name !in obj`, `name notin obj`, or whatever it gets called
> * `obj hasOwn name`, `name inOwn obj`, or whatever it gets called
> * `obj !hasOwn name`, `name !inOwn obj`, or whatever it gets called
> * `Reflect.hasOwn`, the "own" version of `Reflect.has`
> * `Proxy` trap for `hasOwn` (even if the operator has a different name)
>
> Is there anyone appropriately-placed who can say "Yeah, if someone spends
> the time to investigate this and put together a really proper proposal, I'm
> willing to look at that proposal with an eye toward _possibly_ championing
> it." I mean, if there's a 10% chance or better, it may be worth someone's
> time. If there isn't, then...
>

`!in` and `!instanceof` are low hanging fruit (run the same steps as their
counterparts but flip the result), better off in their own proposal. I
don't know if you'd find a champion to do it, but I do think a lot of
people would find them convenient.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Small Proposal "!in"

2018-07-19 Thread Naveen Chawla
I still prefer truthy checks when logically valid. Otherwise a truthy
check + [any other validity check in the logic]. I find `in` far too quirky
and I'd rather never ever use it.

I think `instanceof` is also a messy pattern. I've always preferred having
an overridden method on the object that performs the necessary logic for
that type, instead of if(x instanceof Y)... I find overridden method based
code shorter at the point of use, and scales to many instances /
permutations for type based logic.

Therefore, I'd rather TC39 let these concepts like `in` and `instanceof`
die quietly, and always focus on the more/most powerful ways of getting
things done first.

On Thu, 19 Jul 2018 at 19:14 T.J. Crowder 
wrote:

> On Thu, Jul 19, 2018 at 12:32 PM, Andy Earnshaw
>  wrote:
> > Although I support the idea of `!in` (for the same reasons as T.J.
> Crowder
> > mentioned, plus it's useful for duck typing), what some browsers do
> isn't a
> > great argument as modern browsers follow the spec more closely with
> regards
> > to inherited accessors like this and you'd never be able to use `!in`
> for an
> > older browser.
>
> Well, there's transpiling.
>
>
> > `!in` and `!instanceof` would be great additions to the operator sets.
>
> AND, agreeing with Mike Samuel, an ergonomic operator for `hasOwnProperty`
> (that doesn't have the issues of being overridden, not being inherited
> because `Object.prototype` isn't in the object's prototype chain, etc.)
> would be a great addition. I don't see any reason they couldn't all be
> part of the same proposal as they touch the same parts of the spec and
> implementations. And agree that the own property ones would be the more
> useful ones, but there are use cases for both.
>
> The immediate temptation is `hasOwn` and `!hasOwn`. My only concern is
> that their operands would be in the opposite order to `in` and `!in`:
>
> ```js
> const o = Object.create({a: 1});
> o.b = 2;
> console.log("a" in o); // true
> console.log(o hasOwn "a"); // false
> console.log("b" in o); // true
> console.log(o hasOwn "b"); // true
> ```
>
> For me, `hasOwn` with the different operand order isn't a problem, but
> others may take a different view. Trying to keep the same order takes us
> down a route like `inOwn` which I can't say I care for.
>
> But I wonder if all of this discussion is useful. If someone *did* take
> the time to work out the naming and do a proper draft proposal, perhaps a
> Babel plugin, is there really any likelihood of someone championing it? I'd
> see these contents:
>
> * `name !in obj`, `name notin obj`, or whatever it gets called
> * `obj hasOwn name`, `name inOwn obj`, or whatever it gets called
> * `obj !hasOwn name`, `name !inOwn obj`, or whatever it gets called
> * `Reflect.hasOwn`, the "own" version of `Reflect.has`
> * `Proxy` trap for `hasOwn` (even if the operator has a different name)
>
> Is there anyone appropriately-placed who can say "Yeah, if someone spends
> the time to investigate this and put together a really proper proposal, I'm
> willing to look at that proposal with an eye toward _possibly_ championing
> it." I mean, if there's a 10% chance or better, it may be worth someone's
> time. If there isn't, then...
>
> -- T.J. Crowder
> ___
> 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: Small Proposal "!in"

2018-07-19 Thread Andy Earnshaw
It was a contrived example I threw together to make a point in 30 seconds.
It may surprise you to know that it is not real world code.  You talk about
an "attacker" as if any code working in such a way is sensitive, but that
is often not the case and leaving your functions intentionally generic
allows third parties more room when working with it.

> 'string' === typeof document.createElement('input').type
> // true

Again, you're missing the point, which is how that is one example of an
object that doesn't 'own' all of its properties.  As already mentioned, it
also triggers a getter.

Let's not also forget that not all code has to adhere to best practices.  I
use the `in` operator far more in the REPL/console or when I'm prototyping
than I do when I'm performing robust checks in code.

On Thu, 19 Jul 2018 at 13:23 Mike Samuel  wrote:

> On Thu, Jul 19, 2018 at 7:32 AM Andy Earnshaw 
> wrote:
>
>> Although I support the idea of `!in` (for the same reasons as T.J.
>> Crowder mentioned, plus it's useful for duck typing), what some browsers do
>> isn't a great argument as modern browsers follow the spec more closely with
>> regards to inherited accessors like this and you'd never be able to use
>> `!in` for an older browser.  However, you do have a point in that accessors
>> can live anywhere in the prototype chain and an object's properties may not
>> necessarily be 'owned' by the object in question:
>>
>> document.createElement('input').hasOwnProperty('type')
>> // false
>>
>
> 'string' === typeof document.createElement('input').type
> // true
>
>
>> So far, the main argument against has been that `hasOwnProperty()` is
>> recommended over `in` as a more robust check.  I don't see how this is a
>> valid concern, they clearly have different use cases and you're not going
>> to solve that problem be excluding a negated `in` from the spec (`!(a in
>> b)` is still easier to type than `!b.hasOwnProperty(a)`).  There are plenty
>> of valid use cases for `in`, not least duck typing as mentioned before:
>>
>
> Agree re "not solving that problem by"
> When I'm duck typing, I typically am testing typeof or truthiness of a
> property, not just presence.
>
> function feed(duck) {
>> if ('quackPitch' in duck && duck.canSwim) {
>> duck.give(defrostedPeas);
>> }
>> }
>>
>
> This code is brittle.  An attacker may be able to deny service by getting
> `{ "quackPitch": true, "canSwim": true }` to a JSON decoder, but would not
> be able to trigger an exception if you tested with typeof instead of in.
>
> function robustFeed(duck) {
>   if (duck.canSwim && typeof duck.give === 'function') {
> duck.give(defrostedPeas);
>   }
> }
>
> `in` provides a weak, confusable kind of duck typing.
> JSON decoding attacks allow forging objects that satisfy `in` predicates,
> encouraging conflating
> objects from an untrusted source with objects from trusted code.
> These forgeries often would not pass stronger predicates that test for the
> typeof required properties.
>
>
>> `!in` and `!instanceof` would be great additions to the operator sets.
>>
>
> Agree re !instanceof.  I'm still not seeing where developers do and should
> use `in` or `!in` on a regular basis.
>
>
>> On Thu, 19 Jul 2018 at 12:06 Tobias Buschor 
>> wrote:
>>
>>> There are valid use-cases.
>>> As an example, some browsers have "onfocus" as an own property of
>>> "window", some as an inherited.
>>>
>>> ```js
>>> if ('onfocus' !in window) {
>>> // polyfill onfocus...
>>> }
>>> ```
>>>
>>>
>>> Am Mi., 18. Juli 2018 um 18:32 Uhr schrieb Mike Samuel <
>>> mikesam...@gmail.com>:
>>>


 On Wed, Jul 18, 2018 at 12:21 PM Michael Theriot <
 michael.lee.ther...@gmail.com> wrote:

> I think it is irrelevant; the operator already exists and I would
> assume if you want the negation of it you are using it correctly in the
> first place. Otherwise are you not just arguing for its removal 
> altogether?
> But to answer your question one case that comes to mind is trapping 
> get/has
> in a proxy handler.


 Why should we assume that only people who consistently use `in`
 correctly would want the negation?  It seems that people who use it
 incorrectly because they are confused about the precise semantics or don't
 care might want the negation too.  If there are more of the latter then we
 should not assume what you assume.

 Proxy handler code is important, but very few developers will ever
 write a proxy handler over their careers, so this seems like a marginal use
 case.
 Besides, Reflect.has is probably a better choice in a proxy handler.

 I am not arguing for removing `in`.  That would break the web.  I am
 just arguing for prioritizing changes that provide features that more
 closely match the semantics developers typically want over making it more
 convenient to write code that seems to work in casual testing but has

Re: Small Proposal "!in"

2018-07-19 Thread T.J. Crowder
On Thu, Jul 19, 2018 at 2:44 PM, T.J. Crowder <
tj.crow...@farsightsoftware.com> wrote:
> Is there anyone appropriately-placed who can say "Yeah, if someone spends
> the time to investigate this and put together a really proper proposal,
I'm
> willing to look at that proposal with an eye toward _possibly_ championing
> it."

Apologies, Mike, I just realized you're a potential champion. Just in case
you read that as seeming a bit off... :-)

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


Re: Small Proposal "!in"

2018-07-19 Thread Mike Samuel
On Thu, Jul 19, 2018 at 9:26 AM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> > 'string' === typeof document.createElement('input').type
> > // true
>
> It should be noted this is a "loose check"; it does not determine whether
> or not the property exists when its value equals undefined. It also
> triggers getters, whereas `in` reports whether or not the property exists
> without triggering a getter.
>

Good point.   `in` does trigger "has" proxy handlers though, so neither is
side-effect free.



> ___
> 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: Small Proposal "!in"

2018-07-19 Thread T.J. Crowder
On Thu, Jul 19, 2018 at 12:32 PM, Andy Earnshaw
 wrote:
> Although I support the idea of `!in` (for the same reasons as T.J. Crowder
> mentioned, plus it's useful for duck typing), what some browsers do isn't
a
> great argument as modern browsers follow the spec more closely with
regards
> to inherited accessors like this and you'd never be able to use `!in` for
an
> older browser.

Well, there's transpiling.

> `!in` and `!instanceof` would be great additions to the operator sets.

AND, agreeing with Mike Samuel, an ergonomic operator for
`hasOwnProperty` (that
doesn't have the issues of being overridden, not being inherited because `
Object.prototype` isn't in the object's prototype chain, etc.) would be a
great addition. I don't see any reason they couldn't all be part of the
same proposal as they touch the same parts of the spec and implementations.
And agree that the own property ones would be the more useful ones, but
there are use cases for both.

The immediate temptation is `hasOwn` and `!hasOwn`. My only concern is that
their operands would be in the opposite order to `in` and `!in`:

```js
const o = Object.create({a: 1});
o.b = 2;
console.log("a" in o); // true
console.log(o hasOwn "a"); // false
console.log("b" in o); // true
console.log(o hasOwn "b"); // true
```

For me, `hasOwn` with the different operand order isn't a problem, but
others may take a different view. Trying to keep the same order takes us
down a route like `inOwn` which I can't say I care for.

But I wonder if all of this discussion is useful. If someone *did* take the
time to work out the naming and do a proper draft proposal, perhaps a Babel
plugin, is there really any likelihood of someone championing it? I'd see
these contents:

* `name !in obj`, `name notin obj`, or whatever it gets called
* `obj hasOwn name`, `name inOwn obj`, or whatever it gets called
* `obj !hasOwn name`, `name !inOwn obj`, or whatever it gets called
* `Reflect.hasOwn`, the "own" version of `Reflect.has`
* `Proxy` trap for `hasOwn` (even if the operator has a different name)

Is there anyone appropriately-placed who can say "Yeah, if someone spends
the time to investigate this and put together a really proper proposal, I'm
willing to look at that proposal with an eye toward _possibly_ championing
it." I mean, if there's a 10% chance or better, it may be worth someone's
time. If there isn't, then...

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


Re: const {resolve} = Promise; // fails

2018-07-19 Thread Claude Pache


> Le 19 juil. 2018 à 13:56, Andrea Giammarchi  a 
> écrit :
> 
> 
> Compared to every other public static method in ECMAScript that works, 
> including those methods that might need the contextual class, as it is for 
> the Array.from case.
> 
> ```js
> const {from} = Array;
> 
> from({0: 'abc', length: 1}); // ["abc"] // all good
> ```

That pattern falls apart when subclassing:

```js
class ImprovedArray extends Array {
/* implementation NOT overriding the `from` static method  */
}

const {from} = ImprovedArray

from({0: 'abc', length: 1}) // Array instance instead of ImprovedArray instance
```

So, no, the `Array.from` precedent is a bad one.

—Claude

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


Re: Small Proposal "!in"

2018-07-19 Thread Michael Theriot
> 'string' === typeof document.createElement('input').type
> // true

It should be noted this is a "loose check"; it does not determine whether
or not the property exists when its value equals undefined. It also
triggers getters, whereas `in` reports whether or not the property exists
without triggering a getter.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Feature proposal

2018-07-19 Thread Nicolas B. Pierron
On Wed, Jul 18, 2018 at 6:43 PM, Mike Samuel  wrote:
> On Wed, Jul 18, 2018 at 2:06 PM Nicolas B. Pierron
>  wrote:
>> Stupid question, but why are some of these methods implemented on
>> String, Array, TypedArray, Map and Set, while all of them are
>> Iteratable?
>
>
> String is different from the others.
> The String index methods deal with a contiguous subsequence of the sequence,
> not the index of an element in the sequence.

I am not sure why this would prevent us from adding an Iteratable
object with common properties.  `Iteratable.prototype.foo` can exist
at the same time as `String.prototype.foo`, and calling the `foo`
property on a String will result in calling `String.prototype.foo`.

Also one could implement a naïve/default implementation of
`reverseOrder` which allocates a temporary array for object which have
no random accesses capabilities.


  Iteratable.prototype.reverseOrder = function* () {
  for (let e of [...this].reverse())
   yield e;
  }
```

>>
>> If we were to add all these methods on Iteratable, then one could add
>> a `reverse` generator property on Iteratable.
>
>
> Reverse is problematic on String.  The index of a codepoint can't be
> subtracted from String.length since length is not the count of codepoints.

Don't take me wrong, I was not suggesting to add a `reverse` property.
I was suggesting to add the Iteratable object in the prototype chain
such that someone can implement extra property on the Iteratable /
Iteratable.prototype object.

Among list of nice Iteratable property that one might add, and which
might not be part of the standard are things like:
  chain, take, skip, takeWhile, skipWhile, repeat, zip, enumerate,
range, stepBy, …

Another option would be to just add a property named `iter` which
returns an Iteratable object.

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


Re: Small Proposal "!in"

2018-07-19 Thread Mike Samuel
On Thu, Jul 19, 2018 at 7:32 AM Andy Earnshaw 
wrote:

> Although I support the idea of `!in` (for the same reasons as T.J. Crowder
> mentioned, plus it's useful for duck typing), what some browsers do isn't a
> great argument as modern browsers follow the spec more closely with regards
> to inherited accessors like this and you'd never be able to use `!in` for
> an older browser.  However, you do have a point in that accessors can live
> anywhere in the prototype chain and an object's properties may not
> necessarily be 'owned' by the object in question:
>
> document.createElement('input').hasOwnProperty('type')
> // false
>

'string' === typeof document.createElement('input').type
// true


> So far, the main argument against has been that `hasOwnProperty()` is
> recommended over `in` as a more robust check.  I don't see how this is a
> valid concern, they clearly have different use cases and you're not going
> to solve that problem be excluding a negated `in` from the spec (`!(a in
> b)` is still easier to type than `!b.hasOwnProperty(a)`).  There are plenty
> of valid use cases for `in`, not least duck typing as mentioned before:
>

Agree re "not solving that problem by"
When I'm duck typing, I typically am testing typeof or truthiness of a
property, not just presence.

function feed(duck) {
> if ('quackPitch' in duck && duck.canSwim) {
> duck.give(defrostedPeas);
> }
> }
>

This code is brittle.  An attacker may be able to deny service by getting
`{ "quackPitch": true, "canSwim": true }` to a JSON decoder, but would not
be able to trigger an exception if you tested with typeof instead of in.

function robustFeed(duck) {
  if (duck.canSwim && typeof duck.give === 'function') {
duck.give(defrostedPeas);
  }
}

`in` provides a weak, confusable kind of duck typing.
JSON decoding attacks allow forging objects that satisfy `in` predicates,
encouraging conflating
objects from an untrusted source with objects from trusted code.
These forgeries often would not pass stronger predicates that test for the
typeof required properties.


> `!in` and `!instanceof` would be great additions to the operator sets.
>

Agree re !instanceof.  I'm still not seeing where developers do and should
use `in` or `!in` on a regular basis.


> On Thu, 19 Jul 2018 at 12:06 Tobias Buschor 
> wrote:
>
>> There are valid use-cases.
>> As an example, some browsers have "onfocus" as an own property of
>> "window", some as an inherited.
>>
>> ```js
>> if ('onfocus' !in window) {
>> // polyfill onfocus...
>> }
>> ```
>>
>>
>> Am Mi., 18. Juli 2018 um 18:32 Uhr schrieb Mike Samuel <
>> mikesam...@gmail.com>:
>>
>>>
>>>
>>> On Wed, Jul 18, 2018 at 12:21 PM Michael Theriot <
>>> michael.lee.ther...@gmail.com> wrote:
>>>
 I think it is irrelevant; the operator already exists and I would
 assume if you want the negation of it you are using it correctly in the
 first place. Otherwise are you not just arguing for its removal altogether?
 But to answer your question one case that comes to mind is trapping get/has
 in a proxy handler.
>>>
>>>
>>> Why should we assume that only people who consistently use `in`
>>> correctly would want the negation?  It seems that people who use it
>>> incorrectly because they are confused about the precise semantics or don't
>>> care might want the negation too.  If there are more of the latter then we
>>> should not assume what you assume.
>>>
>>> Proxy handler code is important, but very few developers will ever write
>>> a proxy handler over their careers, so this seems like a marginal use case.
>>> Besides, Reflect.has is probably a better choice in a proxy handler.
>>>
>>> I am not arguing for removing `in`.  That would break the web.  I am
>>> just arguing for prioritizing changes that provide features that more
>>> closely match the semantics developers typically want over making it more
>>> convenient to write code that seems to work in casual testing but has
>>> subtly wrong semantics.
>>>
>>>
>>>
>>>
>>>
>>>
>>>
 On Wednesday, July 18, 2018, Mike Samuel  wrote:

>
>
> On Wed, Jul 18, 2018 at 11:05 AM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> I think `in` and `instanceof` could both benefit from having negated
>> versions.
>>
>> Assuming the developer is using `in` correctly, hasOwnProperty
>> concerns are irrelevant. Either way they would attempt to use !(a in b),
>> not !hasOwnProperty.
>>
>
> Why should we assume the developer is using `in` correctly?
> Apologies if I buried my question at the end.  It was, what are the
> use cases for `in` that would not be better served by an ergonomic, infix
> hasOwnProperty?
>
>
> Same reason we don't use...
>> !(a == b) // a != b
>> !(a === b) // a !== b
>>
>
>
>> !(a > b) // a <= b
>> (!(a > b) && !(a == b)) // a < b
>>
>
> I'm not sure this is 

Re: const {resolve} = Promise; // fails

2018-07-19 Thread Michael Luder-Rosefield
I'd reinforce this with the fact that this works for RSVP.js
https://github.com/tildeio/rsvp.js/, and so the current behaviour is a
potential breaking point if code is being converted to use native Promises.

On Thu, 19 Jul 2018 at 12:56 Andrea Giammarchi 
wrote:

> As quickly discussed on Twitter, it's very inconvenient and inconsistent
> that the following fails:
>
> ```js
> const {resolve, reject} = Promise;
>
> resolve(123); // throws
> ```
>
> Compared to every other public static method in ECMAScript that works,
> including those methods that might need the contextual class, as it is for
> the Array.from case.
>
> ```js
> const {from} = Array;
>
> from({0: 'abc', length: 1}); // ["abc"] // all good
> ```
>
> Why cannot Promise methods fallback to Promise constructor when the
> class/context is not available?
>
> Wouldn't be simple/reasonable change to make so that developers
> expectations would be preserved?
>
> Best Regards.
> ___
> 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


const {resolve} = Promise; // fails

2018-07-19 Thread Andrea Giammarchi
As quickly discussed on Twitter, it's very inconvenient and inconsistent
that the following fails:

```js
const {resolve, reject} = Promise;

resolve(123); // throws
```

Compared to every other public static method in ECMAScript that works,
including those methods that might need the contextual class, as it is for
the Array.from case.

```js
const {from} = Array;

from({0: 'abc', length: 1}); // ["abc"] // all good
```

Why cannot Promise methods fallback to Promise constructor when the
class/context is not available?

Wouldn't be simple/reasonable change to make so that developers
expectations would be preserved?

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


Re: Small Proposal "!in"

2018-07-19 Thread Andy Earnshaw
Although I support the idea of `!in` (for the same reasons as T.J. Crowder
mentioned, plus it's useful for duck typing), what some browsers do isn't a
great argument as modern browsers follow the spec more closely with regards
to inherited accessors like this and you'd never be able to use `!in` for
an older browser.  However, you do have a point in that accessors can live
anywhere in the prototype chain and an object's properties may not
necessarily be 'owned' by the object in question:

document.createElement('input').hasOwnProperty('type')
// false

So far, the main argument against has been that `hasOwnProperty()` is
recommended over `in` as a more robust check.  I don't see how this is a
valid concern, they clearly have different use cases and you're not going
to solve that problem be excluding a negated `in` from the spec (`!(a in
b)` is still easier to type than `!b.hasOwnProperty(a)`).  There are plenty
of valid use cases for `in`, not least duck typing as mentioned before:

function feed(duck) {
if ('quackPitch' in duck && duck.canSwim) {
duck.give(defrostedPeas);
}
}

`!in` and `!instanceof` would be great additions to the operator sets.

On Thu, 19 Jul 2018 at 12:06 Tobias Buschor 
wrote:

> There are valid use-cases.
> As an example, some browsers have "onfocus" as an own property of
> "window", some as an inherited.
>
> ```js
> if ('onfocus' !in window) {
> // polyfill onfocus...
> }
> ```
>
>
> Am Mi., 18. Juli 2018 um 18:32 Uhr schrieb Mike Samuel <
> mikesam...@gmail.com>:
>
>>
>>
>> On Wed, Jul 18, 2018 at 12:21 PM Michael Theriot <
>> michael.lee.ther...@gmail.com> wrote:
>>
>>> I think it is irrelevant; the operator already exists and I would assume
>>> if you want the negation of it you are using it correctly in the first
>>> place. Otherwise are you not just arguing for its removal altogether? But
>>> to answer your question one case that comes to mind is trapping get/has in
>>> a proxy handler.
>>
>>
>> Why should we assume that only people who consistently use `in` correctly
>> would want the negation?  It seems that people who use it incorrectly
>> because they are confused about the precise semantics or don't care might
>> want the negation too.  If there are more of the latter then we should not
>> assume what you assume.
>>
>> Proxy handler code is important, but very few developers will ever write
>> a proxy handler over their careers, so this seems like a marginal use case.
>> Besides, Reflect.has is probably a better choice in a proxy handler.
>>
>> I am not arguing for removing `in`.  That would break the web.  I am just
>> arguing for prioritizing changes that provide features that more closely
>> match the semantics developers typically want over making it more
>> convenient to write code that seems to work in casual testing but has
>> subtly wrong semantics.
>>
>>
>>
>>
>>
>>
>>
>>> On Wednesday, July 18, 2018, Mike Samuel  wrote:
>>>


 On Wed, Jul 18, 2018 at 11:05 AM Michael Theriot <
 michael.lee.ther...@gmail.com> wrote:

> I think `in` and `instanceof` could both benefit from having negated
> versions.
>
> Assuming the developer is using `in` correctly, hasOwnProperty
> concerns are irrelevant. Either way they would attempt to use !(a in b),
> not !hasOwnProperty.
>

 Why should we assume the developer is using `in` correctly?
 Apologies if I buried my question at the end.  It was, what are the use
 cases for `in` that would not be better served by an ergonomic, infix
 hasOwnProperty?


 Same reason we don't use...
> !(a == b) // a != b
> !(a === b) // a !== b
>


> !(a > b) // a <= b
> (!(a > b) && !(a == b)) // a < b
>

 I'm not sure this is relevant to your larger point, and I've already
 conceded ergonomics, but
 these last two are not equivalent because NaN is weird.

 a = NaN, b = 0
 [!(a > b), a <= b]  // [true, false]
 [!(a > b) && !(a == b), a < b]  // [true, false]





> On Thursday, June 28, 2018, Tobias Buschor 
> wrote:
>
>> I dont like to write:
>> if ( !('x' in obj) &&  !('y' in obj) ) {
>>  doit()
>> }
>>
>> I was even tempted to write it that way:
>> if ('x' in obj  ||  'y' in obj) { } else {
>>  doit()
>> }
>>
>> What about a !in operator to write it like this?
>> if ('x' !in obj  &&  'y' !in obj) {
>>  doit()
>> }
>>
>> ___
> 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
>>
>
>
> --
> Freundliche Grüsse
> Tobias Buschor
>
> schwups GmbH
> Hauptstr. 33
> 9424 Rheineck/SG
>
> +41 76 321 23 21 

Re: Small Proposal "!in"

2018-07-19 Thread Tobias Buschor
There are valid use-cases.
As an example, some browsers have "onfocus" as an own property of "window",
some as an inherited.

```js
if ('onfocus' !in window) {
// polyfill onfocus...
}
```


Am Mi., 18. Juli 2018 um 18:32 Uhr schrieb Mike Samuel :

>
>
> On Wed, Jul 18, 2018 at 12:21 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> I think it is irrelevant; the operator already exists and I would assume
>> if you want the negation of it you are using it correctly in the first
>> place. Otherwise are you not just arguing for its removal altogether? But
>> to answer your question one case that comes to mind is trapping get/has in
>> a proxy handler.
>
>
> Why should we assume that only people who consistently use `in` correctly
> would want the negation?  It seems that people who use it incorrectly
> because they are confused about the precise semantics or don't care might
> want the negation too.  If there are more of the latter then we should not
> assume what you assume.
>
> Proxy handler code is important, but very few developers will ever write a
> proxy handler over their careers, so this seems like a marginal use case.
> Besides, Reflect.has is probably a better choice in a proxy handler.
>
> I am not arguing for removing `in`.  That would break the web.  I am just
> arguing for prioritizing changes that provide features that more closely
> match the semantics developers typically want over making it more
> convenient to write code that seems to work in casual testing but has
> subtly wrong semantics.
>
>
>
>
>
>
>
>> On Wednesday, July 18, 2018, Mike Samuel  wrote:
>>
>>>
>>>
>>> On Wed, Jul 18, 2018 at 11:05 AM Michael Theriot <
>>> michael.lee.ther...@gmail.com> wrote:
>>>
 I think `in` and `instanceof` could both benefit from having negated
 versions.

 Assuming the developer is using `in` correctly, hasOwnProperty concerns
 are irrelevant. Either way they would attempt to use !(a in b), not
 !hasOwnProperty.

>>>
>>> Why should we assume the developer is using `in` correctly?
>>> Apologies if I buried my question at the end.  It was, what are the use
>>> cases for `in` that would not be better served by an ergonomic, infix
>>> hasOwnProperty?
>>>
>>>
>>> Same reason we don't use...
 !(a == b) // a != b
 !(a === b) // a !== b

>>>
>>>
 !(a > b) // a <= b
 (!(a > b) && !(a == b)) // a < b

>>>
>>> I'm not sure this is relevant to your larger point, and I've already
>>> conceded ergonomics, but
>>> these last two are not equivalent because NaN is weird.
>>>
>>> a = NaN, b = 0
>>> [!(a > b), a <= b]  // [true, false]
>>> [!(a > b) && !(a == b), a < b]  // [true, false]
>>>
>>>
>>>
>>>
>>>
 On Thursday, June 28, 2018, Tobias Buschor 
 wrote:

> I dont like to write:
> if ( !('x' in obj) &&  !('y' in obj) ) {
>  doit()
> }
>
> I was even tempted to write it that way:
> if ('x' in obj  ||  'y' in obj) { } else {
>  doit()
> }
>
> What about a !in operator to write it like this?
> if ('x' !in obj  &&  'y' !in obj) {
>  doit()
> }
>
> ___
 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
>


-- 
Freundliche Grüsse
Tobias Buschor

schwups GmbH
Hauptstr. 33
9424 Rheineck/SG

+41 76 321 23 21
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Feature proposal

2018-07-19 Thread Dmitry Shulgin
Yeah, i meant  T.J. Crowder's comment that `reverseView` won't solve
original issue.

2018-07-19 12:34 GMT+03:00 Isiah Meadows :

> It shouldn't make anything that much more complex - the various Array
> methods are already generic.
>
>
> On Thu, Jul 19, 2018, 05:31 Dmitry Shulgin  wrote:
>
>> Cool, gonna read it out.
>> First impression -- it can make methods more complex and usage will be
>> different between `find`, `findlastIndex` etc., if we want to use something
>> like `reverseView`.
>>
>>
>> 2018-07-19 11:56 GMT+03:00 T.J. Crowder 
>> :
>>
>>> On Thu, Jul 19, 2018 at 9:49 AM, Isiah Meadows
>>>  wrote:
>>> > What about this alternate proposal:
>>>
>>> Great minds: https://esdiscuss.org/topic/fwd-feature-proposal#content-5
>>> ;-)
>>>
>>> -- T.J. Crowder
>>>
>>
>>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Feature proposal

2018-07-19 Thread Dmitry Shulgin
Cool, gonna read it out.
First impression -- it can make methods more complex and usage will be
different between `find`, `findlastIndex` etc., if we want to use something
like `reverseView`.

2018-07-19 11:56 GMT+03:00 T.J. Crowder :

> On Thu, Jul 19, 2018 at 9:49 AM, Isiah Meadows
>  wrote:
> > What about this alternate proposal:
>
> Great minds: https://esdiscuss.org/topic/fwd-feature-proposal#content-5
> ;-)
>
> -- T.J. Crowder
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Feature proposal

2018-07-19 Thread Isiah Meadows
I'd rather keep it restricted to very simple, context-free things like a
reverse subtract or single add, with only a few bits of data necessary.
Anything more is going to be a perf concern because you can't avoid visible
side effects.

On Thu, Jul 19, 2018, 05:03 Michael Luder-Rosefield 
wrote:

> This array view thing is very close to what I had in mind, and seems to
> suggest to a lot of interesting possibilities.
>
> What strikes me as the two most significant are:
>
>- again, 'reversed' is just one alternative iteration order through,
>though almost certainly the most useful
>- others I can think of could be 'even/odd indexes', 'random shuffle',
>   'iterate-until /while-condition', and filter equivalents
>- as well as the view defining the iteration order, it could define
>the computed value
>   - this would be basically a map where the value isn't computed
>   until accessed; caching behaviour could be user-determined
>
>
>
>
> On Thu, 19 Jul 2018 at 09:49 Isiah Meadows  wrote:
>
>> What about this alternate proposal:
>>
>>
>> https://github.com/isiahmeadows/array-additions-proposal/blob/master/README.md#get-arrayprototypereversed-get-typedarrayprototypereversed
>>
>> (I've got a myriad of other related stuff there, too.)
>>
>>
>> On Thu, Jul 19, 2018, 04:41 Dmitry Shulgin  wrote:
>>
>>> Above we was talking about this.
>>> consistency and handy using -- two main reasons for this proposal.
>>>
>>> `reverse` will also mutate my array, cause of in-place implementation.
>>>
>>> You can find workaround for many existing methods, but it's not handy to
>>> my mind.
>>>
>> ___
>> 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: Feature proposal

2018-07-19 Thread Michael Luder-Rosefield
This array view thing is very close to what I had in mind, and seems to
suggest to a lot of interesting possibilities.

What strikes me as the two most significant are:

   - again, 'reversed' is just one alternative iteration order through,
   though almost certainly the most useful
   - others I can think of could be 'even/odd indexes', 'random shuffle',
  'iterate-until /while-condition', and filter equivalents
   - as well as the view defining the iteration order, it could define the
   computed value
  - this would be basically a map where the value isn't computed until
  accessed; caching behaviour could be user-determined




On Thu, 19 Jul 2018 at 09:49 Isiah Meadows  wrote:

> What about this alternate proposal:
>
>
> https://github.com/isiahmeadows/array-additions-proposal/blob/master/README.md#get-arrayprototypereversed-get-typedarrayprototypereversed
>
> (I've got a myriad of other related stuff there, too.)
>
>
> On Thu, Jul 19, 2018, 04:41 Dmitry Shulgin  wrote:
>
>> Above we was talking about this.
>> consistency and handy using -- two main reasons for this proposal.
>>
>> `reverse` will also mutate my array, cause of in-place implementation.
>>
>> You can find workaround for many existing methods, but it's not handy to
>> my mind.
>>
> ___
> 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: Feature proposal

2018-07-19 Thread T.J. Crowder
On Thu, Jul 19, 2018 at 9:49 AM, Isiah Meadows
 wrote:
> What about this alternate proposal:

Great minds: https://esdiscuss.org/topic/fwd-feature-proposal#content-5 ;-)

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


Re: Feature proposal

2018-07-19 Thread Isiah Meadows
What about this alternate proposal:

https://github.com/isiahmeadows/array-additions-proposal/blob/master/README.md#get-arrayprototypereversed-get-typedarrayprototypereversed

(I've got a myriad of other related stuff there, too.)

On Thu, Jul 19, 2018, 04:41 Dmitry Shulgin  wrote:

> Above we was talking about this.
> consistency and handy using -- two main reasons for this proposal.
>
> `reverse` will also mutate my array, cause of in-place implementation.
>
> You can find workaround for many existing methods, but it's not handy to
> my mind.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Feature proposal

2018-07-19 Thread Dmitry Shulgin
Above we was talking about this.
consistency and handy using -- two main reasons for this proposal.

`reverse` will also mutate my array, cause of in-place implementation.

You can find workaround for many existing methods, but it's not handy to my
mind.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss