Re: Private fields in sub-objects within class definition.

2020-08-09 Thread Michael Theriot
Why stop at class definitions?

e.g.
```js
let obj;
{
  let local = 0;
  obj = {
get local() {
  return local;
}
  }
}
```

becomes
```js
const obj = {
  #local: 0,
  get local() {
return this.#local;
  }
}
```

On Fri, Aug 7, 2020 at 3:33 PM #!/JoePea  wrote:

> Not sure if the following is exactly how we'd want it to be, but it
> would be useful:
>
> ```js
> class Foo {
>   // calculatedValue is intended to have read-only properties
>   calculatedValue = {
> #x: 0,
> get x() { return this.#x },
> #y: 0,
> get y() { return this.#y },
> #z: 0,
> get z() { return this.#z },
>   }
>
>   update() {
> this.calculatedValue.#x = 42 // ok
> this.calculatedValue.#y = 42 // ok
> this.calculatedValue.#z = 42 // ok
>   }
> }
> ```
>
> End user:
>
> ```js
> const foo = new Foo
> foo.calculatedValue.x // ok
> foo.calculatedValue.#x // syntax error
> ```
>
> We could currently do something like this:
>
> ```js
> class Foo {
>   #calcX = 0
>   #calcY = 0
>   #calcZ = 0
>
>   // calculatedValue is intended to have read-only properties
>   calculatedValue = (() => {
> const self = this
> return {
>   get x() { return self.#calcX },
>   get y() { return self.#calcY },
>   get z() { return self.#calcZ },
> }
>   })()
>
>   update() {
> this.#calcX = 42 // ok
> this.#calcY = 42 // ok
> this.#calcZ = 42 // ok
>   }
> }
> ```
>
> Any plans for something like this? Is there a plan for private fields
> for object literals? If so, maybe that can somehow tie into usage
> within class bodies with WeakMap-ish semantics.
>
> #!/JoePea
> ___
> 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: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-12 Thread Michael Theriot
I assume OP wants to use proxies and private members together. They are not
designed to be compatible.

Proxies and private members are a UX goal primarily for developers. Proxies
easily allow observation of another object or creation of exotic objects
(e.g. Array), and private members (safely) allow classes with internal
slots. Since they cannot be used together the issue exists, and the hack
circumvents this by reimplementing private in a way that does not require
private fields.

On Sun, Jul 12, 2020 at 4:45 PM kai zhu  wrote:

> as product-developer, can i ask what ux-objective you ultimately want
> achieved?
>
> ```js
> const sub = new Sub()
>
> // i'm a noob on proxies. what is this thing (with proxied-private-fields)
> ultimately used for?
> const proxy = new Proxy(sub, ...)
> ```
>
> On Sun, Jul 12, 2020 at 4:34 PM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> This does require you to have both the key and the weakmap though, so it
>> actually does succeed in hiding the data so long as the weakmap is out of
>> scope. I guess the issue I can foresee is that the key could be modified
>> after the object is created.
>>
>> e.g.
>> ```js
>> var a = new A();
>> var key = Object.getOwnPropertySymbols(a)[0];
>> delete a[key];
>> a.hidden; // throws
>> ```
>>
>> That itself can be guarded by just making the key undeletable. So, I
>> guess this solution could work depending what your goals are?
>>
>> On Sun, Jul 12, 2020 at 4:21 PM Michael Theriot <
>> michael.lee.ther...@gmail.com> wrote:
>>
>>> It nearly works, but the issue is that the key will be leaked by
>>> `Object.getOwnPropertySymbols(new A())`, so it's not truly private.
>>>
>>> There have been ideas proposing "private symbols" but I am not familiar
>>> with their issues, and I would guess with Class Fields they are unlikely to
>>> materialize anyway.
>>>
>>> On Sun, Jul 12, 2020 at 2:19 PM François REMY <
>>> francois.remy@outlook.com> wrote:
>>>
>>>> At the risk of pointing out the obvious:
>>>>
>>>>
>>>>
>>>> ```js
>>>>
>>>> const privkey = Symbol();
>>>>
>>>> const stores = new WeakMap();
>>>>
>>>>
>>>>
>>>> class A {
>>>>
>>>>   [privkey] = {};
>>>>
>>>>   constructor() {
>>>>
>>>> const priv = {};
>>>>
>>>>     priv.hidden = Math.random();
>>>>
>>>> stores.set(this[privkey], priv);
>>>>
>>>>   }
>>>>
>>>>
>>>>
>>>>   get hidden() {
>>>>
>>>> const priv = stores.get(this[privkey]);
>>>>
>>>> return priv.hidden;
>>>>
>>>>   }
>>>>
>>>> }
>>>>
>>>>
>>>>
>>>> var as = [
>>>>
>>>> new A(),
>>>>
>>>> new Proxy(new A(),{}),
>>>>
>>>> new Proxy(new A(),{}),
>>>>
>>>> ];
>>>>
>>>> console.log(as.map(a=>a.hidden));
>>>>
>>>> ```
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>> *From: *Michael Theriot 
>>>> *Sent: *Sunday, July 12, 2020 20:59
>>>> *To: *Michael Haufe 
>>>> *Cc: *es-discuss@mozilla.org
>>>> *Subject: *Re: Why does a JavaScript class getter for a private field
>>>> fail using a Proxy?
>>>>
>>>>
>>>>
>>>> I experienced this issue prior to this proposal, using weakmaps for
>>>> private access.
>>>>
>>>>
>>>>
>>>> e.g.
>>>>
>>>> ```js
>>>>
>>>> const stores = new WeakMap();
>>>>
>>>> class A {
>>>>   constructor() {
>>>> const priv = {};
>>>> priv.hidden = 0;
>>>> stores.set(this, priv);
>>>>   }
>>>>
>>>>   get hidden() {
>>>> const priv = stores.get(this);
>>>> return priv.hidden;
>>>>   }
>>>> }
>>>>
>>>> const a = new A();
>>>> console.log(a.hidden); // 0
>>>>
>>>> const p = new Proxy(a, {});
>>>> console.log(p.hi

Re: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-12 Thread Michael Theriot
This does require you to have both the key and the weakmap though, so it
actually does succeed in hiding the data so long as the weakmap is out of
scope. I guess the issue I can foresee is that the key could be modified
after the object is created.

e.g.
```js
var a = new A();
var key = Object.getOwnPropertySymbols(a)[0];
delete a[key];
a.hidden; // throws
```

That itself can be guarded by just making the key undeletable. So, I guess
this solution could work depending what your goals are?

On Sun, Jul 12, 2020 at 4:21 PM Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> It nearly works, but the issue is that the key will be leaked by
> `Object.getOwnPropertySymbols(new A())`, so it's not truly private.
>
> There have been ideas proposing "private symbols" but I am not familiar
> with their issues, and I would guess with Class Fields they are unlikely to
> materialize anyway.
>
> On Sun, Jul 12, 2020 at 2:19 PM François REMY <
> francois.remy@outlook.com> wrote:
>
>> At the risk of pointing out the obvious:
>>
>>
>>
>> ```js
>>
>> const privkey = Symbol();
>>
>> const stores = new WeakMap();
>>
>>
>>
>> class A {
>>
>>   [privkey] = {};
>>
>>   constructor() {
>>
>> const priv = {};
>>
>> priv.hidden = Math.random();
>>
>> stores.set(this[privkey], priv);
>>
>>   }
>>
>>
>>
>>   get hidden() {
>>
>> const priv = stores.get(this[privkey]);
>>
>> return priv.hidden;
>>
>>   }
>>
>> }
>>
>>
>>
>> var as = [
>>
>> new A(),
>>
>> new Proxy(new A(),{}),
>>
>> new Proxy(new A(),{}),
>>
>> ];
>>
>> console.log(as.map(a=>a.hidden));
>>
>> ```
>>
>>
>>
>>
>>
>>
>>
>> *From: *Michael Theriot 
>> *Sent: *Sunday, July 12, 2020 20:59
>> *To: *Michael Haufe 
>> *Cc: *es-discuss@mozilla.org
>> *Subject: *Re: Why does a JavaScript class getter for a private field
>> fail using a Proxy?
>>
>>
>>
>> I experienced this issue prior to this proposal, using weakmaps for
>> private access.
>>
>>
>>
>> e.g.
>>
>> ```js
>>
>> const stores = new WeakMap();
>>
>> class A {
>>   constructor() {
>> const priv = {};
>> priv.hidden = 0;
>> stores.set(this, priv);
>>   }
>>
>>   get hidden() {
>> const priv = stores.get(this);
>> return priv.hidden;
>>   }
>> }
>>
>> const a = new A();
>> console.log(a.hidden); // 0
>>
>> const p = new Proxy(a, {});
>> console.log(p.hidden); // throws!
>>
>> ```
>>
>>
>>
>> I found a workaround:
>>
>>
>>
>> ```js
>> const stores = new WeakMap();
>>
>> class A {
>>   constructor() {
>> const priv = {};
>> priv.hidden = 0;
>> stores.set(this, priv);
>>
>> const p = new Proxy(this, {});
>> stores.set(p, priv); // set proxy to map to the same private store
>>
>> return p;
>>   }
>>
>>   get hidden() {
>> const priv = stores.get(this); // the original instance and proxy
>> both map to the same private store now
>> return priv.hidden;
>>   }
>> }
>>
>> const a = new A();
>>
>> console.log(a.hidden);
>> ```
>>
>>
>>
>> Not ideal, and only works if you provide the proxy in the first place
>> (e.g. making exotic JS objects). But, not necessarily a new issue with
>> proxies, either.
>>
>>
>>
>> On Fri, Jun 5, 2020 at 12:29 AM Michael Haufe 
>> wrote:
>>
>> This is a known issue and very painful for me as well. You can see a long
>> ugly discussion here:
>>
>>
>>
>> <https://github.com/tc39/proposal-class-fields/issues/106>
>>
>>
>>
>> I suggest the following guide to assist you:
>>
>>
>>
>> <https://javascript.info/proxy#proxy-limitations>
>>
>>
>>
>> Another possible approach is to have your classes extend a proxy:
>>
>>
>>
>> <
>> https://github.com/tc39/proposal-class-fields/issues/106#issuecomment-397484713
>> >
>>
>>
>>
>>
>>
>> *From:* es-discuss  *On Behalf Of *Laurie
>> Harper
>> *Sent:* Friday, June 5, 2020 12:21 AM
>> *To:* es-discuss@mozilla.org
>>

Re: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-12 Thread Michael Theriot
It nearly works, but the issue is that the key will be leaked by
`Object.getOwnPropertySymbols(new A())`, so it's not truly private.

There have been ideas proposing "private symbols" but I am not familiar
with their issues, and I would guess with Class Fields they are unlikely to
materialize anyway.

On Sun, Jul 12, 2020 at 2:19 PM François REMY 
wrote:

> At the risk of pointing out the obvious:
>
>
>
> ```js
>
> const privkey = Symbol();
>
> const stores = new WeakMap();
>
>
>
> class A {
>
>   [privkey] = {};
>
>   constructor() {
>
> const priv = {};
>
> priv.hidden = Math.random();
>
> stores.set(this[privkey], priv);
>
>   }
>
>
>
>   get hidden() {
>
> const priv = stores.get(this[privkey]);
>
> return priv.hidden;
>
>   }
>
> }
>
>
>
> var as = [
>
> new A(),
>
>     new Proxy(new A(),{}),
>
> new Proxy(new A(),{}),
>
> ];
>
> console.log(as.map(a=>a.hidden));
>
> ```
>
>
>
>
>
>
>
> *From: *Michael Theriot 
> *Sent: *Sunday, July 12, 2020 20:59
> *To: *Michael Haufe 
> *Cc: *es-discuss@mozilla.org
> *Subject: *Re: Why does a JavaScript class getter for a private field
> fail using a Proxy?
>
>
>
> I experienced this issue prior to this proposal, using weakmaps for
> private access.
>
>
>
> e.g.
>
> ```js
>
> const stores = new WeakMap();
>
> class A {
>   constructor() {
> const priv = {};
> priv.hidden = 0;
> stores.set(this, priv);
>   }
>
>   get hidden() {
> const priv = stores.get(this);
> return priv.hidden;
>   }
> }
>
> const a = new A();
> console.log(a.hidden); // 0
>
> const p = new Proxy(a, {});
> console.log(p.hidden); // throws!
>
> ```
>
>
>
> I found a workaround:
>
>
>
> ```js
> const stores = new WeakMap();
>
> class A {
>   constructor() {
> const priv = {};
> priv.hidden = 0;
> stores.set(this, priv);
>
> const p = new Proxy(this, {});
> stores.set(p, priv); // set proxy to map to the same private store
>
> return p;
>   }
>
>   get hidden() {
> const priv = stores.get(this); // the original instance and proxy both
> map to the same private store now
> return priv.hidden;
>   }
> }
>
> const a = new A();
>
> console.log(a.hidden);
> ```
>
>
>
> Not ideal, and only works if you provide the proxy in the first place
> (e.g. making exotic JS objects). But, not necessarily a new issue with
> proxies, either.
>
>
>
> On Fri, Jun 5, 2020 at 12:29 AM Michael Haufe 
> wrote:
>
> This is a known issue and very painful for me as well. You can see a long
> ugly discussion here:
>
>
>
> <https://github.com/tc39/proposal-class-fields/issues/106>
>
>
>
> I suggest the following guide to assist you:
>
>
>
> <https://javascript.info/proxy#proxy-limitations>
>
>
>
> Another possible approach is to have your classes extend a proxy:
>
>
>
> <
> https://github.com/tc39/proposal-class-fields/issues/106#issuecomment-397484713
> >
>
>
>
>
>
> *From:* es-discuss  *On Behalf Of *Laurie
> Harper
> *Sent:* Friday, June 5, 2020 12:21 AM
> *To:* es-discuss@mozilla.org
> *Subject:* Why does a JavaScript class getter for a private field fail
> using a Proxy?
>
>
>
> I can expose private class fields in JavaScript using getters, and those
> getters work correctly when invoked on instances of a subclass. However, if
> I then wrap the instance with a proxy the getter will throw a type error,
> even if the proxy `get` hook uses `Reflect.get()`:
>
> ```
> class Base {
> _attrA
> #_attrB
>
> constructor() {
> this._attrA = 100
> this.#_attrB = 200
> }
>
> get A() { return this._attrA }
>
> get B() { return this.#_attrB }
>
> incrA() { this._attrA++ }
>
> incrB() { this.#_attrB++ }
> }
>
> class Sub extends Base {}
>
> const sub = new Sub()
>
> const proxy = new Proxy(sub, {
> get(target, prop, receiver) {
> const value = Reflect.get(target, prop, receiver)
> return typeof value === 'function' ? value.bind(target) : value //
> (1)
> }
> })
>
> console.log('sub.A', sub.A) // OK: -> 100
> console.log('sub.B', sub.B) // OK: -> 200
> sub.incrA() // OK
> sub.incrB() // OK
> console.log('sub.A', sub.A) // OK: -> 101
> console.log('sub.B', sub.B) // OK: -> 201
>
> console.log('proxy.A', proxy.A) // OK: -> 100
> conso

Re: Why does a JavaScript class getter for a private field fail using a Proxy?

2020-07-12 Thread Michael Theriot
I experienced this issue prior to this proposal, using weakmaps for private
access.

e.g.
```js
const stores = new WeakMap();

class A {
  constructor() {
const priv = {};
priv.hidden = 0;
stores.set(this, priv);
  }

  get hidden() {
const priv = stores.get(this);
return priv.hidden;
  }
}

const a = new A();
console.log(a.hidden); // 0

const p = new Proxy(a, {});
console.log(p.hidden); // throws!
```

I found a workaround:

```js
const stores = new WeakMap();

class A {
  constructor() {
const priv = {};
priv.hidden = 0;
stores.set(this, priv);

const p = new Proxy(this, {});
stores.set(p, priv); // set proxy to map to the same private store

return p;
  }

  get hidden() {
const priv = stores.get(this); // the original instance and proxy both
map to the same private store now
return priv.hidden;
  }
}

const a = new A();

console.log(a.hidden);
```

Not ideal, and only works if you provide the proxy in the first place (e.g.
making exotic JS objects). But, not necessarily a new issue with proxies,
either.

On Fri, Jun 5, 2020 at 12:29 AM Michael Haufe 
wrote:

> This is a known issue and very painful for me as well. You can see a long
> ugly discussion here:
>
>
>
> 
>
>
>
> I suggest the following guide to assist you:
>
>
>
> 
>
>
>
> Another possible approach is to have your classes extend a proxy:
>
>
>
> <
> https://github.com/tc39/proposal-class-fields/issues/106#issuecomment-397484713
> >
>
>
>
>
>
> *From:* es-discuss  * On Behalf Of *Laurie
> Harper
> *Sent:* Friday, June 5, 2020 12:21 AM
> *To:* es-discuss@mozilla.org
> *Subject:* Why does a JavaScript class getter for a private field fail
> using a Proxy?
>
>
>
> I can expose private class fields in JavaScript using getters, and those
> getters work correctly when invoked on instances of a subclass. However, if
> I then wrap the instance with a proxy the getter will throw a type error,
> even if the proxy `get` hook uses `Reflect.get()`:
>
> ```
> class Base {
> _attrA
> #_attrB
>
> constructor() {
> this._attrA = 100
> this.#_attrB = 200
> }
>
> get A() { return this._attrA }
>
> get B() { return this.#_attrB }
>
> incrA() { this._attrA++ }
>
> incrB() { this.#_attrB++ }
> }
>
> class Sub extends Base {}
>
> const sub = new Sub()
>
> const proxy = new Proxy(sub, {
> get(target, prop, receiver) {
> const value = Reflect.get(target, prop, receiver)
> return typeof value === 'function' ? value.bind(target) : value //
> (1)
> }
> })
>
> console.log('sub.A', sub.A) // OK: -> 100
> console.log('sub.B', sub.B) // OK: -> 200
> sub.incrA() // OK
> sub.incrB() // OK
> console.log('sub.A', sub.A) // OK: -> 101
> console.log('sub.B', sub.B) // OK: -> 201
>
> console.log('proxy.A', proxy.A) // OK: -> 100
> console.log('proxy.B', proxy.B) // TypeError: Cannot read private member
> #_attrB from an object whose class did not declare it
> proxy.incrA() // OK
> proxy.incrB() // OK due to (1)
> console.log('proxy.A', proxy.A) // OK: -> 100
> console.log('proxy.B', proxy.B) // TypeError: Cannot read private member
> #_attrB from an object whose class did not declare it
> ```
>
> The call to `proxy.incrB()` works, because the proxy handler explicitly
> binds function values to `target` on line (1). Without the `bind()` call,
> the `proxy.incrB()` invocation would throw a `TypeError` like the getter
> invocation does. That makes some sense: the result of the call to
> `Reflect.get()` is the 'unbound' function value of the property being
> retrieved, which must then be bound to `target`; it would make more sense,
> though, if `this` binding was applied by the [[Call]] operation on the
> result of the [[Get]] operation...
>
> But there is no opportunity to 'bind' a getter before invoking it; as a
> result, a proxied getter ends up receiving the wrong `this` binding,
> leading to the inconsistency.
>
> Is there any way to make this work correctly? The only approach I can
> think of (which I haven't tried) would be to have the `get` hook walk up
> the prototype chain, starting from `target`, calling
> `getOwnPropertyDescriptor()` and checking for a getter method, and
> explicitly applying the getter with an adjusted `this` binding. That sounds
> ludicrously cumbersome and brittle...
>
> Is there a better way to get this working correctly?
>
>
>
> --
>
> Laurie
> ___
> 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: Proposal: Static Typing

2019-03-27 Thread Michael Theriot
On Monday, March 25, 2019, ViliusCreator 
wrote:

> ```js
>
> let a = 10
>
> a += ‘1’ // ‘101’
>
> // or
>
> a += undefined // NaN
>
> ```
>
> VS this:
>
> ```js
>
> let a: number = 10
>
> a += ‘1’ // Error, cannot convert type string to type number.
>
> // or
>
> a += undefined // Error, number doesn’t have nullable mark.
>
> ```
>
Thought experiment:

```js

let a = 10;
let b: number = 10;
a === b; // true

```

Would an error at runtime or compiletime occur here?

```js

a += '1'; // ok
b += '1'; // error

```

If it is a runtime error, is it optimal for the engine to keep track of
typed variables vs regular for the same value?

If not and it is a compiletime error, what happens here?

```js

var x = something();

a += x;
b += x; // error?

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


Re: Proposal: 1) Number (integer or decimal) to Array 2) Array to Number (integer or decimal)

2019-03-10 Thread Michael Theriot
So this would help with precision?

On Sunday, March 10, 2019, guest271314  wrote:

> (If you really wanted this as an integer, it's not well-founded; .567
>> isn't exactly representable as a double, so JS doesn't know that you
>> "meant" it to have only three digits after the decimal point, and thus
>> want 567 as the answer. You'll instead get some very very large
>> integer that *starts with* 567, followed by a bunch of zeros, followed
>> by some randomish digits at the end.)
>
>
> The code at the first post solves that problem.
>
> But the question is still "what would someone use this information for?"
>
>
> That question has been answered several times in the posts above. This
> users' motivation was and is the ability to manipulate JavaScript
> floating-point numbers  (which could be considered "broken", as you
> described above) in order to solve mathematical problems (in this case,
> directly calculating the *n*th lexicographic permutation) with the number
> or decimal being represented as an array, without having to be concerned
> with not getting the same value when the array is converted back to a
> number.
>
> Felipe Nascimento de Moura mentioned several other applications.
>
> The work has already been done. This proposal is essentially to
> standardize the naming conventions. Whether a Number method is used
>
> i.getTensMethod
>
> or an array is used
>
>arr["integer"] // 1234
>
> or an object where values are arrays is used
>
> o["fraction"] // .567
>
> Having mentioned Intl.NumberFormat earlier in the thread, if the issue
> devoting resources to a *new *proposal, Intl.NumberFormate can be
> extended; e.g. a rough draft in code
>
> function formatNumberParts(args) {
>   return Object.assign({sign:0, fraction:[0], integer:[0]},
> ...args.filter(({type}) => type === "integer" || type === "fraction" ||
> type === "minusSign").map(({type, value}) => ({[type === "minusSign" ?
> "sign" : type]: type !== "minusSign" ? [...value].map(Number) : -1})));
> }
>
> let number = -123;
>
> let formatter = new Intl.NumberFormat('en-US');
>
> let res = formatter.formatToParts(number);
>
> formatNumberParts(res);
>
> If the concern is that the proposal would not be useful, consider what you
> would *name* various uses of Math.trunc and remainder operator used at
> your message?
>
>
> On Sun, Mar 10, 2019 at 3:58 PM Tab Atkins Jr. 
> wrote:
>
>> On Sat, Mar 9, 2019 at 11:10 AM Felipe Nascimento de Moura
>>  wrote:
>> >
>> > Personally, I don't think it would be THAT useful...
>> > but...I think there is something behind this proposal that makes sense.
>> >
>> > I do believe it could be useful for developers to have an easier access
>> to number parts or characteristics.
>> > Perhaps something like:
>> >
>> > const i = 1234.567;
>>
>> Can you provide a scenario in which these would do something useful,
>> such that it would be worth adding them over just using the math
>> operations that already exist?
>>
>> > console.log( i.float ); // 567
>>
>> i % 1
>>
>> (If you really wanted this as an integer, it's not well-founded; .567
>> isn't exactly representable as a double, so JS doesn't know that you
>> "meant" it to have only three digits after the decimal point, and thus
>> want 567 as the answer. You'll instead get some very very large
>> integer that *starts with* 567, followed by a bunch of zeros, followed
>> by some randomish digits at the end.)
>>
>> > console.log( i.abs ); // 1234
>>
>> Math.trunc(i)
>>
>> > console.log( i.thousands ); // 1
>>
>> Math.trunc(i / 1000)
>>
>> > console.log( i.million ); // 0
>>
>> Math.trunc(i / 1e6)
>>
>> > console.log( i.hundred ); // 2
>>
>> Math.trunc(i / 100) % 10
>>
>> > console.log( i.hundreds ); // 12
>>
>> Math.trunc(i / 100)
>>
>> > console.log( i.ten ); // 2
>>
>> Math.trunc(i / 10) % 10
>>
>> > console.log( i.tens ); // 123
>>
>> Math.trunc(i / 10)
>>
>> > console.log( i.tenth ); // 5
>>
>> Math.trunc(i % 1 * 10) % 10
>>
>> > console.log( i.tenths ); // 5
>>
>> Math.trunc(i % 1 * 10)
>>
>> > console.log( i.hundredth ); // 6
>>
>> Math.trunc(i % 1 * 100) % 10
>>
>> > console.log( i.hundredths ); // 56
>>
>> Math.trunc(i % 1 * 100)
>>
>>
>> Some of these are easy to remember and use; others take some thinking
>> to deploy. But the question is still "what would someone use this
>> information for?", such that the benefit to developers is worth the
>> cost to all parties involved (spec writers, implementors, testers, and
>> then developers having to navigate a larger stdlib).
>>
>> ~TJ
>> ___
>> 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 ES6.

2018-08-14 Thread Michael Theriot
I've been brainstorming a few days and this is the same idea I reached. I
just wasn't sure if returning some kind of special object (JSON.Fragment)
was a good way to handle stringify.

Elaborating, basically a third argument would come back in JSON.parse
reviver method, which is the actual string that was parsed (not the parsed
value). When stringifying, a JSON.Fragment would not get parsed but inserts
the underlying string value (which must be valid JSON).

JSON.Fragment would just be a way to use valid, raw strings in JSON. E.g.
JSON.stringify([0]) === JSON.stringify(JSON.Fragment("[0]")

On Tuesday, August 14, 2018, Michał Wadas  wrote:

> Personally, I would like to see:
> - third argument to JSON.parse reviver, "raw string"
> - new class JSON.Fragment accepting any syntactically valid JSON in
> constructor (eg. new JSON.Fragment('9')
> - returning JSON.Fragment from JSON.stringify would paste it as-it-is into
> string output
>
> This should cover any Bigint use case without breaking backward
> compatibility.
>
> On Tue, 14 Aug 2018, 07:57 Anders Rundgren, 
> wrote:
>
>> On 2018-08-14 06:55, J Decker wrote:
>> > my primary usage of json is
>> > https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_
>> API/Writing_WebSocket_client_applications#Using_JSON_to_transmit_objects
>> >
>> > in which case JSON.parse( JSON.strinigfy( msg ) ) really needs to
>> result in the same sort of thing as the input; although I guess dates do
>> get lost in translation anyway, but they could be handled as numbers with a
>> few more character exceptions ':','-'(in a number),'Z',' ' the last one
>> (the space) complicating the whole thing immensely; there is no meaning of
>> multiple numbers without a ',' between them in JSON, so maybe not so
>> impossible.
>> >
>> > and given the requirement that seems to be lost, that bigints ONLY
>> interop with bigints, they MUST decode the same as their encoding; the
>> JSONnumber type almost works; but requires custom code every time bigints
>> are used. (much like dates)
>> >
>> > what writing a JSON parser taught me, is the type of a variable is the
>> type of the data it has; and JSON does a really good job of representing
>> 99% of generally communicated types. which makes generic code quite easy...
>> without having to respecify/recast the data, the data is already the type
>> it is.
>>
>> Since the JSON standard doesn't distinguish between a single bit or
>> BigNumber, I guess you are proposing extensions to JSON?
>>
>>
>> > but there's certainly fewer of me, than of those that thing everything
>> is perfectly fine, and shouldn't evolve as the langugage has.
>> > but then there's 'don't break the net' and 'this could certainy break
>> the net'; but since bigints didn't exist before, I guess they shouldn't be
>> added now, because sending them to old code would break  the old code
>> but actually since being added; should also update JSON to support that
>> number type (although I guess base JSON doesn't suppose ES6 number
>> encodings like 0x, 0b, etc...)
>> >
>> > and again, since bigints ONLY interop with other bigints, there should
>> be no chance they will get lost in interpretation.
>> >
>> > can see JSONnumber can aid application handling; but if you send
>> bigints to an application that doesn't support bigints it's not going to
>> work anyway; so why not just let existing json.parse throw when it doens't
>> have bigint support?
>>
>> The proposal is targeting *cross-platform applications* using JSON.  The
>> only thing it adds is offering a way to use JSON Number formatting for new
>> numeric types, in addition to the quoting schemes which already are fully
>> supported (and extensively used as well).
>>
>> Example: A java class element like `BigInteger big;` used in a JSON
>> context presumes that all values targeting "big" should be treated as
>> BigIntger (=BigInt).  However, there are different practices for formatting
>> BigIntegers in JSON and they are all "right" :-)
>>
>> In essence, the proposal's only ambition is making the ES6 JSON object
>> better aligned with an already established JSON reality.
>>
>> Anders
>>
>> > On Mon, Aug 13, 2018 at 12:33 AM Anders Rundgren <
>> anders.rundgren@gmail.com >
>> wrote:
>> >
>> > For good or for worse I have written a proposal for
>> https://github.com/tc39/proposal-bigint/issues/162
>> > available at https://github.com/cyberphone/
>> es6-bigint-json-support#json-support-for-bigint-in-es6
>> >
>> > Since the proposal doesn't introduce a default serialization mode,
>> I guess nobody will be happy :-(
>> > OTOH, a fairly decent rationale for not specifying a default is
>> also provided :-)
>> > This comment is also worth reading: https://github.com/tc39/
>> proposal-bigint/issues/162#issuecomment-409700859
>> >
>> >
>> > Cheers,
>> > Anders
>> > ___
>> > es-discuss mailing list

Re: Re: Implementing an identical JSON.stringify

2018-08-04 Thread Michael Theriot
>
> Regarding cases like Reflect.construct(Number, [], String), the reason
> this throws is because the ToNumber algorithm calls ToPrimitive if its
> operand is an object. This in turn will call String.prototype.valueOf on
> the object which does not have [[StringData]]. There’s nothing funny going
> on, it’s just a weird effect in aggregate. You would just need to implement
> all the steps here — internal ops like ToNumber, ToPrimitive, etc. It’s not
> that it "considers type", but rather that these algorithms will call
> methods by specific names on objects they receive. String.prototype and
> Object.prototype both implement "valueOf", but only the former will fail
> the slot check.
>

Thanks for demystifying this. I never realized it was just ducktyping
.valueOf on the object.

```js
Number.prototype.valueOf = () => 0;

JSON.stringify(1); // 1
JSON.stringify(new Number(1)); // 0
```

I guess what confused me is that it would detect a [[NumberData]] internal
slot, but instead of unboxing to that value it tries to ducktype call
.valueOf on the object. So the presence of [[NumberData]] changes the
behavior even if it does not actually use this value.

On Sat, Aug 4, 2018 at 10:14 PM Darien Valentine 
wrote:

> Is this a question about how/if one could replicate its behavior in theory
> from ES code, or are you suggesting a change to the existing behavior for
> these exotic cases?
>
> Assuming the former:
>
> The relevant steps are [here](
> https://tc39.github.io/ecma262/#sec-serializejsonproperty). The
> `instanceof` a value isn’t significant in this algorithm, just its slots
> (if it is an object) or its primitive type. So one can handle number and
> string by leveraging branded checks as you’ve shown — nothing more is
> needed than branded methods and typeof to manage that one.
>
> However it is ultimately not possible to replicate because there is no
> possible brand test for [[BooleanData]].
> ___
> 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: Implementing an identical JSON.stringify

2018-08-04 Thread Michael Theriot
>
> Try `Number.prototype.valueOf.call(obj)`: it will throw a TypeError if and
> only if `obj` has no [[NumberData]] internal slot. Ditto for String,
> Boolean and Symbol.


I already mention this and demonstrate why it is not sufficient in my
example.

Reiterated plainly:
```js
JSON.stringify(Reflect.construct(Number, [], Number)); // "0"
JSON.stringify(Reflect.construct(Number, [], String)); // TypeError
JSON.stringify(Reflect.construct(Number, [], Object)); // null
```

Even though both of these have [[NumberData]] internal slots, it also
considers the type when throwing. Hence the question if you can type check
cross-realm in a way that does not depend on internal slots.

On Sat, Aug 4, 2018 at 6:35 PM Claude Pache  wrote:

>
>
> > Le 5 août 2018 à 00:16, Michael Theriot 
> a écrit :
> >
> > `JSON.stringify` has unintuitive behavior regarding interal slots.
>
> I don’t think that anything involving an object that has a [[StringData]]
> internal slot but has `Number.prototype` in its prototype chain could have
> an ”intuitive” behaviour...
>
> >
> >
> > I think this is related to `Array.isArray`. Is there an equivalent
> `Number.isNumber`? Or is this just something only `JSON.stringify` can do?
>
> Try `Number.prototype.valueOf.call(obj)`: it will throw a TypeError if and
> only if `obj` has no [[NumberData]] internal slot. Ditto for String,
> Boolean and Symbol.
>
> —Claude
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Implementing an identical JSON.stringify

2018-08-04 Thread Michael Theriot
`JSON.stringify` has unintuitive behavior regarding interal slots.

```js
// Number with[[NumberData]]
// "0"
JSON.stringify(Object(Number(0)));

// Number without [[NumberData]]
// "{}"
JSON.stringify(Reflect.construct(Object, [], Number));

// Number without [[NumberData]]
// Number with[[StringData]]
// throws TypeError
JSON.stringify(Reflect.construct(String, [], Number));

// String with[[StringData]]
// ""
JSON.stringify(Object(String()));

// String without [[StringData]]
// "{}"
JSON.stringify(Reflect.construct(Object, [], String));

// String without [[StringData]]
// String with[[NumberData]]
// throws TypeError
JSON.stringify(Reflect.construct(Number, [], String));

// Object with[[StringData]]
// "[object String]"
JSON.stringify(Reflect.construct(String, [], Object));

// Object with[[NumberData]]
// null
JSON.stringify(Reflect.construct(Number, [], Object));
```

Weird, but not impossible to implement.

* You can detect class with instanceof
* You can detect internal slots by try-catching `.prototype.valueOf`

e.g.
```js
const isNumberInstance = (item) => item instanceof Number;
const isStringInstance = (item) => item instanceof String;

const hasNumberData = (item) => {
  try { Number.prototype.valueOf.call(item); } catch { return false; }
  return true;
};
const hasStringData = (item) => {
  try { String.prototype.valueOf.call(item); } catch { return false; }
  return true;
};
```

Since this relies on having a reference to the classes, it will not work
with an instance of `Number` from another realm for example.

```js
const item = Reflect.construct(iframe.contentWindow.String, [],
iframe.contentWindow.Number);

iframe.contentWindow.Number !== Number;
```

I think this is related to `Array.isArray`. Is there an equivalent
`Number.isNumber`? Or is this just something only `JSON.stringify` can do?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-08-04 Thread Michael Theriot
I also agree private properties / instance variables should not be
class-exclusive.

I was a big fan of the syntax used in the JavaScript Classes 1.1 proposal (
https://github.com/zenparsing/js-classes-1.1#1-instance-variables) and
always felt like it could have been painlessly extended to plain old
objects.

On Fri, Aug 3, 2018 at 11:30 PM, Bob Myers  wrote:

> >  `private`, `protected`, `class`, and a few other such keywords have all
> been part of ES since long be for the TC39 board got their hands on it.
> They hadn't been implemented, but they were all a very real part of ES.
>
> Whoa. Is that just misinformed or intentionally misleading? They have
> never been "part of ES" in any meaningful sense. It was not that they had
> not been implemented; it was that they had not even been defined. To say
> they are a "real part of ES" is a strange interpretation of the meaning of
> the word "real". The notion that we would choose features to work on based
> on some designation of certain keywords as reserved long ago, and that they
> are now "languishing", is odd. Why not focus on "implementing" enum, or
> final, or throws, or any other of the dozens of reserved words?
>
> Having said that, I think it is a valid general principle that as language
> designers we should be very reluctant to use magic characters. `**` is
> fine, of course, as is `=>`, or even `@` for decorators. Personally, I
> don't think the problem of access modifiers rises to the level of
> commonality and need for conciseness that would justify eating up another
> magic  character. We also don't want JS to start looking like Perl or APL.
>
> Speaking as a self-appointed representative of Plain Old Programmers, I do
> feel a need for private fields, although it was probably starting to
> program more in TS that got me thinking that way. However, to me it feels
> odd to tie this directly to `class` syntax. Why can't I have a private
> field in a plain old object like `{a: 1}` (i.e., that would only be
> accessible via a method on that object? We already have properties which
> are enumerable and writable, for example, independent of the class
> mechanism. Why not have properties which are private in the same way?
>
> The problem,of course, is that even assuming the engines implemented the
> `private` property on descriptors, I obviously don't want to have to write
> `Object.create({}, {a: {value: 22, private: true})`. So the problem can be
> restated as trying to find some nice sugar for writing the above.  You
> know, something like `{a: 22}`. That's obviously a completely
> random syntax suggestion, just to show the idea. Perhaps we'd prefer to
> have the access modifiers be specifiable under program control as an object
> itself, to allow something like
>
> ```
> const PRIVATE = {private: true};
>
> const myObject = {a(: 2; }
> ```
>
> But what would the precise meaning of such as `private` descriptor
> property be? In operational terms, it could suffice to imagine (as a
> behavior, not as an implementation strategy) that objects would have a flag
> that would skip over private properties when doing property lookups. I
> think the right implementation is to have a private property look like it's
> not there at all when access is attempted from outside the object (in other
> words, is undefined), rather than some kind of `PrivatePropertyAccessError`.
>
> The above approach ought to be extensible to class notation:
>
> ```
> class Foo (
>   bar(): { return 22; }
> }
> ```
>
> which would end up being something like `Object.defineProperty(Foo.prototype,
> "bar", {value() {return 22; }, private: true})`.
>
> Or when classes get instance variables:
>
> ```
> class Foo {
>   bar = 22;
> ```
>
> Was anything along these lines already brought up in this discussion?
>
> Bob
>
>
> On Sat, Aug 4, 2018 at 12:30 AM Ranando King  wrote:
>
>> > It certainly doesn't look or feel like JS - it feels more like Java or
>> C#.
>>
>> `private`, `protected`, `class`, and a few other such keywords have all
>> been part of ES since long be for the TC39 board got their hands on it.
>> They hadn't been implemented, but they were all a very real part of ES. Now
>> that `class` has been implemented, it makes little sense to leave behind
>> the `private` and `protected` keywords when we are trying to implement
>> their functionality.
>>
>> > `private` looks like an identifier, and IMHO getters, setters, and
>> async functions suffer the same issue of the keyword seeming to blend in a
>> little with surrounding code.
>>
>> Have you ever thought that `var` or `let` look like identifiers? The
>> `private` and `protected` keywords serve the same role as `var` and `let`:
>> declaring a variable within a given scope or context. If you think there is
>> a good logical or rational reason to avoid using the keywords that have
>> been embedded in the language and left languishing, waiting for their
>> meaning to be implemented, then I'm willing to entertain that. If the
>> 

Re: !Re: proposal: Object Members

2018-08-03 Thread Michael Theriot
I'd argue that is 1:1 with the way subclasses work today.

Protected properties can be implemented by sharing the weakmap instance
with the parent.

Private properties can be implemented by using a unique weakmap instance
for the subclass.

I actually think it's pretty straightforward and simple.

On Friday, August 3, 2018, Ranando King  wrote:

> > 1. It's *super incredibly boilerplatey* and verbose syntactically.
>
> I'm not sure what you mean by "boilerplatey". As for being verbose, I'm
> just using the keywords everyone understands for this purpose. IMO, there's
> no advantage in trying to find some shorthand to do the same thing just
> because it saves a keystroke or two when it makes the code significantly
> more difficult to understand.
>
> > 2. `protected` on an object literal is next to useless. I've used that kind
> of feature almost never.
>
> I get where you're coming from with that. I don't see it being used very
> often (kinda like `with`), but it has to be there. If someone wants to use
> the facilities of `class` without the limitations of the keyword, and the
> intent is to build vertical hierarchies, they'll need the "protected"
> keyword on their prototype definition to share private data with descendant
> factories. It's even more necessary for people writing factory factories.
> The only other way to achieve the same thing would be to force them to use
> `Function()` or `eval` and build up the code as strings. I'd rather avoid
> that.
>
> > I also find it odd you're supporting private dynamic properties.
>
> How'd you get to the idea that I'm supporting dynamic private properties?
> The first 2 paragraphs in the implementation say that all private container
> records are sealed, and all fields in info records are added read-only. If
> it wasn't clear from that, I'm going to have to re-write that section.
> However, the intent is that after the declaration process is complete, what
> you have is all you can get. No additional private fields can be added
> later. I considered dynamic private data, but that can get very messy very
> quickly.
>
> > I actually think it's odd there is no attempt to implement dynamic
> properties in the other "private properties" proposals.
>
> It's not that odd. There are issues around inheritance when a subclass can
> remove the `protected` properties of its base. Further, exactly how do you
> add a new `protected` property at runtime? Under both proposal-class-fields
> and proposal-object-members, there is never any direct access to the
> private container record, so use of `Object.defineProperty` will never
> work. IMO, any attempt to implement dynamic private properties in any
> sensible and consistent fashion would require somehow exposing the private
> data record to the code. That's a recipe for a private data leak. Not worth
> it.
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: !Re: proposal: Object Members

2018-08-03 Thread Michael Theriot
If I understand the terminology, "private dynamic properties" are easily
polyfilled via weakmaps?

I actually think it's odd there is no attempt to implement dynamic
properties in the other "private properties" proposals.

On Friday, August 3, 2018, Isiah Meadows  wrote:

> Okay, now that I look at that proposal, I see two issues right off:
>
> 1. It's *super incredibly boilerplatey* and verbose syntactically. I
> don't know very many people who'd be willing to downgrade very far
> from even what TypeScript has. (I'm specifically referring to the
> declarations here.)
> 2. `protected` on an object literal is next to useless. I've used that
> kind of feature almost never.
>
> I also find it odd you're supporting private dynamic properties. It
> does make polyfilling next to impossible, though.
>
> Just my 2 cents on it. (I glanced over this while very tired, so I
> probably missed several highlights. These are what stuck out to me.)
>
> -
>
> Isiah Meadows
> cont...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Wed, Aug 1, 2018 at 11:54 PM, Ranando King  wrote:
> > https://github.com/rdking/proposal-object-members/blob/master/README.md
> >
> > On Wed, Aug 1, 2018 at 2:01 AM Isiah Meadows 
> wrote:
> >>
> >> Do you have a link to this proposal so I can take a look at it? It'd
> >> be much easier to critique it if I could see the proposal text.
> >> -
> >>
> >> Isiah Meadows
> >> cont...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Wed, Aug 1, 2018 at 2:18 AM, Ranando King  wrote:
> >> >> If you go back a few months, what you're proposing is *very* similar,
> >> >> at
> >> >> least functionally, to my previous iteration of my proposal:
> >> >
> >> > That functional similarity is intentional. After pouring over years
> >> > worth of
> >> > posts, I figured out what the vast majority of the
> proposal-class-fields
> >> > detractors actually wanted: an elegant, easily recognized syntax for
> >> > adding
> >> > private members to objects.
> >> >
> >> >> My main problem was that trying to limit private properties to
> objects
> >> >> created within a scope got complicated in a hurry once you considered
> >> >> all
> >> >> the small details, and it just didn't seem simple anymore.
> >> >
> >> > I noticed that about your proposal too. I'm also pretty sure that
> Daniel
> >> > E.
> >> > and Kevin G. ran into the same issues back during the
> >> > proposal-private-names
> >> > days which is why the private names concept is just an implementation
> >> > detail
> >> > in their current proposal. My proposal is made less complicated by
> >> > breaking
> >> > the problem down into the 3 pieces required to make it all work:
> >> > 1. a record to store private data
> >> > 2. an array to hold references to the schema records of accessible
> >> > private
> >> > data
> >> > 3. a schema record for the sharable data.
> >> >
> >> > In this way private = encapsulated on a non-function, protected =
> >> > private +
> >> > shared, and static = encapsulated on a function. It should be easy to
> >> > sort
> >> > out how the data would be stored given such simple definitions. These
> >> > simple
> >> > definitions also mean that encapsulation is naturally confined to
> >> > definitions. Attempts to alter that state lead to strange logical
> >> > contradictions and potential leaks of encapsulated data. I have
> thought
> >> > of
> >> > the possibility that private data could be added after definition, but
> >> > every
> >> > attempt I make to consider such a thing has so far led to a risk of
> >> > leaking.
> >> >
> >> > I've been working on some code that can serve as a proof-of-concept in
> >> > ES6.
> >> > It will implement all of my proposal that can reasonably be
> implemented
> >> > in
> >> > ES6 using Proxy. It's already in the proposal repository under the POC
> >> > branch, but it's still a WIP. For now, it already supports inheriting
> >> > from
> >> > native objects. I'm working on subclassing right now. By the time I
> get
> >> > done
> >> > (likely this coming Monday), it should support every feature in my
> >> > proposal.
> >> > I'm basically using it as a means to check the viability of my
> proposal.
> >> >
> >> > On Tue, Jul 31, 2018 at 4:35 PM Isiah Meadows  >
> >> > wrote:
> >> >>
> >> >> If you go back a few months, what you're proposing is *very* similar,
> >> >> at least functionally, to my previous iteration of my proposal:
> >> >>
> >> >>
> >> >> https://github.com/isiahmeadows/private-symbol-proposal/blob/
> c5c9781d9e76123c92d8fbc83681fdd3a9b0b319/README.md
> >> >>
> >> >> My main problem was that trying to limit private properties to
> objects
> >> >> created within a scope got complicated in a hurry once you considered
> >> >> all the small details, and it just didn't seem simple anymore. It
> only
> >> >> got more complicated when you started getting into the logistics of
> >> >> integrating with modules.
> >> >>
> >> >> So I've considered the issue and explored it pretty 

Re: !Re: proposal: Object Members

2018-07-31 Thread Michael Theriot
Should a sealed/frozen object be privately extensible? I don't actually
know, but interesting point.

On Tuesday, July 31, 2018, Ranando King  wrote:

> > Consider what people often use public symbols for now.
>
> I know that I use them as fixed-value unique keys (module globals) for
> properties on objects that I export and don't want others to be aware of or
> able to touch.
>
> > For example, consider this library [1]. In this case, they use a public
> symbol for their stuff in this file [2].
>
> And as I said before, if someone passes a non-extensible object to this
> library, it breaks. Since any library can request any object be sealed or
> frozen, the implementation of this library is too fragile.
>
> > Because here, it's not a cache, but it's literally extra associated
> data in the object. And also, in that case, you *want* the engine to see
> it as a property, since it can employ relevant IC caching for it.
>
> Here's a parallel for you. Right now, Google has a database with
> information about me on it. I don't have access to that information (module
> privacy) and that information isn't stored anywhere on me or my devices
> (module locality). This is a proper conceptual model. The information
> Google is keeping about me is information they generated. Why should I have
> to pay to store their information? Thankfully I don't. However, this is
> precisely what you're claiming to be a good use case. You want module
> privacy without module locality. If I were to play at a Kevin Gibbons-like
> response, I'd say you've identified the common pattern, but that pattern
> itself is a bad use case, and the use of private symbols as you have
> defined them doesn't do anything to correct the technical issue. Since you
> cannot stick new properties onto a non-extensible object, even private
> symbols won't solve the problem with your use case.
>
> > No, I'm not. I'm drawing a distinction between a pure many-to-one 
> > association
> (weak maps) and a "has a" relationship (private symbol properties).
>
> First, for any given property bag, the keys will need to be unique, but
> that doesn't force uniqueness onto the values. As such, even properties on
> an object provided by your "private Symbol" would still be many-1. When a
> 3rd party library wants to keep information associated with an arbitrary
> object, there are only 3 choices:
> * try to store that information on the object
>   * this is what you're advocating, but it's not a good pattern. It's too
> fragile, being subject to break if the incoming object is not extensible.
> * store the information as being associated to the object (WeakMap)
>   * this is the pattern that works in all cases (but the syntax is
> cumbersome and the implementation somewhat slow)
> * return a wrapper containing the original object and the new information
> (Proxy or custom wrapper)
>   * this is another possibility, but requires that any users accept and
> use the new Proxy or wrapper object in lieu of the original.
>
> > Another scenario is for JSDOM's `Window` implementation, where they have
> a few underscore-private variables like this [3]. That particular variable
> is used in several disparate parts throughout the code base [4], but is
> still conceptually a property. This is a case where a private symbol
> property is appropriate.
>
> It's not just "conceptually" a property. It's logically a property. Why?
> Because all the objects that it exists on were constructed somewhere within
> the JSDOM library. That's me putting _my_ keys in _my_ pocket. There's
> absolutely nothing wrong with that.
>
> > Conversely in this JSDOM file [5], it's just associating data with an 
> > arbitrary
> object it happens to have, and so using the weak map makes perfect sense.
>
> Conceptually speaking, this is the same scenario as SymbolTree. In both
> cases, the library is generating information associated with an object it
> doesn't own and didn't create.
>
> > BTW, you could make a similar argument against superclass private fields
> - it's like hiding valuable info in your wallet before you receive it for
> the first time, but even after dismantling it, you can't find any
> evidence of that valuable info.
>
> That dog don't hunt. The difference here is that in your use cases,
> library A is "sneakily" storing information on object B. In the case of
> superclass private fields, subclass B has "volunteered" to take on the
> information and functionality of class A. You've essentially compared
> apples and asteroids just because they both begin with "a".
>
> On Tue, Jul 31, 2018 at 2:15 AM Isiah Meadows 
> wrote:
>
>> > Isn't this precisely what WeakMaps are for? If the data is
>> > "module-internal", then the module needs to be the owner of the data
>> store.
>> > If the data is about "arbitrary objects" (object from outside the
>> module?)
>> > then those objects are the keys to the data store. If any object is
>> thrown
>> > away, the associated data is no longer needed. If this 

Re: Streaming regexp matching

2018-07-30 Thread Michael Theriot
I'll say I have at least a few times desired a way to stream input to
RegExp. To the point I fiddled around implementing a finite state machine.

My use cases:
1. short circuiting on nth capture
2. parsing streams

On Mon, Jul 30, 2018 at 2:39 PM, Isiah Meadows 
wrote:

> There's two things I've found that need suspendable matching:
>
> 1. Partially matching against a string, which is useful with
> interactive form validation and such.
> 2. Pattern matching and replacement over a character stream, which is
> useful for things like matching against files without loading the
> entire thing into memory or easier filtering of requests.
>
> Also, it'd be nice if there was a facility to get *all* matches,
> including duplicate group matches. This is often useful for simple
> parsing, where if such support existed, you could just use a Kleene
> star instead of the standard `exec` loops (which admittedly get old).
>
> And finally, we could avoid setting regexp globals here. That would
> speed up the matcher quite a bit.
>
> So, here's my proposal:
>
> - `regexp.matcher() -> matcher` - Create a streaming regexp matcher.
> - `matcher.consume(codePoint, charSize?) -> result | undefined` -
> Consume a Unicode code point or `-1` if no more characters exist, and
> return a match result, `undefined` if no match occurred. `charSize` is
> the number of bytes represented by `codePoint` (default: 1-2 if `/u`
> is set, 1 otherwise), so it can work with other encodings flexibly.
> - `matcher.nextPossibleStart -> number` - The next possible start the
> matcher could have, for more effective buffering and stream
> management. This is implementation-defined, but it *must* be be `-1`
> after the matcher completes, and it *must* be within [0, N) otherwise,
> where N is the next returned match.
> - `result.group -> string | number | undefined` - Return the group
> index/name of the current match, or `undefined` if it's just issuing a
> match of the global regexp.
> - `result.start -> number` - Return the matched value's start index.
> - `result.end -> number` - Return the matched value's end index.
> - This does *not* modify any globals or regexp instance members. It
> only reads `regexp.lastIndex` on creation. (It doesn't operate on
> strings, so it shouldn't return any it doesn't already have.)
>
> Most RegExp methods could similarly be built using this as a base: if
> they work on strings, they can iterate their code points.
>
> As for the various concerns:
>
> - Partial matching is just iterating a string's character codes and
> seeing if the matcher ever returned non-`undefined`.
> - Streaming pattern matching is pretty obvious from just reading the API.
> - Getting all matches is just iterating the string and returning an
> object with all the groups + strings it matched.
>
> So WDYT?
>
> /cc Mathias Bynens, since I know you're involved in this kind of
> text-heavy stuff.
>
> -
>
> Isiah Meadows
> cont...@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


Re: !Re: proposal: Object Members

2018-07-30 Thread Michael Theriot
I'll just say it feels inconsistent with how every other property is
configured. That the key itself holds magic behavior-changing information.
It's not a use case or overhead concern.

On Monday, July 30, 2018, Isiah Meadows  wrote:

> Um, no. The use case is *extremely* limited, and that ruins a few
> optimizations you could otherwise make with private symbols (like
> caching proxy forwarding without having to bail out).
>
> Besides, whether a symbol is private requires exactly one bit to
> store, so there's no real overhead with storing it on the object.
> Heck, if you want to optimize it better, you might choose to store
> that same bit on both the symbol and the object descriptor itself, and
> I'd expect engines to do just that - it saves a pointer dereference.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Mon, Jul 30, 2018 at 1:25 AM, Michael Theriot
>  wrote:
> > Also throwing this out there, symbols would now carry additional
> > information: private or normal. Would it be better to configure this on
> > objects instead?
> >
> > E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`
> >
> > (and then ideally sugar for this)
> >
> > That way a symbol's visibility on an object is information held on the
> > object rather than the primitive. A little more work involved, but lines
> up
> > with Object.defineProperty and symbols remain purely unique identifiers.
> >
> > On Monday, July 30, 2018, Isiah Meadows  wrote:
> >>
> >> I'm aware it's possible to misuse, but if concerns of misuse were a
> >> serious issue, we wouldn't have iterators, for example [1] [2]. But
> >> IMHO freeing weak maps from a role they weren't designed for
> >> substantially outweighs the risks of abusing them further (and the
> >> abuses are incredibly frequent).
> >>
> >> [1]:
> >> https://esdiscuss.org/topic/iterators-generators-finally-
> and-scarce-resources-was-april-10-2014-meeting-notes
> >> [2]: https://esdiscuss.org/topic/resource-management
> >>
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
> >>  wrote:
> >> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
> >> > think
> >> > it's a blocker though, and actually frees weakmaps from trying to fill
> >> > this
> >> > role.
> >> >
> >> >
> >> > On Sunday, July 29, 2018, Isiah Meadows 
> wrote:
> >> >>
> >> >> It will, but weak maps will still remain useful for cases when you're
> >> >> semantically dealing with a key/value map. In theory, you could
> >> >> implement a weak map on top of this [1], but in practice, it doesn't
> >> >> always make sense to do it. A good example of this is if you are
> >> >> "tagging" an object with data. If this data isn't really part of the
> >> >> object itself, you shouldn't be using a private symbol for it.
> Another
> >> >> good example is if you're doing simple caching and you need to clear
> >> >> the weak map by replacing it. Using private symbols for this doesn't
> >> >> really fit with the domain here, so you're more likely just to
> confuse
> >> >> future readers (including yourself) if you do this.
> >> >>
> >> >> [1]:
> >> >> https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472a
> d8
> >> >> -
> >> >>
> >> >> Isiah Meadows
> >> >> m...@isiahmeadows.com
> >> >> www.isiahmeadows.com
> >> >>
> >> >>
> >> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
> >> >>  wrote:
> >> >> > Private symbols sounds like an easy win. They would be painfully
> >> >> > simple,
> >> >> > real properties, not just variables with property imitation syntax
> >> >> > that
> >> >> > undoubtedly confuses people. With the added benefit that children
> can
> >> >> > truly
> >> >> > override the base class, freedom to define private members shared
> >> >> > across
> >> >> > otherwise unrelated objects, and even injection. My only concern is
> >> >> > that
> >> >> > it
> &

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Also throwing this out there, symbols would now carry additional
information: private or normal. Would it be better to configure this on
objects instead?

E.g. `Object.setPropertySymbolVisibility(object, symbol, true / false)`

(and then ideally sugar for this)

That way a symbol's visibility on an object is information held on the
object rather than the primitive. A little more work involved, but lines up
with Object.defineProperty and symbols remain purely unique identifiers.

On Monday, July 30, 2018, Isiah Meadows  wrote:

> I'm aware it's possible to misuse, but if concerns of misuse were a
> serious issue, we wouldn't have iterators, for example [1] [2]. But
> IMHO freeing weak maps from a role they weren't designed for
> substantially outweighs the risks of abusing them further (and the
> abuses are incredibly frequent).
>
> [1]: https://esdiscuss.org/topic/iterators-generators-finally-
> and-scarce-resources-was-april-10-2014-meeting-notes
> [2]: https://esdiscuss.org/topic/resource-management
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 10:55 PM, Michael Theriot
>  wrote:
> > Right, I wouldn't, but I'm concerned others would misuse it. I don't
> think
> > it's a blocker though, and actually frees weakmaps from trying to fill
> this
> > role.
> >
> >
> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
> >>
> >> It will, but weak maps will still remain useful for cases when you're
> >> semantically dealing with a key/value map. In theory, you could
> >> implement a weak map on top of this [1], but in practice, it doesn't
> >> always make sense to do it. A good example of this is if you are
> >> "tagging" an object with data. If this data isn't really part of the
> >> object itself, you shouldn't be using a private symbol for it. Another
> >> good example is if you're doing simple caching and you need to clear
> >> the weak map by replacing it. Using private symbols for this doesn't
> >> really fit with the domain here, so you're more likely just to confuse
> >> future readers (including yourself) if you do this.
> >>
> >> [1]: https://gist.github.com/isiahmeadows/
> a8494868c4b193dfbf7139589f472ad8
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
> >>  wrote:
> >> > Private symbols sounds like an easy win. They would be painfully
> simple,
> >> > real properties, not just variables with property imitation syntax
> that
> >> > undoubtedly confuses people. With the added benefit that children can
> >> > truly
> >> > override the base class, freedom to define private members shared
> across
> >> > otherwise unrelated objects, and even injection. My only concern is
> that
> >> > it
> >> > could cross into WeakMap use cases.
> >> >
> >> >
> >> > On Sunday, July 29, 2018, Isiah Meadows 
> wrote:
> >> >>
> >> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> >> https://github.com/tc39/proposal-class-fields/issues/115
> >> >>
> >> >> TL;DR: private symbols that proxies can't see and that can't be
> >> >> enumerated.
> >> >> -
> >> >>
> >> >> Isiah Meadows
> >> >> m...@isiahmeadows.com
> >> >> www.isiahmeadows.com
> >> >>
> >> >>
> >> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
> >> >>  wrote:
> >> >> >> What you're essentially asking for is a violatable private field,
> or
> >> >> >> as
> >> >> >> has been described by others, a "soft private".
> >> >> >
> >> >> > We might have different definitions here, but I would describe what
> >> >> > I’m
> >> >> > talking about as hard private. Soft private, at least as it appears
> >> >> > to
> >> >> > have
> >> >> > been defined in [prior
> >> >> >
> >> >> > discussions](https://github.com/tc39/proposal-private-
> fields/issues/33),
> >> >> > described an avenue where symbol keyed properties were given a new
> >> >> > syntactic
> >> >> > form — but they were still just regular symbol keys, and therefore

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Right, I wouldn't, but I'm concerned others would misuse it. I don't think
it's a blocker though, and actually frees weakmaps from trying to fill this
role.

On Sunday, July 29, 2018, Isiah Meadows  wrote:

> It will, but weak maps will still remain useful for cases when you're
> semantically dealing with a key/value map. In theory, you could
> implement a weak map on top of this [1], but in practice, it doesn't
> always make sense to do it. A good example of this is if you are
> "tagging" an object with data. If this data isn't really part of the
> object itself, you shouldn't be using a private symbol for it. Another
> good example is if you're doing simple caching and you need to clear
> the weak map by replacing it. Using private symbols for this doesn't
> really fit with the domain here, so you're more likely just to confuse
> future readers (including yourself) if you do this.
>
> [1]: https://gist.github.com/isiahmeadows/a8494868c4b193dfbf7139589f472ad8
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 10:05 PM, Michael Theriot
>  wrote:
> > Private symbols sounds like an easy win. They would be painfully simple,
> > real properties, not just variables with property imitation syntax that
> > undoubtedly confuses people. With the added benefit that children can
> truly
> > override the base class, freedom to define private members shared across
> > otherwise unrelated objects, and even injection. My only concern is that
> it
> > could cross into WeakMap use cases.
> >
> >
> > On Sunday, July 29, 2018, Isiah Meadows  wrote:
> >>
> >> BTW, I came up with an alternate proposal for privacy altogether:
> >> https://github.com/tc39/proposal-class-fields/issues/115
> >>
> >> TL;DR: private symbols that proxies can't see and that can't be
> >> enumerated.
> >> -
> >>
> >> Isiah Meadows
> >> m...@isiahmeadows.com
> >> www.isiahmeadows.com
> >>
> >>
> >> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
> >>  wrote:
> >> >> What you're essentially asking for is a violatable private field, or
> as
> >> >> has been described by others, a "soft private".
> >> >
> >> > We might have different definitions here, but I would describe what
> I’m
> >> > talking about as hard private. Soft private, at least as it appears to
> >> > have
> >> > been defined in [prior
> >> > discussions](https://github.com/tc39/proposal-private-
> fields/issues/33),
> >> > described an avenue where symbol keyed properties were given a new
> >> > syntactic
> >> > form — but they were still just regular symbol keys, and therefore
> could
> >> > be
> >> > introspected by outside agents who had not been given express
> privilege
> >> > to
> >> > do so:
> >> >
> >> >> [...] the core would be that "private state" is simply (public)
> >> >> symbol-named properties, with syntactic sugar for those symbols, and
> >> >> possibly some kind of introspection over them [...]
> >> >
> >> > The thread goes on to contrast the soft model with an earlier version
> of
> >> > the
> >> > private fields proposal seen today. The hard private example uses the
> >> > class
> >> > declaration as a pseudo-scope, but contrasting these two options as if
> >> > they
> >> > are binary is not accurate: hard private through module/function/block
> >> > scope
> >> > already exists, it is just difficult to work with in the context of
> >> > shared
> >> > prototypes — one must either use WeakMaps, technically giving
> _hardness_
> >> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype`
> /
> >> > `WeakMap.prototype.get|has|set`, or be willing to either not worry
> about
> >> > garbage collection or implement it manually. This could be solved for
> >> > with a
> >> > few rather undramatic changes, though.
> >> >
> >> > Notably, the first post there lists the following as a disadvantage of
> >> > the
> >> > soft model it describes:
> >> >
> >> >> Platform objects, both within ECMAScript and in embedding
> environments,
> >> >> contain hard private state. If a library wants to be high-fidelity
> and
> >> >> just
> >> >> like a pl

Re: !Re: proposal: Object Members

2018-07-29 Thread Michael Theriot
Private symbols sounds like an easy win. They would be painfully simple,
real properties, not just variables with property imitation syntax that
undoubtedly confuses people. With the added benefit that children can truly
override the base class, freedom to define private members shared across
otherwise unrelated objects, and even injection. My only concern is that it
could cross into WeakMap use cases.

On Sunday, July 29, 2018, Isiah Meadows  wrote:

> BTW, I came up with an alternate proposal for privacy altogether:
> https://github.com/tc39/proposal-class-fields/issues/115
>
> TL;DR: private symbols that proxies can't see and that can't be enumerated.
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
> www.isiahmeadows.com
>
>
> On Sun, Jul 29, 2018 at 12:23 AM, Darien Valentine
>  wrote:
> >> What you're essentially asking for is a violatable private field, or as
> >> has been described by others, a "soft private".
> >
> > We might have different definitions here, but I would describe what I’m
> > talking about as hard private. Soft private, at least as it appears to
> have
> > been defined in [prior
> > discussions](https://github.com/tc39/proposal-private-fields/issues/33),
> > described an avenue where symbol keyed properties were given a new
> syntactic
> > form — but they were still just regular symbol keys, and therefore could
> be
> > introspected by outside agents who had not been given express privilege
> to
> > do so:
> >
> >> [...] the core would be that "private state" is simply (public)
> >> symbol-named properties, with syntactic sugar for those symbols, and
> >> possibly some kind of introspection over them [...]
> >
> > The thread goes on to contrast the soft model with an earlier version of
> the
> > private fields proposal seen today. The hard private example uses the
> class
> > declaration as a pseudo-scope, but contrasting these two options as if
> they
> > are binary is not accurate: hard private through module/function/block
> scope
> > already exists, it is just difficult to work with in the context of
> shared
> > prototypes — one must either use WeakMaps, technically giving _hardness_
> > because of the forgeability of `global.WeakMap` / `WeakMap.prototype` /
> > `WeakMap.prototype.get|has|set`, or be willing to either not worry about
> > garbage collection or implement it manually. This could be solved for
> with a
> > few rather undramatic changes, though.
> >
> > Notably, the first post there lists the following as a disadvantage of
> the
> > soft model it describes:
> >
> >> Platform objects, both within ECMAScript and in embedding environments,
> >> contain hard private state. If a library wants to be high-fidelity and
> just
> >> like a platform object, soft-private state does not provide this
> (@domenic)
> >
> > ...but neither model there quite covers that use case. Platform objects
> > _can_ see each other’s private state (cf the `isView` example earlier, or
> > scan the DOM API specs / Chrome source a bit to find numerous examples).
> > It’s only the ES layer interacting with their interfaces that cannot.
> >
> > Such things can be achieved with ordinary scope, which is why the WeakMap
> > pattern has worked in practice in my experience to date, while
> > class-declaration-scoped privacy has not. It isn’t uncommon for a
> library’s
> > exposed interface to be composed of an object graph, where privacy is a
> > concern at this public interface level, but library internal state may be
> > interconnected in unexposed ways under the hood. The most familiar
> example
> > of this is a DOM node tree. As an experiment, perhaps try to implement
> the
> > relationships between HTMLFormElement, HTMLFormControlsCollection and the
> > various form control elements using either the main private fields
> proposal
> > or your alternative proposal and see what happens.
> >
> >> However, the guardian logic tries to verify that the function trying to
> >> access the private fields of an instance is a member of the same or
> >> descending prototype that was used to create that instance.
> >
> > Because I’m looking at this in terms of slots, I’d first point out that
> > prototypes don’t determine slottedness, the execution of some specific
> > constructor does. It’s during this process that slots are associated with
> > the newly minted object by its identity. But even the current private
> fields
> > proposal tracks this behavior closely, and I’m not sure how else it could
> > work. The [[Prototype]] slot of an object is typically mutable
> > (`R|O.setPrototypeOf`, `__proto__`) and forgeable (Proxy’s
> `getPrototypeOf`
> > trap). Why/how would its value matter when it comes to accessing private
> > state?
> >
> > ```js
> > const pattern = /foo/;
> > Reflect.setPrototypeOf(pattern, Date.prototype);
> > pattern instanceof Date; // true
> > pattern instanceof RegExp; // false
> > pattern.getMinutes(); // throws TypeError because [[DateValue]] slot is
> > missing
> > 

Re: JSON support for BigInt in Chrome/V8

2018-07-28 Thread Michael Theriot
I think we should move away from guessing and automagically parsing our
JSON. The fact is a JSON number != JS number. Perhaps in userland (or a
proposal...) JSON.parse could return with a JSONNumber object which the
developer decides to convert to BigInt or Number.

On Saturday, July 28, 2018, J Decker  wrote:

>
>
> On Sat, Jul 28, 2018 at 6:57 AM Michael Theriot <
> michael.lee.ther...@gmail.com> wrote:
>
>> In a language with arbitrary integer precision, Python 3 for example, the
>> way to parse a "BigInt" would just be a plain, human readable number
>> without quotes. The way to serialize it is the same. Any other kind of
>> representation is out of spec, a workaround, and belongs in userland.
>
>
> The problem with this, 'guessing' whether is't a Number() or a BigInt() is
> that numbers and bigint's don't interop.
>
> {a:123, b:123n}
> " { "a":123, "b":123 }"  any expressions that expect B to be a BigInt()
> will fail, becasue it will be in an expression of other bigints.
>
> bigInts aren't just a better Number type, but, rather require other
> bigints for their expressions.
>
>
>
>>
>> I think BigInt should serialize the same, not as strings or anything that
>> is not a number. JSON.parse being unable to parse back into BigInt is a
>> separate issue. It is solvable by using better parsing methods, not the
>> convenient built-in one which has other issues. E.g. a streaming JSON
>> parser that lets you inspect the key name and string being parsed can
>> handle this. Case solved and you can also redesign your code so you are not
>> creating a temporary object every single parse that you most likely copy
>> into actual objects later.
>>
>> Not serializing BigInt is questionable to me but even that can be solved
>> in userland.
>>
>> On Saturday, July 14, 2018, Anders Rundgren <
>> anders.rundgren@gmail.com> wrote:
>>
>>> var small = BigInt("5");
>>> var big = BigInt("553");
>>> JSON.stringify([big,small]);
>>> VM330:1 Uncaught TypeError: Do not know how to serialize a BigInt
>>> at JSON.stringify ()
>>> at :1:6
>>>
>>> JSON Number serialization has apparently reached a new level (of
>>> confusion).
>>>
>>> Personally I don't see the problem.  XML did just fine without
>>> hard-coded data types.
>>>
>>> The JSON type system is basically a relic from JavaScript.  As such it
>>> has proved to be quite useful.
>>> However, when you are outside of that scope, the point with the JSON
>>> type system gets pretty much zero since you anyway need to map extended
>>> types.
>>>
>>> Oracle's JSON-B solution which serializes small values as Number and
>>> large values as String rather than having a unified serialization based on
>>> the underlying data type seems like a pretty broken concept although indeed
>>> fully conforming to the JSON specification. "Like the Devil reads the
>>> Bible" as we say in Scandinavia :-)
>>>
>>> Adding a couple of double quotes is a major problem?  If so, it seems
>>> like a way more useful project making quotes optional for keys (named in a
>>> specific way), like they already are in JavaScript.
>>>
>>> Yeah, and of course adding support for comments.
>>>
>>> Anders
>>>
>>> ___
>>> 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: JSON support for BigInt in Chrome/V8

2018-07-28 Thread Michael Theriot
In a language with arbitrary integer precision, Python 3 for example, the
way to parse a "BigInt" would just be a plain, human readable number
without quotes. The way to serialize it is the same. Any other kind of
representation is out of spec, a workaround, and belongs in userland.

I think BigInt should serialize the same, not as strings or anything that
is not a number. JSON.parse being unable to parse back into BigInt is a
separate issue. It is solvable by using better parsing methods, not the
convenient built-in one which has other issues. E.g. a streaming JSON
parser that lets you inspect the key name and string being parsed can
handle this. Case solved and you can also redesign your code so you are not
creating a temporary object every single parse that you most likely copy
into actual objects later.

Not serializing BigInt is questionable to me but even that can be solved in
userland.

On Saturday, July 14, 2018, Anders Rundgren 
wrote:

> var small = BigInt("5");
> var big = BigInt("553");
> JSON.stringify([big,small]);
> VM330:1 Uncaught TypeError: Do not know how to serialize a BigInt
> at JSON.stringify ()
> at :1:6
>
> JSON Number serialization has apparently reached a new level (of
> confusion).
>
> Personally I don't see the problem.  XML did just fine without hard-coded
> data types.
>
> The JSON type system is basically a relic from JavaScript.  As such it has
> proved to be quite useful.
> However, when you are outside of that scope, the point with the JSON type
> system gets pretty much zero since you anyway need to map extended types.
>
> Oracle's JSON-B solution which serializes small values as Number and large
> values as String rather than having a unified serialization based on the
> underlying data type seems like a pretty broken concept although indeed
> fully conforming to the JSON specification. "Like the Devil reads the
> Bible" as we say in Scandinavia :-)
>
> Adding a couple of double quotes is a major problem?  If so, it seems like
> a way more useful project making quotes optional for keys (named in a
> specific way), like they already are in JavaScript.
>
> Yeah, and of course adding support for comments.
>
> Anders
>
> ___
> 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-26 Thread Michael Theriot
FWIW I have never heard of this terminology before either but in practice
have used the pattern myself.

On Thu, Jul 26, 2018 at 12:15 AM, Bob Myers  wrote:

> > It allows you to reveal things, selectively, just as the revealing
> module pattern does. \
>
> The revealing module pattern is so named precisely because it reveals (to
> clients) certain aspects of the "module" in question.
> Yes, it hides other aspects, but only by virtue of not revealing them.
> If you want to support the terminology of "revealing constructor pattern",
> could you please state *what* is being revealed, exactly, to *whom*?
> When I call a promise constructor I get back one thing and one thing only,
> which is a promise.
> Is the notion that it is the promise which is being revealed?
> In that sense, all APIs "reveal" their results.
> If is the intent of using this term that the content of the executor is
> being revealed to the coder when he views the code?
> All code is revealed when it is viewed.
> It would seem to me that to qualify for the name "revealing constructor
> pattern" it ought to be revealing something.
>
> >  (separately, the measure of "caught on" is not "there does not exist
> someone who has not heard of it")
>
> This group is not a court of law with evidentiary rules.
> That someone with a degree of interest in JS to the extent they are a
> regular on the ML has never heard of it would seem to mean at least that it
> has not caught on *widely*.
> I myself had worked with and read about ES6 promises extensively before I
> heard the term.
> Perhaps in the future I can write things like "It might be argued by some
> that there is some possibility that the evidence could conceivably be
> interpreted as indicating that it may be the case that it has not caught on
> widely"?
>
> In any case, "catching on", however you define it, would seem to require
> more than a grand total of two Google results for "revealing constructor
> pattern", one of which is by the person that invented it.
>
> Bob
>
> On Thu, Jul 26, 2018 at 3:13 AM Jordan Harband  wrote:
>
>> It allows you to reveal things, selectively, just as the revealing module
>> pattern does.
>>
>> (separately, the measure of "caught on" is not "there does not exist
>> someone who has not heard of it")
>>
>> On Wed, Jul 25, 2018 at 2:04 PM, Bob Myers  wrote:
>>
>>> Not to beat a dead horse but
>>>
>>> * No, it hasn't caught on, as evidenced by the recent poster who had
>>> never heard of it.
>>> * Yes, I know it's used to describe the Promise executor pattern.
>>> * "Revealing module pattern" reveals. The so-called "revealing
>>> constructor pattern" does not reveal anything. It hides. So the term is
>>> semantically incorrect from the beginning.
>>>
>>> Bob
>>>
>>> On Wed, Jul 25, 2018 at 10:55 PM Jordan Harband 
>>> wrote:
>>>
 It's already caught on - "revealing constructor pattern" is the pattern
 that describes the Promise executor.

 The "revealing module" pattern is obsolete anyways, but it functions on
 the same principle - using closures to reveal only explicit things instead
 of everything.

 On Wed, Jul 25, 2018 at 10:01 AM, Bob Myers  wrote:

> Yes, I've encountered this "revealing constructor" terminology and
> find it confusing. I hope it doesn't catch on.
> A lot of people are likely to try to associate it with the "revealing
> module" pattern, with which it actually has nothing in common.
> It's a strange term because this pattern, if one wants to characterize
> it in terms of "revealing" things,
> is more about what is **not** being revealed (to the outside world),
> not what is being revealed.
>
> It's a useful pattern seen also in the observable constructor, and
> probably deserves to have a good name,
> but I can't come up with anything myself, other than maybe the
> suboptimal "callback-based constructor".
>
> Bob
>
> On Wed, Jul 25, 2018 at 6:45 PM Isiah Meadows 
> wrote:
>
>> Here's a quick overview of the "revealing constructor" pattern, if it
>> helps: https://blog.domenic.me/the-revealing-constructor-pattern/
>> -
>>
>> Isiah Meadows
>> m...@isiahmeadows.com
>> www.isiahmeadows.com
>>
>>
>> On Wed, Jul 25, 2018 at 7:05 AM, Herbert Vojčík 
>> wrote:
>> >
>> >
>> > Isiah Meadows wrote on 20. 7. 2018 3:13:
>> >>
>> >> 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 

Re: javascript vision thing

2018-07-25 Thread Michael Theriot
Classes are just sugar for a predominant pattern.

On Wednesday, July 25, 2018, kai zhu  wrote:

> > Classes are widely used on the web. See any modern web framework.
>
> indeed, and i conjecture in doing so, developers have caused more harm
> than good for their employers in getting their web-projects shipped, when
> JSON-serialization web-integration problems arise.
>
> On Jul 25, 2018 17:44, "Michael Theriot" 
> wrote:
> >
> > Classes are widely used on the web. See any modern web framework.
> >
> >
> > On Wednesday, July 25, 2018, kai zhu  wrote:
> >>
> >> @tj, would you or i care about nodejs/javascript if the language did
> not exist in browsers?  in fact would anyone on tc39 give a damn about
> javascript (aside from its creator) in that scenario?  as i've said before
> [ad nauseam], the only drive most of us [non-frontend-developers] have in
> javascript is making our backend-programs accessible to the masses via
> browsers/webviews.  javascript’s dominance/relevance in industry is as a
> *web-integration* language.  and its aided by its special-ability to
> directly serialize JSON data-structures (an underrated, and very useful
> web-integration feature), while most of its competitors have to rely on
> clumsy, hard-to-serialize classes.
> >>
> >> there is no foreseeable future where javascript will be a better tool
> than java/c++/python/etc. for non web-related projects.  there is
> no foreseeable future where employers would hire nodejs-developers to work
> on non web-related projects.  so why does tc39 insist on pushing
> distracting language-features (clumsy java-like classes,
> non-integration-friendly meta-programming, static module-loading, etc.) for
> an unrealistic future-scenario that’s not going to happen?
> >>
> >> kai zhu
> >> kaizhu...@gmail.com
> >>
> >>> On 24 Jul 2018, at 5:56 PM, T.J. Crowder  com> wrote:
> >>>
> >>> On Tue, Jul 24, 2018 at 11:27 AM, kai zhu  wrote:
> >>>>
> >>>> tldr - tc39 should focus more on JSON-friendly
> javascript-language-features
> >>>> instead of wasting-time on hard-to-serialize classes/meta-programming.
> >>>
> >>>
> >>> This is a false dichotomy (the fallacy of the either/or choice). I'd
> >>> agree we're approaching, or at, the need for the next thing after
> >>> JSON, and that some focus on that would be a good thing. That doesn't
> >>> mean stopping work on other good things. Perhaps you could take the
> >>> lead on addressing the issues you run into. I'm sure constructive
> >>> input would be welcomed.
> >>>
> >>>> my problem with tc39, is that they “claim” javascript is a
> general-purpose
> >>>> language (and try to design it as such), when industry-wise, its
> really not.
> >>>
> >>>
> >>> Yes, it is. Just because you don't see it that way doesn't mean others
> >>> don't. And others have been telling you they see it differently
> >>> repeatedly over a long period of time on this list.
> >>>
> >>>> if tc39 is sincerely
> >>>> interested in keeping javascript a dominant/relevant language in
> industry,
> >>>> they should focus on *practical* (vs *academic*) features
> >>>
> >>>
> >>> `class` notation is practical (simplifying a common pattern and making
> >>> it less error-prone). (I know you don't use that pattern. That's fine.
> >>> But lots of people do, so it's practical for them whether you like the
> >>> pattern or not.) Promises are practical (simplifying and standardizing
> >>> callbacks, making them composable; again making them less
> >>> error-prone). `async`/`await` is HUGELY practical, massively
> >>> simplifying writing asynchronous code. Arrow functions, rest and
> >>> spread, default parameter values -- all practical. (NOT trying to put
> >>> words in your mouth, but if you were going to reply "Yes, but those
> >>> problems could already be solved in others ways.", then: Sure, and we
> >>> could all write assembly code, too. But it's *useful* to address these
> >>> in the language.)
> >>>
> >>> All of them are useful beyond the web. All are also useful in web
> programming.
> >>>
> >>> I have no problem with skepticism of specific proposals. What I would
> >>> find useful, though, would be a focus on the proposal's merits, rather
> >>> than constant 

Re: javascript vision thing

2018-07-25 Thread Michael Theriot
Classes are widely used on the web. See any modern web framework.

On Wednesday, July 25, 2018, kai zhu  wrote:

> @tj, would you or i care about nodejs/javascript if the language did not
> exist in browsers?  in fact would anyone on tc39 give a damn about
> javascript (aside from its creator) in that scenario?  as i've said before
> [ad nauseam], the only drive most of us [non-frontend-developers] have in
> javascript is making our backend-programs accessible to the masses via
> browsers/webviews.  javascript’s dominance/relevance in industry is as a
> *web-integration* language.  and its aided by its special-ability to
> directly serialize JSON data-structures (an underrated, and very useful
> web-integration feature), while most of its competitors have to rely on
> clumsy, hard-to-serialize classes.
>
> there is no foreseeable future where javascript will be a better tool than
> java/c++/python/etc. for non web-related projects.  there is
> no foreseeable future where employers would hire nodejs-developers to work
> on non web-related projects.  so why does tc39 insist on pushing
> distracting language-features (clumsy java-like classes,
> non-integration-friendly meta-programming, static module-loading, etc.) for
> an unrealistic future-scenario that’s not going to happen?
>
> kai zhu
> kaizhu...@gmail.com
>
> On 24 Jul 2018, at 5:56 PM, T.J. Crowder 
> wrote:
>
> On Tue, Jul 24, 2018 at 11:27 AM, kai zhu  wrote:
>
> tldr - tc39 should focus more on JSON-friendly javascript-language-features
> instead of wasting-time on hard-to-serialize classes/meta-programming.
>
>
> This is a false dichotomy (the fallacy of the either/or choice). I'd
> agree we're approaching, or at, the need for the next thing after
> JSON, and that some focus on that would be a good thing. That doesn't
> mean stopping work on other good things. Perhaps you could take the
> lead on addressing the issues you run into. I'm sure constructive
> input would be welcomed.
>
> my problem with tc39, is that they “claim” javascript is a general-purpose
> language (and try to design it as such), when industry-wise, its really
> not.
>
>
> Yes, it is. Just because you don't see it that way doesn't mean others
> don't. And others have been telling you they see it differently
> repeatedly over a long period of time on this list.
>
> if tc39 is sincerely
> interested in keeping javascript a dominant/relevant language in industry,
> they should focus on *practical* (vs *academic*) features
>
>
> `class` notation is practical (simplifying a common pattern and making
> it less error-prone). (I know you don't use that pattern. That's fine.
> But lots of people do, so it's practical for them whether you like the
> pattern or not.) Promises are practical (simplifying and standardizing
> callbacks, making them composable; again making them less
> error-prone). `async`/`await` is HUGELY practical, massively
> simplifying writing asynchronous code. Arrow functions, rest and
> spread, default parameter values -- all practical. (NOT trying to put
> words in your mouth, but if you were going to reply "Yes, but those
> problems could already be solved in others ways.", then: Sure, and we
> could all write assembly code, too. But it's *useful* to address these
> in the language.)
>
> All of them are useful beyond the web. All are also useful in web
> programming.
>
> I have no problem with skepticism of specific proposals. What I would
> find useful, though, would be a focus on the proposal's merits, rather
> than constant re-raising of this claim that JavaScript is a web-only
> language. You've made that claim, ad nauseum. My view is that it's
> been rejected by the list membership and by TC39, but whether that's
> true or I'm mistaken, please stop spamming the list with it. We all
> know how you feel about it.
>
> But again: I'm sure constructive, research-based input on how to deal
> with JSON issues related to (for instance) BigInt would be welcome in
> that BigInt thread and, ideally, eventually a proposal. There's no
> need for some big conceptual argument over the course of the language
> -- that *is* a waste of time.
>
> -- T.J. Crowder
>
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread Michael Theriot
What can classes do that ES6 can't?

On Tuesday, July 24, 2018, Andrea Giammarchi 
wrote:

> > Proxy was used to create a membrane between the public and private
> storage, and I can't prevent that proxy from being passed to external
> functions
>
> this already underlines what I mean: classes are not just syntactic sugar
> because you cannot replicate what they do, not even using ES6.
>
> having privates / proxies maybe exposed is not how I'd personally code.
>
>
>
> On Tue, Jul 24, 2018 at 5:15 PM Ranando King  wrote:
>
>> > Private fields also won't work as expected...
>>
>> Can you clarify what you're referring to? I've created a library that
>> essentially implements the functional parts of what I intend with this
>> proposal. Of course the syntax isn't the same, and Proxy was used to create
>> a membrane between the public and private storage, and I can't prevent that
>> proxy from being passed to external functions, but those are ES-specific
>> implementation details and not how it would be implemented in the engine.
>>
>> >  ... the mandatory super call in constructor is also different from
>> ES5.
>>
>> You shouldn't really try to compare ES5 and ES6. My statement that
>> "`class` is syntactic sugar" refers to the fact that anything you can do
>> with `class` in ES6 can also be done without `class` in ES6.
>>
>> > P.S. Babel mistakenly sold classes as "just sugar" and never worked
>> properly with Custom Elements and builtins extend until version 7 which is
>> still not perfect but at least it doesn't throw errors for no reason.
>>
>> Just because `class` is essentially syntactic sugar doesn't mean that the
>> desugaring is backwards compatible with older versions of the language. I
>> do not wish to imply that. Nor do I see the need to make such a statement
>> true. Such an attempt to enforce backwards compatibility to that degree
>> would prove excessively burdensome on the process of improving and adding
>> features to the language.
>>
>> On Tue, Jul 24, 2018 at 9:41 AM Andrea Giammarchi <
>> andrea.giammar...@gmail.com> wrote:
>>
>>> Private fields also won't work as expected and the mandatory super call
>>> in constructor is also different from ES5. Let's add species and special
>>> class related Symbol so that it makes no sense to define classes "just
>>> sugar" + there's no point in avoiding classes at all costs when any of
>>> these features is needed.
>>>
>>> Regards
>>>
>>> P.S. Babel mistakenly sold classes as "just sugar" and never worked
>>> properly with Custom Elements and builtins extend until version 7 which is
>>> still not perfect but at least it doesn't throw errors for no reason
>>>
>>>
>>> On Tue, Jul 24, 2018 at 4:15 PM Ranando King  wrote:
>>>
>>>> @ljharb: It seems you now understand what I was trying to say. Sadly,
>>>> I'm not always the most eloquent.
>>>>
>>>> >  As you've all pointed out, it's not "just sugar" in the sense that
>>>> you couldn't do it in ES5; it's more that parallel syntax and API were
>>>> created for the new functionality in ES6.
>>>>
>>>> The intent of my proposal is to provide both member fields and
>>>> privilege levels to the `class` keyword, and the equivalent for object
>>>> literals in a way that meets with both an intuitive declaration style, and
>>>> a reasonable access notation that breaks as little as few as possible of
>>>> the developers expectations of what can and can't be done.
>>>>
>>>> On Tue, Jul 24, 2018 at 3:18 AM Jordan Harband 
>>>> wrote:
>>>>
>>>>> As you've all pointed out, it's not "just sugar" in the sense that you
>>>>> couldn't do it in ES5; it's more that parallel syntax and API were created
>>>>> for the new functionality in ES6. Thanks for providing clear code examples
>>>>> of how one might extend builtins without `class`.
>>>>>
>>>>> @kai: yes, extending builtins makes sense, in that it's an important
>>>>> part of ES6. Invoking "the web" doesn't negate *any* of the features of 
>>>>> the
>>>>> language, new or old. Separately, not every web use involves any JSON
>>>>> serialization in either direction.
>>>>>
>>>>> On Tue, Jul 24, 2018 at 12:15 AM, T.J. Crowder <
>>>>> tj.crow...@farsightso

Re: javascript vision thing

2018-07-24 Thread Michael Theriot
Native JSON streaming would be nice in my opinion.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: proposal: Object Members

2018-07-24 Thread Michael Theriot
>
> Extend builtins, in particular - ie, `super()` allows your subclass to
> obtain internal slots it can't otherwise get.
>
> Even if `class` were just sugar, I don't think I see the argument that
> that's a *good* thing to preserve.
>

`Reflect.construct` allows subclasses to obtain internal slots without
`super()` / class syntax.

```js
const SubDate = function (...args) {
  const instance = Reflect.construct(Date, args, SubDate);
  return instance;
};

Object.setPrototypeOf(SubDate.prototype, Date.prototype);

const sub = new SubDate();
sub.getDate(); // has internal slots, does not throw
sub instanceof SubDate; // true
sub instanceof Date; // true
```

This is the first I have heard `class` is anything but sugar.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Promise capability support

2018-07-20 Thread Michael Theriot
So I run into this issue when waiting on multiple events I don't initiate.
What I do is create a subclass of promise that exposes these calls.

Not saying that's the ideal way to do it, but solvable in userland and
without modifying the base class.

On Thursday, July 19, 2018, 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


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

2018-07-18 Thread Michael Theriot
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.

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


Small Proposal "!in"

2018-07-18 Thread Michael Theriot
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.

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

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


Re: ECMA site down

2018-04-24 Thread Michael Theriot
It's in French now... 稜

> On Apr 24, 2018, at 10:16 AM, T.J. Crowder  
> wrote:
> 
> For any ECMA members on the list; http://ecma-international.org appears to be 
> down at present. It shows a message saying:
> 
> > Account Suspended
> >
> > This Account has been suspended.
> >
> > Contact your hosting provider for more information.
> 
> Reasonably certain that it's not talking about *my* account. :-) (Not least 
> because I tried from three completely separate IPs on different networks, in 
> two separate countries, in one case using `wget`, not a browser.)
> 
> -- 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: Proposal: allow primitives to be explicitly returned from constructors

2018-04-20 Thread Michael Theriot
I don't understand the use case. If anything I would like it if returning
an object that fails `new Class instanceof Class` to also fail, not permit
even more oddities.

On Thu, Apr 19, 2018 at 6:49 PM, Isiah Meadows 
wrote:

> Here's my proposal:
>
> In constructors, currently, non-objects are replaced with `this`.
> Here's what I think it should be replaced with:
>
> 1. When calling the constructor, if `undefined` is returned and
> `new.target` is not `undefined`, return `this` instead. This is for
> compatibility and ease of implementation.
> 1. When calling the constructor, if anything else is returned, return
> that value in raw form.
>
> I know this is very *likely* very breaking, but I wonder if it would
> be possible.
>
> In case you're curious what this would change in the spec, it would
> change [section 9.2.2][1], step 13.a-13.c to this:
>
> a. If result.[[Value]] is not `undefined`, return
> NormalCompletion(`result.[[Value]]`).
> b. If kind is `"base"`, return NormalCompletion(thisArgument).
>
> [1]: https://tc39.github.io/ecma262/#sec-ecmascript-
> function-objects-construct-argumentslist-newtarget
>
> -
>
> Isiah Meadows
> m...@isiahmeadows.com
>
> Looking for web consulting? Or a new website?
> Send me an email and we can get started.
> 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


Re: EcmaScript Proposal – Private methods and fields proposals.

2018-04-17 Thread Michael Theriot
There's no confidence anything you run on someone else's machine really is 
"private" in any language (especially with reflection). Nevertheless private 
members still exist and continue to be used.

> On Apr 17, 2018, at 6:34 AM, kai zhu  wrote:
> 
> can you give actual code-examples of real-world things in web-projects
> that are worth the effort and cost to **proactively** hide from
> web-developers?  i suspect for most, just following python
> design-pattern of prefixing them with '_' or '$' is good enough.
> 
> also in a webpage-context, how confident are you that private
> methods/fields really are "private" and safe from naughty-developers?
> would you trust private fields/methods enough to allow untrusted code
> to run alongside your credit-card transaction webpage?  for example,
> here's a live web-demo of a side-channel attack to indirectly
> modify/read private fields (via jquery from untrusted cdn) [1], with
> screenshots and full source-code here [2].
> 
> its not too difficult to craft these side-channel exploits when a
> naughty-developer has full-access to your frontend source-code. how
> many companies/organizations in the world do you think have the
> resources to audit/harden their frontend-code to ensure private
> methods/fields really are private and cannot be tinkered with through
> various side-channel exploits (hijacking dom-inputs, XMLHttpRequest,
> LocalStorage, IndexedDb, Array-accessors,
> dependent-subclasses-you-forgot-to-encapsulate, etc)?
> 
> [1]
> "live web-demo"
> https://kaizhu256.github.io/tc39-private-field-side-channel-attack-example/
> 
> [2]
> "screenshot and full source-code of demo-exploit"
> https://github.com/tc39/proposal-class-fields/issues/93#issuecomment-380073112
> 
> 
> 
> ```javascript
> /*
> * jquery.from.untrusted.cdn.js
> *
> * this script will indirectly modify/read private-fields by hijacking
> dom-inputs and XMLHttpRequest.
> * it is custom-crafted for a given webpage's freely available
> frontend source-code
> *
> * live web-demo of it in action at:
> * https://kaizhu256.github.io/tc39-private-field-side-channel-attack-example/
> */
> /*jslint
>bitwise: true,
>browser: true,
>maxerr: 4,
>maxlen: 100,
>node: true,
>nomen: true,
>regexp: true,
>stupid: true
> */
> (function () {
>'use strict';
>var XMLHttpRequestPrototypeSend, consoleLog;
>consoleLog = console.log;
>console.log = function () {
>document.querySelector('#textareaStdout').value +=
> Array.from(arguments).join(' ') +
>'\n';
>consoleLog.apply(console, arguments);
>};
>// side-channel attack to modify private-fields in hijacked dom-inputs
>['inputPassword', 'inputUsername'].forEach(function (element) {
>/*
> * this function will hide the original dom-inputs from the user,
> * and replace them with hijacked ones, that can arbitrarily modify data
> */
>var hijackElement;
>element = document.querySelector('#' + element);
>element.style.display = 'none';
>hijackElement = document.createElement('input');
>element.parentNode.insertBefore(hijackElement, element);
>hijackElement.id = element.id + '2';
>hijackElement.type = element.type;
>hijackElement.value = element.value;
>hijackElement.addEventListener('change', function () {
>// arbitrarily modify data and pass it back to original dom-inputs
>element.value = hijackElement.value + ' modified!';
>});
>element.value = element.value + ' modified!';
>});
>document.querySelector('#inputSubmit').addEventListener('click',
> function () {
>console.log('hijacked dom-input to modify field
> loginInstance.privateUsername=' +
>JSON.stringify(document.querySelector('#inputUsername').value));
>console.log('hijacked dom-input to modify field
> loginInstance.privatePassword=' +
>JSON.stringify(document.querySelector('#inputPassword').value)
> + '\n');
>});
>// side-channel attack to read private-fields from hijacked XMLHttpRequest
>XMLHttpRequestPrototypeSend = XMLHttpRequest.prototype.send;
>XMLHttpRequest.prototype.send = function (data) {
>/*
> * this function will hijack XMLHttpRequest.prototype.send to
> indirectly read private-fields
> */
>try {
>data = JSON.parse(data);
>console.log('hijacked XMLHttpRequest.prototype.send to
> read field ' +
>'loginInstance.privateUsername=' +
> JSON.stringify(data.username));
>console.log('hijacked XMLHttpRequest.prototype.send to
> read field ' +
>'loginInstance.privatePassword=' +
> JSON.stringify(data.password) + '\n');
>} catch (ignore) {
>}
>XMLHttpRequestPrototypeSend.apply(this, arguments);
>};
>console.log('loaded script  src="jquery.from.untrusted.cdn.js">');
> }());
> ```
> 
> 
>> On 4/17/18, 

Re: [strawman] Symbol.thenable proposal

2018-04-14 Thread Michael Theriot
A hypothetical proposal addressing that would intersect with this.

On Sat, Apr 14, 2018 at 2:01 PM, <m...@gus.host> wrote:

> I don't understand why you would expect that, can you explain a bit more?
>
> -Gus
>
> On 14 Apr 2018 10:53, Michael Theriot <michael.lee.ther...@gmail.com>
> wrote:
>
> Currently 'then' is effectively a reserved key and I'd expect any
> extension that allows the language to ignore it likewise include a means of
> changing the key entirely.
>
> On Apr 12, 2018, at 9:33 PM, Gus Caplan <m...@gus.host> wrote:
>
> Hello all,
>
> In an effort to curtail the interesting behavior of Promise.resolve
> (especially
> with regard to dynamic import), I have created a proposal for a well-known
> symbol which will allow an object to not be treated as a "thenable."
>
> I am privy to the current protocol proposal which might be a better fit for
> this, but due to dynamic import already being stage 3, I don't feel we
> should
> wait for it to come to fruition.
>
> Comments and suggestions are of course quite welcome at the repo [1].
>
> Thanks,
> -Gus
>
> [1]: https://github.com/devsnek/proposal-symbol-thenable
>
> ___
> 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: [strawman] Symbol.thenable proposal

2018-04-14 Thread Michael Theriot
Currently 'then' is effectively a reserved key and I'd expect any extension
that allows the language to ignore it likewise include a means of changing
the key entirely.

On Apr 12, 2018, at 9:33 PM, Gus Caplan  wrote:

Hello all,

In an effort to curtail the interesting behavior of Promise.resolve
(especially
with regard to dynamic import), I have created a proposal for a well-known
symbol which will allow an object to not be treated as a "thenable."

I am privy to the current protocol proposal which might be a better fit for
this, but due to dynamic import already being stage 3, I don't feel we
should
wait for it to come to fruition.

Comments and suggestions are of course quite welcome at the repo [1].

Thanks,
-Gus

[1]: https://github.com/devsnek/proposal-symbol-thenable

___
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: EcmaScript Proposal – Private methods and fields proposals.

2018-04-13 Thread Michael Theriot
I'd imagine that would fail the same way proxies fail on typed arrays.

> On Apr 13, 2018, at 6:26 PM, Waldemar Horwat  wrote:
> 
>> On 04/13/2018 01:38 AM, Sultan wrote:
>> The proposal is an explainer with regards to an alternative sigil-less 
>> syntax to back private fields/methods.
>>> What does private(this)[property] do?
>> "private(this)[property]" and alternatively "private[property]" or 
>> "private.property" all invoke access of a private "property" on the "this" 
>> instance of the class, symmetrical to thesyntax/function nature of both the 
>> "super" and"import" keywords.
>>> How do private fields come into existence?
>> Unless i've misunderstood what is meant by "come into existence" the 
>> proposals makes use of the reserved "private" keyword to define private 
>> fields i.e "private id = 1".
> 
> I was asking about what creates those fields.
> 
>>> What's private about private fields?
>> Outside of a private fields provider class, private fields/methods would not 
>> be accessible.
>>> How do you prevent them from being forged or stuck onto unrelated objects?
>> What do you mean by this?
> 
> Writing your private field to an object that's not an instance of your class.
> 
> class A {
>  private id = ...;
>  private foo = ...;
>  write(value) {
>private(this)["id"] = value;
>private(this)["foo"] = ... my private secret that anyone outside the class 
> must not learn ...;
>  }
> }
> 
> and then invoking the above write method with a this value that's not an 
> instance of A, such as a proxy.
> 
>Waldemar
> ___
> 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: EcmaScript Proposal – Private methods and fields proposals.

2018-04-13 Thread Michael Theriot
This matches my initial perceptions of private properties in JS; exactly 
identical to regular properties but private, which I have not seen preserved in 
the other proposals.

> On Apr 13, 2018, at 4:38 AM, Sultan  wrote:
> 
> The proposal is an explainer with regards to an alternative sigil-less syntax 
> to back private fields/methods.
> 
> >What does private(this)[property] do?
> 
> "private(this)[property]" and alternatively "private[property]" or 
> "private.property" all invoke access of a private "property" on the "this" 
> instance of the class, symmetrical to the syntax/function nature of both the 
> "super" and "import" keywords.
> 
> >How do private fields come into existence?
> 
> Unless i've misunderstood what is meant by "come into existence" the 
> proposals makes use of the reserved "private" keyword to define private 
> fields i.e "private id = 1".
> 
> >What's private about private fields?
> 
> Outside of a private fields provider class, private fields/methods would not 
> be accessible.
> 
> >How do you prevent them from being forged or stuck onto unrelated objects?
> 
> What do you mean by this?
> 
>> On Fri, Apr 13, 2018 at 1:16 AM, Waldemar Horwat  wrote:
>> I read that proposal but don't understand what the proposal actually is.  At 
>> this point it's a bit of syntax with no semantics behind it.  What does 
>> private(this)[property] do?  How do private fields come into existence?  How 
>> do you prevent them from being forged or stuck onto unrelated objects?  
>> What's private about private fields?
>> 
>> Waldemar
> 
> ___
> 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: Proposal: if variable initialization

2018-04-07 Thread Michael Theriot
Same sentiments, and I am pleased with how golang handles this common
desire. Another idea I had is a `for` statement with only one expression of
declarations, or even a new use for the dead `with` statement (conveniently
named).

On Tue, Mar 20, 2018 at 3:57 PM, Rodrigo  wrote:

> Proposal: inline let/const statements to declare and initialize
> variables within if statements, so that temporary variables exist only
> within the if/else block scope.
>
> Reason: limits variable scope to the block where really needed, in
> similar fashion to variables defined in for(;;) statements. This
> improves readability while reducing unnecessary variables roaming
> outside their needed block.
>
> The syntax would be very similar to the for(;;) assignment/test pair:
>
> if (let x = 100; x > 50) {
> console.log(x); // 100
> }
> console.log(x); // ReferenceError
>
> // same for const
> if( const x = foo(); typeof x === 'object' ) {
> //...
> }
>
> // the variable is available within any else block
> // after its declaration
> if (let x = foo(); x < 50) {
> console.log(x);  // y is not available here
> } else if (let y = bar(); y > 0) {
> console.log(x, y);
> } else {
> console.log(x, y);
> }
>
> Right now there isn't a way to limit a variable to the if block:
>
> let x = 100;
> if (x > 50) {
> console.log(x);
> }
> // x is in scope, but may not be needed beyond the if statement
> console.log(x);
>
> // or a non-strict assignment, which also "leaks" scope
> if( (x = 100) > 50 ) {
> // ...
> }
>
> There are many "workarounds" available, here's a few:
>
> // workaround 1: can be remedied with a scope block
> // but it's asymmetrical and non-idiomatic
> {
> let x = 100;
> if (x > 50) {
> console.log(x);
> }
> }
>
> // workaround 2: with a for statement
> // but this is non-idiomatic, hard to read and error-prone
> for (let x = 100; x > 50;) {
> console.log(x);
> break;
> }
>
> If-initialization is available in many languages (Go, Perl and Ruby
> come to mind) and are considered best practice in each one of them:
>
> // Golang - x is defined, assigned and conditionally tested
> if x := 100; x > 50 {
> // x is in scope here
> } else {
> // and in here
> }
> // x is not available here
>
> ## Perl
> if( my $x = 100 ) {
> print $x;
> }
> print $x; # an error
>
> if ( ( my $x = myfoo() ) > 50 ) {  # also ok in Perl
> print $x;
> }
>
> ## Ruby
> if ( x = 100 )  # parens required per style guide
> puts(x)
> end
> puts(x) # unfortunately Ruby does not limit scope to if, so x "leaks"
>
> I think this would be a great and important addition to the language.
>
> -Rodrigo
>
> PS: Just for the sake of comparison, Perl-style if-assignments could also
> be an
> option, albeit a very bad one IMO:
>
> if( ( let x = 100 ) > 50 ) {
> }
>
> A Perl-style, value-returning let/const has readability issues, opens
> quite a few fronts and sort of implies that let/const can return
> values anywhere in the code outside if/else. On the other hand it
> would fit with the currently if assignment if( x = y ). Definitely not
> recommended.
> ___
> 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: Expanding Object Shorthand

2018-03-17 Thread Michael Theriot
Not up to speed with any pitfalls already discussed but for what it's worth I 
tried this at least a few times when destructuring landed and was disappointed 
it didn't work.

> On Mar 16, 2018, at 4:30 PM, Sebastian Malton  wrote:
> 
> Hello currently the following is a possible way to define an object. 
> 
> ```
> var d = { a, b, c };
> ```
> 
> But this only works if the fields are already variables.
> 
> So if you wanted to select some fields from an object within you have to use 
> temp variables, reference the field by name but without the temporary 
> variables, or use some immediately called functions which is messy.
> 
> So I propose the following syntax:
> 
> ```
> var d = {
> a,
> b,
> { c }: e
> };
> ```
> 
> Here d will have the fields [a, b, c] and the values are the variable a, 
> variable b, and value e.c.
> 
> Other things like name reassignment would work too.
> 
> Sebastian Malton
> 
> ___
> 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: @strict class decorator

2017-08-08 Thread Michael Theriot
Subclassing can work too.

```js
class A {
  constructor() {
this.bar = 1;
this.baz = 2;
if (new.target === A) Object.preventExtensions(this);
  }
}

class B extends A {
  constructor() {
super();
this.bat = 3;
if (new.target === B) Object.preventExtensions(this);
  }
}
```

No decorator needed to do this today.

I am not keeping up with decorators but @sealed implies to me that the
class cannot be subclassed? At least that's what it means in C# and would
confuse me if it simply meant Object.seal(this)...
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Quantum / Multicore Constructs

2016-12-10 Thread Michael Theriot
(FYI this was tagged spam by Gmail for failing email auth)

You can't do that, but this will probably achieve what you wanted.

`var obj = Object.assign({}, new Array(4).fill(1));`

I think a few of these already exist under a different name.

Object.prototype.parent -> Object.prototype.constructor
Object.prototype.toArray -> [...Object]
Array.prototype.iterate -> Array.prototype[Symbol.iterator]
Entity() -> Object.create(null)

On Wed, Dec 7, 2016 at 9:08 AM, Michelle Antonello <
foldit_resea...@yahoo.com> wrote:

> How well does JavaScript model constructs in Graph theory ?
>
> obj = {
> [0,1,2,3]:1
> }
>
> Also, I would like
>
> Object.prototype.parent
> Object.prototype.forEachOwnProperty
> Object.prototype.trace
> Object.prototype.traceModules (emits source)
> Object.prototype.toArray
> Array.prototype.iterate = { (iterator function_) }
> Entity() (A lightweight Object superclass w/o an *.prototyp property)
> Even more powerful regular expressions !!!
>
> I monitor progress in mathematics and physics (eg. Black holes accurately
> modeled by tensors == Array.prototype construct; Discovery of Higgs
> particle as sole mass carrier == Object baseclass along with its extensible
> prototypes)
>
> Michelle Antonello
> Abdul S.
> ___
> 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: Object.equals() and Object.clone()

2016-11-14 Thread Michael Theriot
I think you'd definitely need to call the constructor for classes because
of scoped variables (e.g. scoped weakmap for private properties).

I would like a way to compare simple objects like identical arrays though.

On Mon, Nov 14, 2016 at 7:58 PM, Frankie Bagnardi 
wrote:

> It's pretty hard to decide how these behave, specifically with custom
> classes. Focusing on Object.clone...
>
> - with classes do you call the constructor, and with what arguments?
> - HTMLElement and sub classes can't be constructed directly, what happens
> with them?
> - do you copy internal properties? this would make it hard to polyfill
> - how does it behave with getters and setters?
> - with regular expressions do you copy the lastIndex?
>
> Most of those apply to Object.equals also.
>
>
>
> On Mon, Nov 14, 2016 at 6:25 PM, Kevin Barabash 
> wrote:
>
>> It would be nice if deep equality checking and deep cloning of objects
>> was included in the standard library.  Has there been any proposals around
>> including these in the past?
>>
>> – Kevin
>>
>>
>> ___
>> 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: Array tail destructuring

2016-10-01 Thread Michael Theriot
I think this is because there's no universal way of determining when an
iterator ends. The only way this could work for all iterators would require
popping values off of `a` after they've been added.

On Sat, Oct 1, 2016 at 6:17 AM, Cyril Auburtin 
wrote:

> It was possibly already discussed, but why isn't:
> ```
> var [...a, last] = [1,2,3];
> ```
> supported?
>
> I don't see the problem, as long as there's one ... only
>
> ___
> 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: Thought about const

2016-08-28 Thread Michael Theriot
I also thought cst would have been good. My petty issue is that when
declaring variables all of my constants have a different indentation.

I define all of my arrow functions with const so I use it fairly often.

On Sun, Aug 28, 2016 at 6:59 AM, Cyril Auburtin 
wrote:

> After a year of using `const`, I got used to it, but even with that I
> often feel losing time using it, with those 2 additional chars. It's really
> unfortunate because it's by far the most frequently used for variables
> assignments.
>
> It's also really close to *cons*ole(.log,...), annoying with
> auto-completers
>
> Thing are probably frozen at this time, but `cst`, `ref`, `val` would have
> been interesting
>
> ___
> 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: Code smell? Iterator prototype has iterator method that returns "this"

2016-07-27 Thread Michael Theriot
At least in Chrome, new weirdFunction() !== iter nor does it throw a
TypeError... but maybe that's a bug...

On Wed, Jul 27, 2016 at 10:12 AM, Allen Wirfs-Brock 
wrote:

>
> On Jul 26, 2016, at 11:52 PM, Claude Pache  wrote:
>
>
> var weirdInstance = new weirdFunction(); // what is this??
> ```
>
>
> My intuition says: "TypeError: weirdFunction is not a constructor”.
>
>
> exactly, because weirdFunction is actually
> https://tc39.github.io/ecma262/#sec-%iteratorprototype%-@@iterator which
> is a built-in function that is not identified as a constructor.
>
> https://tc39.github.io/ecma262/#sec-ecmascript-standard-built-in-objects
>  says:
>  "Built-in function objects that are not identified [in this
> specification] as constructors do not implement the [[Construct]] internal
> method unless otherwise specified in the description of a particular
> function.”
>
> Step 7 of https://tc39.github.io/ecma262/#sec-evaluatenew says:
> If IsConstructor(*constructor*) is *false*, throw a TypeError exception.
>
>
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Code smell? Iterator prototype has iterator method that returns "this"

2016-07-26 Thread Michael Theriot
There are many things I still don't understand about iterators...

```js
var iter = [].values();
iter[Symbol.iterator]() === iter;

var weirdFunction = iter[Symbol.iterator];
weirdFunction.call(iter) === iter;

var weirdInstance = new weirdFunction(); // what is this??
```


On Mon, Jul 25, 2016 at 10:19 AM, John Lenz  wrote:

> This seems ripe for misuse:  you don't want two "owners" for the same
> iterator calling "next" and normally, without the Iterator interface
> implementation, you would expect "iterator()" to always return an instance
> of the iterator that the caller "owned".
>
> Can anyone provide any historical context on why this method was added to
> the "iterator"?
>
> ___
> 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: operator overloading proposal

2016-06-29 Thread Michael Theriot
What about extending proxies to have operator traps?

On Sun, Jun 5, 2016 at 8:22 AM, Benjamin Gruenbaum 
wrote:

> I see some discussion is happening - that's good.
>
> As I don't want to see the tremendous amount of work people put into value
> types and operator overloading go to waste - let's bring Brendan and
> Christian into this discussion and start with a link to Brendan's 2013
> slides:
>
> http://www.slideshare.net/BrendanEich/value-objects
>
> Let's consider value semantics for this.
>
> > I've been working on implementing operator overloading and would like to
> submit a proposal.
>
> > I think operator overloading would be a useful addition to the language.
> In particular I think it would be useful for defining operations on common
> mathematical object types such as complex numbers, vectors, matrices, and
> sets.
>
> > I've create a working prototype that consists of:
>
> > babel plugin that rewrites operators as function calls
> > a polyfill which defines these functions and which call the correct
> argument-specific function based on the arguments' prototypes
> > Function.defineOperator which can be used to define which function an
> operator should use for the specified types
> > "use overloading" directive which allows users to opt-in
> > More details can be found at kevinbarabash/operator-overloading. The
> babel plugin can be found at
> kevinbarabash/babel-plugin-operator-overloading. I also have a demo project
> at kevinbarabash/operator-overloading-demo.
>
> The design was inspired by some of the slides from
> www.slideshare.net/BrendanEich/js-resp.
>
>
> ___
> 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: operator overloading proposal

2016-05-15 Thread Michael Theriot
What if you used a target parameter to indicate assignment?

```js
operator +(a, b, target = new obj()) {
  target.val = a.val + b.val;
  return target;
}

// or... no arrow functions...

operator +(other, target = new obj()) {
  target.val = this.val + other.val;
  return target;
}

// or... just a boolean

operator +(other, assign) {
  let target = assign ? this : new obj();
  target.val = this.val + other.val;
  return target;
}
```

And throw a TypeError if an assignment does not return the same object.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: extending an ES6 class using ES5 syntax?

2016-05-15 Thread Michael Theriot
Is there a reason Reflect.setPrototypeOf(B.prototype, A.prototype) can't be 
optimized on class declaration the same way B.prototype = 
Object.create(A.prototype) is?
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Adding a non-class-syntax method for subclassing native objects

2016-05-03 Thread Michael Theriot
I believe you can do this with `Reflect.construct`.

```js
function SubArray(arg1) {
  return Reflect.construct(Array, arguments, SubArray);
}
SubArray.prototype = Object.create(Array.prototype);
Reflect.setPrototypeOf(SubArray, Array);

var arr = new SubArray();
arr instanceof SubArray; // true
arr instanceof Array; // true
arr[5] = 0; // should exotically update length property
arr.length === 6; // true
```
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Pseudo headless arrows

2016-04-21 Thread Michael Theriot
Three equals used outside of strict equality might take some getting used
to `var fn ===> x`

On Thu, Apr 21, 2016 at 1:48 PM, Peter van der Zee  wrote:

> 
>
> There are two ways of writing argument-less arrows;
>
> () => x;
> _ => x;
>
> (Where `_` can be any identifier, of course.) I understand why we
> can't drop the head entirely so if we're forced to type anything at
> all, anyways, why not at least make it simpler by pressing two
> different keys instead of three/four:
>
> ==> x;
>
> I don't believe this leads to syntactical problems anywhere, not even
> with arrow functions themselves and it's future proof for at least the
> cases I'm aware of.
>
> It's a minor addition but I think it's much nicer than either of the
> two alternatives we currently have, which lead to a lot of
> inconsistencies (it's spaces and tabs all over again).
>
> Semantics are the same otherwise as `() => x` would be.
>
> - peter
> ___
> 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: JavaScript Language feature Idea

2016-04-19 Thread Michael Theriot
>
> And Set by definition is an unordered collection, so there is no "last"
> element.


Sets in ES6 are iterated in insertion order.

I don't think a .get or .set needs to be made for Array. Why would you use
`arr.set(1, 4)` over `arr[1] = 4`, and why should there be more ways of
doing the same thing? It would only ever be used for negative indices, and
Reflect.get/Reflect.set already exists without that behavior.

The original question was to use negative indices, which you can do with
proxies. If a method should be added I think .last is the safest and would
expect any implementation of it to have the same behavior.

An `array[Symbol.last]` getter/setter would also be safe. You can even add
it yourself without collision.

```js
var last = Symbol();

Reflect.defineProperty(Array.prototype, last, {
  get: function () {
return Reflect.get(this, this.length - 1);
  },
  set: function (value) {
return Reflect.set(this, this.length - 1, value);
  }
});

var arr = [1,2,3];
arr[last] = 0;
console.log(arr); // 1,2,0
```

On Tue, Apr 19, 2016 at 9:37 AM, Michał Wadas  wrote:

>
> 2016-04-19 10:40 GMT+02:00 Jordan Harband :
>
>> (note that `Set#get(-1)` does not retrieve the last item in the set, for
>> example).
>>
>
>
> Because Set.prototype.get doesn't even exist. And Set by definition is an
> unordered collection, so there is no "last" element.
>
> I think Array.prototype.get and Array.prototype.set are the way to go - it
> should not break backward compatibility. And it's consistent with
> Array.prototype.slice behaviour.
>
>
> BTW, this was discussed 3 years ago:
> https://esdiscuss.org/topic/array-prototype-last
>
>
>
> ___
> 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: New Assignment Operators (Not bit-wise OR)

2016-04-18 Thread Michael Theriot
What scenarios do you need to declare a new variable equal to its current
declaration or a default value?

On Sun, Apr 17, 2016 at 8:21 AM, even stensberg 
wrote:

> I've seen a lot of code using an extra type to have as a fallback. This to
> me seems like not a very good way of putting use of the logical OR. Here's
> an example:
>
> `var itemList = itemList || 'something went extremely wrong'`
>
>
> This is a really hacky way of doing things. I don't think you should
> assign your variable to a default by doing this.
>
>
> Been back and forth by this "issue" with some of the ReactJS members at
> GitHub, and while saying this is a "stylus" thing, I disagree. It is more
> about not reiterating your code.
>
> Options could be:
>
> -tenaries - long & !clean codelines
> -default params (ES) , though it won't be a general use case
>
> There is already a lot of assignment, string and so on operators, but I
> don't really seem any of them touch this, except maybe the bit-wise OR
> assignment Operator. To read more about that, check these two links out:
>
> https://msdn.microsoft.com/en-us/library/81bads72(v=vs.94).aspx
> http://web.eecs.umich.edu/~bartlett/jsops.html
> http://stackoverflow.com/a/14871137/5893008
>
> And that is really not the use case here. We don't want a bit-wise, we
> want a logical OR.
>
> So here is what I come up with. It's not rocket science but ... nah, it's
> pretty straight forward..
>
> `var listItem || = 'I love open source!'`
>
>
> For me, this is one thousand times more clean and it makes sense.
> JavaScript teaches us and wants us to use `+ =`,` - =` and any other type
> of "abbreviation" , so this makes perfectly sense for me. Either I'm crazy,
> but it seems like this should have been implemented a long time ago.
> ( Perhaps I'm both).
>
> Implementation will be another issue, but let us discuss that too( just
> keep in mind this is conceptional)
>
>
> Without further ado, I leave this up to you to discuss, and hopefully a
> champion to fetch up to the committee.
>
> ___
> 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: JavaScript Language feature Idea

2016-04-18 Thread Michael Theriot
This can be trivially done with proxies. I don't think arrays should have a
special trap dependent on whether or not a symbol is set. If I were to make
a custom array with proxies I would then have to check if someone changed
standard behavior by inserting a symbol, and pass the symbol to the target
just to work properly.

If the `var arr = [1,2,3];` syntax is the real reason to change default
behavior then just use `Array.from` like such `var arr =
InvertedArray.from([1,2,3]);`. See below...

```
var getProp = (target, property) => typeof property !== 'symbol' &&
target.length && property < 0 && property >= -target.length ? +property +
target.length : property;

var handler = {
  get: (target, property, receiver) => Reflect.get(target, getProp(target,
property), receiver),
  set: (target, property, value, receiver) => Reflect.set(target,
getProp(target, property), value, receiver)
};

var InvertedArray = new Proxy(function InvertedArray(arg1) {}, {
  construct: (target, arguments, newTarget) => new
Proxy(Reflect.construct(Array, arguments, InvertedArray), handler)
});

Reflect.setPrototypeOf(InvertedArray, Array);

InvertedArray.prototype = Object.create(Array.prototype);
```

Arrays are effectively regular objects with traps on get/set to update the
length property. I don't think they should have a special new syntax to
access negative indices like `arr[:-1]` since it would logically have to
work on all objects and is dependent on a length property; it's just
syntactic sugar for yet another trap.

On Mon, Apr 18, 2016 at 2:05 PM, kdex  wrote:

> `Symbol.implementation` should be fairly trivial to implement once [Realm](
> https://github.com/caridy/proposal-realms)s are around, without affecting
> global scope.
>
> On Montag, 18. April 2016 18:58:06 CEST Andy Earnshaw wrote:
> > I don't think that would be trivial to implement and there might not be a
> > common enough use case for it.  You might want to look into something
> like
> > http://sweetjs.org if it's the syntactic sugar you're looking for.
> >
> > On Mon, 18 Apr 2016 19:35 /#!/JoePea,  wrote:
> >
> > > > ```js
> > > > Array[Symbol.implementation] = MyArray;
> > > > ```
> > >
> > > > That would mean all other programs executing on the page would be
> forced
> > > to use that Array implementation
> > >
> > > And also with my suggestion that would impact all code too.
> > >
> > > Would it be possible to limit the effect of using certain symbols to a
> > > scope where the symbol is used? For example:
> > >
> > > ```js
> > > function main() {
> > >   Array[Symbol.implementation] = MyArray;
> > >
> > >   let a = [1,2,3] // uses MyArray
> > > }
> > > let a = [1,2,3] // uses Array
> > > main()
> > > ```
> > >
> > > or
> > >
> > > ```js
> > > Array[Symbol.implementation] = MyArray;
> > > function main() {
> > >   let a = [1,2,3] // uses MyArray, from outer scope
> > > }
> > > let a = [1,2,3] // uses MyArray
> > > main()
> > > ```
> > >
> > > Or maybe some other method on a per-scope basis?
> > >
> > > On Mon, Apr 18, 2016 at 11:25 AM, Andy Earnshaw <
> andyearns...@gmail.com>
> > > wrote:
> > > > That would mean all other programs executing on the page would be
> forced
> > > to
> > > > use that Array implementation, imposing potentially critical problems
> > > with,
> > > > for example, performance and expected behavior. It's just not a good
> > > idea.
> > > >
> > > > I missed off esdiscuss when I replied earlier, but I mentioned that
> the
> > > only
> > > > reasonable solution is to introduce new syntax, e.g.
> > > >
> > > > myArray[:-1]
> > > >
> > > > However, it's been said that there needs to be a compelling reason
> to add
> > > > new syntax and I'm not sure this qualifies imo.
> > > >
> > > >
> > > > On Mon, 18 Apr 2016 19:11 kdex,  wrote:
> > > >>
> > > >> Yes, now we're heading in the right direction.
> > > >>
> > > >> The problem with something like `Symbol.propertyAccess` is that this
> > > might
> > > >> lead to a flood of new well-known Symbols.
> > > >> Conceptually, `Symbol.propertyAccess` sounds like it should have
> been a
> > > >> `Proxy` trap, anyway.
> > > >>
> > > >> Here's an more general idea: Why not allow users to set a derived
> class
> > > >> for literals via well-known Symbols?
> > > >> Thus, users could provide custom implementations for `RegExp`,
> `Array`,
> > > >> `Object` (…) literals, as long as the value points to a derived
> class.
> > > >>
> > > >> We could even introduce negative array indices in a way that doesn't
> > > break
> > > >> the web like this:
> > > >>
> > > >> ```js
> > > >> [1, 2, 3][-1]; // undefined
> > > >> Array[Symbol.implementation] = MyArray;
> > > >> [1, 2, 3][-1]; // 3
> > > >> Array[Symbol.implementation] = 3; // TypeError: Array
> implementations
> > > must
> > > >> extend Array (→ Array.isPrototypeOf(Number(3)) is false)
> > > >> ```
> > > >>
> > > >> On Montag, 18. April 2016 10:47:24 CEST /#!/JoePea wrote:
> > > >> > But, can
> > > >> >

Re: Proxy handler.has() does not have a receiver argument?

2016-04-03 Thread Michael Theriot
That is good news then. I think I have the right expectations of proxies
now.

Sharing one handler is easy too. All you need to do is map both the `proxy`
and its `target` to the same data. `receiver` is actually the proxy but the
argument is no longer important here.

```js
var priv = new WeakMap();

var handler = {
  get: (target, property, receiver) => property in priv.get(target) ?
priv.get(target)[property] : target[property],
  set: (target, property, value, receiver) => property in
priv.get(target) ? priv.get(target)[property] = value : target[property] =
value,
  has: (target, property) => property in priv.get(target) || property in
target
};

function A() {
  let proxy = new Proxy(this, handler);
  let store = {secret: 4};
  priv.set(this, store).set(proxy, store);
  return proxy;
}

A.prototype.getSecret = function () {
  return priv.get(this).secret;
};

var a = new A();
a.getSecret(); // 4
a.secret; // 4
a.secret = 5;
a.secret; // 5
a.getSecret(); // 5
'secret' in a; // true
```

(sorry for any dupes, new to mailing lists...)

On Thu, Mar 17, 2016 at 5:46 AM, Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> I feel like it should, or I am misunderstanding something fundamental. I
> made a basic scenario to explain:
>
> ```js
> var arrays = new WeakMap();
>
> function ArrayView(array) {
>   arrays.set(this, array);
>
>   return new Proxy(this, {
> set: (target, property, value) => (arrays.has(this) && property in
> arrays.get(this))  ? arrays.get(this)[property] = value : target[property]
> = value,
> get: (target, property)=> (arrays.has(this) && property in
> arrays.get(this))  ? arrays.get(this)[property] : target[property],
> has: (target, property)=> (arrays.has(this) && property in
> arrays.get(this)) || property in target
>   });
> }
>
> ArrayView.prototype = Object.create(Array.prototype, {
>   arrayLength: {
> get() {
>   return arrays.get(this).length;
> }
>   }
> });
> ```
>
> When `new ArrayView(somearray)` is called the reference to `somearray` is
> stored in the `arrays` weak map and a proxy is returned that allows you to
> manipulate indices on it, or fallback to the object for other properties.
>
> This could be simplified by putting the proxy on the prototype chain to
> reduce overhead and actually return a genuine `ArrayView` object instead:
>
> ```js
> var arrays = new WeakMap();
>
> function ArrayView2(array) {
>   arrays.set(this, array);
> }
>
> var protoLayer = Object.create(Array.prototype, {
>   arrayLength: {
> get() {
>   return arrays.get(this).length;
> }
>   }
> });
>
> ArrayView2.prototype = new Proxy(protoLayer, {
>   set: (target, property, value, receiver) => (arrays.has(receiver) &&
> property in arrays.get(receiver))  ? arrays.get(receiver)[property] = value
> : Reflect.set(target, property, value, receiver),
>   get: (target, property, receiver)=> (arrays.has(receiver) &&
> property in arrays.get(receiver))  ? arrays.get(receiver)[property]
> : Reflect.get(target, property, receiver),
>   has: (target, property)  => (arrays.has(target)   &&
> property in arrays.get(target))   || Reflect.has(target, property)
> });
> ```
>
> Under this setup `target` refers to the protoLayer object which is useless
> here, but we can use the `receiver` argument in its place to access the
> weak map, and replace our set/get operations with Reflect.set/Reflect.get
> calls to the target (protoLayer) using a receiver (the instance) to pass
> the correct `this` value to the `arrayLength` getter and prevent infinite
> recursion.
>
> One problem - handler.has() lacks a receiver argument. So in this scenario
> when using the `in` operator it will always fail on array properties
> because we cannot check the weak map by passing in the instance.
>
> ```js
> var arr = [0, 1];
>
> var a = new ArrayView(arr);
> a.arrayLength; // 2
> 'arrayLength' in a; // true
> '0' in a; // true
> '1' in a; // true
> '2' in a; // false
>
> var b = new ArrayView2(arr);
> b.arrayLength; // 2
> 'arrayLength' in b; // true
> '0' in b; // false
> '1' in b; // false
> '2' in b; // false
> ```
>
> Without a receiver argument on handler.has(), it is practically useless
> for proxies used as a prototype. You can't reference the instance calling
> it and your target is simply the parent prototype.
>
> Is there a reason the handler.has() trap should not obtain the receiver
> when used on the prototype chain? I can understand why Reflect.has()
> wouldn't have a receiver argument (that wouldn't make sense) but this seems
> like a legiti

Proxy handler.has() does not have a receiver argument?

2016-03-19 Thread Michael Theriot
I feel like it should, or I am misunderstanding something fundamental. I
made a basic scenario to explain:

```js
var arrays = new WeakMap();

function ArrayView(array) {
  arrays.set(this, array);

  return new Proxy(this, {
set: (target, property, value) => (arrays.has(this) && property in
arrays.get(this))  ? arrays.get(this)[property] = value : target[property]
= value,
get: (target, property)=> (arrays.has(this) && property in
arrays.get(this))  ? arrays.get(this)[property] : target[property],
has: (target, property)=> (arrays.has(this) && property in
arrays.get(this)) || property in target
  });
}

ArrayView.prototype = Object.create(Array.prototype, {
  arrayLength: {
get() {
  return arrays.get(this).length;
}
  }
});
```

When `new ArrayView(somearray)` is called the reference to `somearray` is
stored in the `arrays` weak map and a proxy is returned that allows you to
manipulate indices on it, or fallback to the object for other properties.

This could be simplified by putting the proxy on the prototype chain to
reduce overhead and actually return a genuine `ArrayView` object instead:

```js
var arrays = new WeakMap();

function ArrayView2(array) {
  arrays.set(this, array);
}

var protoLayer = Object.create(Array.prototype, {
  arrayLength: {
get() {
  return arrays.get(this).length;
}
  }
});

ArrayView2.prototype = new Proxy(protoLayer, {
  set: (target, property, value, receiver) => (arrays.has(receiver) &&
property in arrays.get(receiver))  ? arrays.get(receiver)[property] = value
: Reflect.set(target, property, value, receiver),
  get: (target, property, receiver)=> (arrays.has(receiver) &&
property in arrays.get(receiver))  ? arrays.get(receiver)[property]
: Reflect.get(target, property, receiver),
  has: (target, property)  => (arrays.has(target)   &&
property in arrays.get(target))   || Reflect.has(target, property)
});
```

Under this setup `target` refers to the protoLayer object which is useless
here, but we can use the `receiver` argument in its place to access the
weak map, and replace our set/get operations with Reflect.set/Reflect.get
calls to the target (protoLayer) using a receiver (the instance) to pass
the correct `this` value to the `arrayLength` getter and prevent infinite
recursion.

One problem - handler.has() lacks a receiver argument. So in this scenario
when using the `in` operator it will always fail on array properties
because we cannot check the weak map by passing in the instance.

```js
var arr = [0, 1];

var a = new ArrayView(arr);
a.arrayLength; // 2
'arrayLength' in a; // true
'0' in a; // true
'1' in a; // true
'2' in a; // false

var b = new ArrayView2(arr);
b.arrayLength; // 2
'arrayLength' in b; // true
'0' in b; // false
'1' in b; // false
'2' in b; // false
```

Without a receiver argument on handler.has(), it is practically useless for
proxies used as a prototype. You can't reference the instance calling it
and your target is simply the parent prototype.

Is there a reason the handler.has() trap should not obtain the receiver
when used on the prototype chain? I can understand why Reflect.has()
wouldn't have a receiver argument (that wouldn't make sense) but this seems
like a legitimate use for it. Otherwise I don't see a reason to use the
handler.has() trap at all on prototype proxies except for bizarre behaviors
that have nothing to do with the instance. It will always have the same
behavior across all instances since you can't differentiate them.
___
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss


Re: Class and Property Initialization

2016-03-19 Thread Michael Theriot
Try this... It will only seal if calling new. The subclasses will still
need to seal though.

```js
class Test {
  constructor() {
this.x = 1;
if(new.target === Test) {
  Object.seal(this);
}
  }
}
```

On Fri, Mar 18, 2016 at 9:57 AM, Brian Barnes  wrote:

> Great, glad to hear that's coming!  I think sealing is a fine solution,
> it'll do what I want and doesn't cause fits for the engine makers.
>
> That said, it has one problem -- base classes.  You can't seal them
> because the constructor in the extended class would fail (I tried it) and
> so the base classes would always have to remain  unsealed which means you
> either (1) understand that or (2) always use an extended class if you care
> for level of code safety.
>
> [>] Brian
>
>
> On 3/18/2016 11:50 AM, kdex wrote:
>
>> Brian, Your first example isn't too far from ES2017. Leave away the
>> `let`s and seal it, and you got:
>>
>> ```js
>> "use strict";
>> class Test {
>>  x = 1;
>>  y = 2;
>>  constructor() {
>>  Object.seal(this);
>>  this.z = 3; // TypeError
>>  }
>> }
>> ```
>> You can already use this using transpilers (at least babel supports it).
>>
>> On 18.03.2016 15:39, Brian Barnes wrote:
>>
>>> Ugh, well, I guess I typed a lot of stuff for nothing!  And by the
>>> look of their experiment, what I wanted was actually one of the major
>>> blockers.
>>>
>>> It seems classes will really need a more standard type of syntax (non
>>> static) before you could actually achieve this, and might be a bridge
>>> too far for javascript:
>>>
>>> class test
>>> {
>>> let x=1;
>>> let y=2;
>>> constructor() {}
>>> func() { this.z=2; }// syntax error
>>> }
>>>
>>> Though it could be kind of faked by some kind of reverse hoisting,
>>> i.e., rebuilding the code inside the engine:
>>>
>>> class test
>>> {
>>> constructor()
>>> {
>>> this.x=1;
>>> this.y=2;
>>> // stuff that was in the constructor
>>> Object.seal(this);
>>> }
>>> ...
>>> }
>>>
>>> [>] Brian
>>>
>>> On 3/18/2016 10:04 AM, Sébastien Doeraene wrote:
>>>
 Hi,

 The Strong Mode experiment was canceled:
 https://groups.google.com/forum/#!topic/strengthen-js/ojj3TDxbHpQ

 Cheers,
 Sébastien

 On Fri, Mar 18, 2016 at 3:59 PM, kdex > wrote:

 Already considered and to be implemented via strong mode IIRC.

 On 18.03.2016 14:36, Brian Barnes wrote:

 I know properties on classes are getting a look over for the
 next iteration (last I checked) and I understand javascript is
 obviously a different language then other oo languages with a
 different foundation, but I bring this up for it's usage in
 producing stricter code that reduces errors and is easier to
 analyze.  A vote for this if anybody considered it!

 class Test
 {

 constructor()
 {
this.x=1;
 }

 func1()
 {
this.y=2;
 }

 func2()
 {
console.log(this.x+','+this.y);
 }
 }

 var test1=new Test();
 test1.func1();
 test2.func2(); // outputs 1,2

 var test2=new Test();
 test2.func(); // outputs 1,undefined

 I know classes contents are meant to be in strict mode, and I
 thinking that only allowing properties to be created in the
 constructor (or eventually static properties on the class
 itself) would make a system less prone to the conditions like
 you see above.  Basically, func1() would produce a error when
 run.

 I can see why this type of initialization of properties could be
 desired, though, especially as it reflect the way it would have
 worked if you used a function instead of a class.

 [>] Brian
 ___
 es-discuss mailing list
 es-discuss@mozilla.org 
 https://mail.mozilla.org/listinfo/es-discuss


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




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

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

Re: Proxy handler.has() does not have a receiver argument?

2016-03-19 Thread Michael Theriot
I'm trying to make the proxy-as-a-prototype pattern work but I've just
discovered the `ownKeys` trap is never called on traps on the prototype. So
even if the `has` trap is allowed to see the `receiver`, and thus verify
the properties "0", "1" exist, this pattern would fail to return the
properties "0", "1" exist on an `Object.getOwnPropertyNames` call.
Disappointing! I'd rather use a proxy on the prototype than create one for
each instance but without a correct `ownKeys` return it just doesn't come
full circle. Is there a trick to make this work or am I out of luck here? I
can only think of actually defining the properties to make it work, which
defeats the idea of using a proxy on the prototype to begin with.

Regardless I agree that traps called on a prototype chain should always
receive the `receiver` as an argument. I think the only trap other than
`set`, `get`, and `has` that can do this is the `getPrototypeOf` trap
(currently does not have a `receiver`) when the `instanceof` check needs to
climb the prototype chain.

On Thu, Mar 17, 2016 at 6:29 PM, Tom Van Cutsem <tomvc...@gmail.com> wrote:

> The rationale for not having a `receiver` argument to `has` is that the
> value produced by the "in" operator is not normally dependent on the
> receiver. This is in contrast with `get` and `set` which may find an
> accessor up the proto chain that needs to run with a `this` bound to the
> receiver.
>
> That said, I follow your line of reasoning and it is true that `has`,
> `get` and `set` are the three traps that can be called on a
> proxy-used-as-prototype (now that `enumerate` is considered deprecated), so
> it would be consistent to allow all of them to  refer back to the original
> receiver. This enables the general pattern that you illustrate.
>
> As you note, the weirdness of this is apparent because it doesn't normally
> make sense to pass a `receiver` argument to Reflect.has(). However, if
> `receiver` would be made visible in a Proxy handler's `has` trap, then
> `Reflect.has` should nevertheless be likewise extended so that one can
> faithfully forward the `receiver` argument.
>
> Spec-wise, I think the only significant change is that 7.3.10 HasProperty
> <http://www.ecma-international.org/ecma-262/6.0/#sec-hasproperty>, step 3
> must be changed to `O.[[HasProperty]](P, O)` and all [[HasProperty]]
> internal methods must likewise be extended with an extra argument (which
> they ignore). Only the Proxy implementation in 9.5.7 would then actually
> refer to that argument.
>
> Cheers,
> Tom
>
> 2016-03-17 11:46 GMT+01:00 Michael Theriot <michael.lee.ther...@gmail.com>
> :
>
>> I feel like it should, or I am misunderstanding something fundamental. I
>> made a basic scenario to explain:
>>
>> ```js
>> var arrays = new WeakMap();
>>
>> function ArrayView(array) {
>>   arrays.set(this, array);
>>
>>   return new Proxy(this, {
>> set: (target, property, value) => (arrays.has(this) && property in
>> arrays.get(this))  ? arrays.get(this)[property] = value : target[property]
>> = value,
>> get: (target, property)=> (arrays.has(this) && property in
>> arrays.get(this))  ? arrays.get(this)[property] : target[property],
>> has: (target, property)=> (arrays.has(this) && property in
>> arrays.get(this)) || property in target
>>   });
>> }
>>
>> ArrayView.prototype = Object.create(Array.prototype, {
>>   arrayLength: {
>> get() {
>>   return arrays.get(this).length;
>> }
>>   }
>> });
>> ```
>>
>> When `new ArrayView(somearray)` is called the reference to `somearray` is
>> stored in the `arrays` weak map and a proxy is returned that allows you to
>> manipulate indices on it, or fallback to the object for other properties.
>>
>> This could be simplified by putting the proxy on the prototype chain to
>> reduce overhead and actually return a genuine `ArrayView` object instead:
>>
>> ```js
>> var arrays = new WeakMap();
>>
>> function ArrayView2(array) {
>>   arrays.set(this, array);
>> }
>>
>> var protoLayer = Object.create(Array.prototype, {
>>   arrayLength: {
>> get() {
>>   return arrays.get(this).length;
>> }
>>   }
>> });
>>
>> ArrayView2.prototype = new Proxy(protoLayer, {
>>   set: (target, property, value, receiver) => (arrays.has(receiver) &&
>> property in arrays.get(receiver))  ? arrays.get(receiver)[property] = value
>> : Reflect.set(target, property, value, receiver),
>>   get: (target, property, receiver) 

Re: Class and Property Initialization

2016-03-19 Thread Michael Theriot
You can accomplish this by calling `Object.seal(this)` in the constructor.

```js
constructor() {
  this.x = 1;
  Object.seal(this);
}
```

On Fri, Mar 18, 2016 at 8:36 AM, Brian Barnes  wrote:

> I know properties on classes are getting a look over for the next
> iteration (last I checked) and I understand javascript is obviously a
> different language then other oo languages with a different foundation, but
> I bring this up for it's usage in producing stricter code that reduces
> errors and is easier to analyze.  A vote for this if anybody considered it!
>
> class Test
> {
>
> constructor()
> {
>   this.x=1;
> }
>
> func1()
> {
>   this.y=2;
> }
>
> func2()
> {
>   console.log(this.x+','+this.y);
> }
> }
>
> var test1=new Test();
> test1.func1();
> test2.func2(); // outputs 1,2
>
> var test2=new Test();
> test2.func(); // outputs 1,undefined
>
> I know classes contents are meant to be in strict mode, and I thinking
> that only allowing properties to be created in the constructor (or
> eventually static properties on the class itself) would make a system less
> prone to the conditions like you see above.  Basically, func1() would
> produce a error when run.
>
> I can see why this type of initialization of properties could be desired,
> though, especially as it reflect the way it would have worked if you used a
> function instead of a class.
>
> [>] Brian
> ___
> 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: Proxy handler.has() does not have a receiver argument?

2016-03-19 Thread Michael Theriot
gt; ES6. But that isn’t what was specified or what has now been implemented. We
>>> can all imagine how many JS features might be “better” if they worked
>>> somewhat differently. But that generally isn’t an option. The existing
>>> language features and their implementations are what they are and as JS
>>> programmers we need to work within that reality.
>>>
>>> Allen
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>>
>>> Also the `getPrototypeOf` trap is really pointless right now
>>>
>>> ```js
>>> function Yak() {}
>>> Yak.prototype = new Proxy(Yak.prototype, {
>>>   getPrototypeOf: (target) => console.log('lulz')
>>> });
>>>
>>> var yup = new Yak;
>>> Object.getPrototypeOf(yup);
>>> ```
>>>
>>> The `target` is actually the original `Yak.prototype` which is already
>>> the `yup` prototype: useless trap if used in such way.
>>>
>>> Being also unable to distinguish between `getOwnPropertyNames` vs `keys`
>>> is a bit weird.
>>>
>>> `Proxy` looks so close to be that powerful but these bits make it kinda
>>> useless for most real-world cases I've been recently dealing with.
>>>
>>> Thanks for any sort of improvement.
>>>
>>> Regards
>>>
>>>
>>>
>>>
>>> On Fri, Mar 18, 2016 at 1:54 PM, Michael Theriot <
>>> michael.lee.ther...@gmail.com> wrote:
>>>
>>>> I'm trying to make the proxy-as-a-prototype pattern work but I've just
>>>> discovered the `ownKeys` trap is never called on traps on the prototype. So
>>>> even if the `has` trap is allowed to see the `receiver`, and thus verify
>>>> the properties "0", "1" exist, this pattern would fail to return the
>>>> properties "0", "1" exist on an `Object.getOwnPropertyNames` call.
>>>> Disappointing! I'd rather use a proxy on the prototype than create one for
>>>> each instance but without a correct `ownKeys` return it just doesn't come
>>>> full circle. Is there a trick to make this work or am I out of luck here? I
>>>> can only think of actually defining the properties to make it work, which
>>>> defeats the idea of using a proxy on the prototype to begin with.
>>>>
>>>> Regardless I agree that traps called on a prototype chain should always
>>>> receive the `receiver` as an argument. I think the only trap other than
>>>> `set`, `get`, and `has` that can do this is the `getPrototypeOf` trap
>>>> (currently does not have a `receiver`) when the `instanceof` check needs to
>>>> climb the prototype chain.
>>>>
>>>> On Thu, Mar 17, 2016 at 6:29 PM, Tom Van Cutsem <tomvc...@gmail.com>
>>>> wrote:
>>>>
>>>>> The rationale for not having a `receiver` argument to `has` is that
>>>>> the value produced by the "in" operator is not normally dependent on the
>>>>> receiver. This is in contrast with `get` and `set` which may find an
>>>>> accessor up the proto chain that needs to run with a `this` bound to the
>>>>> receiver.
>>>>>
>>>>> That said, I follow your line of reasoning and it is true that `has`,
>>>>> `get` and `set` are the three traps that can be called on a
>>>>> proxy-used-as-prototype (now that `enumerate` is considered deprecated), 
>>>>> so
>>>>> it would be consistent to allow all of them to  refer back to the original
>>>>> receiver. This enables the general pattern that you illustrate.
>>>>>
>>>>> As you note, the weirdness of this is apparent because it doesn't
>>>>> normally make sense to pass a `receiver` argument to Reflect.has().
>>>>> However, if `receiver` would be made visible in a Proxy handler's `has`
>>>>> trap, then `Reflect.has` should nevertheless be likewise extended so that
>>>>> one can faithfully forward the `receiver` argument.
>>>>>
>>>>> Spec-wise, I think the only significant change is that 7.3.10
>>>>> HasProperty
>>>>> <http://www.ecma-international.org/ecma-262/6.0/#sec-hasproperty>,
>>>>> step 3 must be changed to `O.[[H

Re: Proxy handler.has() does not have a receiver argument?

2016-03-18 Thread Michael Theriot
To be clear, I'm not suggesting behavior like `getOwnPropertyNames` be
overridden by anything on the prototype, just a way to use proxies without
having to instantiate identical copies that all use the same handler.

I still believe a proxy on the prototype should always have a `receiver`
sent to each trap, but if I need to return a proxy for each object it
doesn't really matter for the example I made.

On Fri, Mar 18, 2016 at 5:43 PM, Tom Van Cutsem <tomvc...@gmail.com> wrote:

> I was on board with potentially making `has()` receiver-dependent but you
> lost me when you expected `getOwnPropertyNames` to trigger a trap on a
> proxy-as-prototype. Adding `receiver` to every MOP method is a no-go. It
> fundamentally changes the meaning of these operations and it would destroy
> the pay-only-when-you-use-it performance model of proxies, since operations
> that used to be local to only the 'own' object would now need to search the
> proto-chain for a potential proxy trap.
>
> Using a proxy-as-prototype was never intended as a way to be able to
> intercept arbitrary operations on whatever object happened to inherit from
> the proxy. A proxy-as-prototype still emulates only a single object. It
> just happens to be an object that serves as a prototype for other objects.
>
> Cheers,
> Tom
>
> 2016-03-18 23:18 GMT+01:00 Michael Theriot <michael.lee.ther...@gmail.com>
> :
>
>> I think I figured out how to make inheritance work...
>>
>> ```js
>> var wm1 = new WeakMap(); function A() { let proxy = new Proxy(this, {
>> get: (target, property, receiver) => property === 'bacon' ||
>> target[property] }); wm1.set(proxy, {}); return proxy; } var wm2 = new
>> WeakMap(); function B() { let proxy = A.call(new Proxy(this, { get:
>> (target, property, receiver) => property === 'ham' || target[property] }));
>> wm2.set(proxy, {}); return proxy; } var a = new A(); var b = new B();
>> wm1.has(a); // true wm2.has(a); // false wm1.has(b); // true wm2.has(b); //
>> true
>>
>> a.bacon; // true
>> a.ham; // undefined
>>
>> b.bacon; // true
>> b.ham; // true
>> ```
>>
>> I can't imagine this is good for optimizations though. But I guess it
>> does what I need.
>>
>> On Fri, Mar 18, 2016 at 4:45 PM, Michael Theriot <
>> michael.lee.ther...@gmail.com> wrote:
>>
>>> Michael’s preferred approach also introduces observable irregularity
>>>> into the standard JS inheritance model for ordinary objects.
>>>> Consider an object created using Michael’s preferred approach:
>>>> ```js
>>>> var arr = [0, 1];
>>>> console.log(Reflect.has(arr,”0”));  //true, arr has “0” as an own
>>>> property
>>>> var subArr = Object.create(arr);
>>>> console.log(Reflect.has(subArr,”0”));  //true, all unshadowed
>>>> properties of proto visible from ordinary objects
>>>> var b = new ArrayView2(arr);
>>>> console.log(Reflect.has(b,”0”));  //true, prototype proxy makes array
>>>> elements visible as if properties of b
>>>> var subB= Object.create(b);
>>>> console.log(Reflect.has(subB,”0”));  //false, some unshadowed
>>>> properties of proto is not visible from subB
>>>> ```
>>>
>>>
>>> I think this relates to the original concern; if you could pass the
>>> receiver this could be resolved. That still leaves `getOwnPropertyNames`
>>> reporting wrong values though and I see no foreseeable way to resolve that
>>> without returning an actual proxy itself.
>>>
>>> The reason I'm trying this approach is because I read on the MDN that
>>> when used in the prototype a `receiver` argument is passed that references
>>> the instance, so I assumed this was the intent behind it. The only other
>>> explanation I could think of is that proxies have a receiver to mimic the
>>> `Reflect.set`/`Reflect.get` methods which need a receiver for
>>> getters/setters to work properly, not so you can use them on the prototype
>>> chain.
>>>
>>> The other case I would make is every instance would have an identical
>>> proxy, and it just makes sense to put that on the prototype for the same
>>> reasons you put shared methods/properties there.
>>>
>>> Note that we are not really talking about a new capability here.
>>>> Michael’s first design shows that ES proxies already have the capability to
>>>> implement the object level semantics he desires.
>>>
>>>
>>> To be fair I had several obstacles with inheritance using the first
>>

Re: Proxy handler.has() does not have a receiver argument?

2016-03-18 Thread Michael Theriot
I think I figured out how to make inheritance work...

```js
var wm1 = new WeakMap(); function A() { let proxy = new Proxy(this, { get:
(target, property, receiver) => property === 'bacon' || target[property]
}); wm1.set(proxy, {}); return proxy; } var wm2 = new WeakMap(); function
B() { let proxy = A.call(new Proxy(this, { get: (target, property,
receiver) => property === 'ham' || target[property] })); wm2.set(proxy,
{}); return proxy; } var a = new A(); var b = new B(); wm1.has(a); // true
wm2.has(a); // false wm1.has(b); // true wm2.has(b); // true

a.bacon; // true
a.ham; // undefined

b.bacon; // true
b.ham; // true
```

I can't imagine this is good for optimizations though. But I guess it does
what I need.

On Fri, Mar 18, 2016 at 4:45 PM, Michael Theriot <
michael.lee.ther...@gmail.com> wrote:

> Michael’s preferred approach also introduces observable irregularity into
>> the standard JS inheritance model for ordinary objects.
>> Consider an object created using Michael’s preferred approach:
>> ```js
>> var arr = [0, 1];
>> console.log(Reflect.has(arr,”0”));  //true, arr has “0” as an own property
>> var subArr = Object.create(arr);
>> console.log(Reflect.has(subArr,”0”));  //true, all unshadowed properties
>> of proto visible from ordinary objects
>> var b = new ArrayView2(arr);
>> console.log(Reflect.has(b,”0”));  //true, prototype proxy makes array
>> elements visible as if properties of b
>> var subB= Object.create(b);
>> console.log(Reflect.has(subB,”0”));  //false, some unshadowed properties
>> of proto is not visible from subB
>> ```
>
>
> I think this relates to the original concern; if you could pass the
> receiver this could be resolved. That still leaves `getOwnPropertyNames`
> reporting wrong values though and I see no foreseeable way to resolve that
> without returning an actual proxy itself.
>
> The reason I'm trying this approach is because I read on the MDN that when
> used in the prototype a `receiver` argument is passed that references the
> instance, so I assumed this was the intent behind it. The only other
> explanation I could think of is that proxies have a receiver to mimic the
> `Reflect.set`/`Reflect.get` methods which need a receiver for
> getters/setters to work properly, not so you can use them on the prototype
> chain.
>
> The other case I would make is every instance would have an identical
> proxy, and it just makes sense to put that on the prototype for the same
> reasons you put shared methods/properties there.
>
> Note that we are not really talking about a new capability here. Michael’s
>> first design shows that ES proxies already have the capability to implement
>> the object level semantics he desires.
>
>
> To be fair I had several obstacles with inheritance using the first
> version.
>
> ```js
> var wm1 = new WeakMap();
>
> function A() {
>   wm1.set(this, {});
>   return new Proxy(this, {});
> }
>
> var wm2 = new WeakMap();
>
> function B() {
>   A.call(this);
>   wm2.set(this, {});
>   return new Proxy(this, {});
> }
>
> var a = new A();
> var b = new B();
>
> wm1.has(a); // true
> wm2.has(a); // false
>
> wm1.has(b); // false
> wm2.has(b); // true
> ```
>
> As you can see storing a reference to `this` can't work anymore, since we
> actually return a proxy. You can try to work around this...
>
> ```js
> var wm1 = new WeakMap();
>
> function A() {
>   let self = this;
>   if(new.target === A) {
> self = new Proxy(this, {});
>   }
>   wm1.set(self, {});
>   return self;
> }
>
> var wm2 = new WeakMap();
>
> function B() {
>   let self = this;
>   if(new.target === B) {
> self = new Proxy(this, {});
>   }
>   A.call(self);
>   wm2.set(self, {});
>   return self;
> }
>
> var a = new A();
> var b = new B();
>
> wm1.has(a); // true
> wm2.has(a); // false
>
> wm1.has(b); // true
> wm2.has(b); // true
> ```
>
> But then problems arise because the new proxy doesn't go through the old
> proxy. So anything guaranteed by A()'s proxy is not guaranteed by B()'s
> proxy.
>
> ```js
> var wm1 = new WeakMap();
>
> function A() {
>   let self = this;
>   if(new.target === A) {
> self = new Proxy(this, {
>   get: (target, property, receiver) => property === 'bacon' ||
> target[property]
> });
>   }
>   wm1.set(self, {});
>   return self;
> }
>
> var wm2 = new WeakMap();
>
> function B() {
>   let self = this;
>   if(new.target === B) {
> self = new Proxy(this, {
>   get: (target, property, receiver) => property === 'ham' ||
> target[property]
> });
>   }
>   A.call(se