How about something like
table{}.user{}.id{}.type = ‘int’
this syntax could be used for arrays, too:
table{}.userList[].push(‘Jane Doe’)
From: es-discuss <[email protected]> on behalf of Jacob Bloom
<[email protected]>
Date: Monday, 27April, 2020 at 02:23
To: es-discuss <[email protected]>
Subject: Re: Proposal: Forced Chaining Operator "!."
(Sorry for the triple-post, I keep pondering this proposal) Come to think of
it, you could do something pretty similar with the `??=` operator from the
logical assignments proposal:
```javascript
(((table ??= {}).user ??= {}).id ??= {}).type = 'int';
```
The main difference being that it tests for nullishness instead of whether the
LHS is a non-null object, but I think that's within the spirit of the original
proposal. It also lets you set a custom default value (like the "getsert"
function above). The shortfall of course is the accumulating parentheses
On Sat, Apr 25, 2020 at 8:08 PM Jacob Bloom
<[email protected]<mailto:[email protected]>> wrote:
Is the Perl syntax opt-in like the proposed operator? Or does it happen on all
accesses to nulls? If it's opt-in in JS, then it doesn't seem to me that it'd
cause too much unexpected behavior, though it could be argued that it's ripe
for abuse by new devs trying to avoid errors.
Something that might be a more generalized middle ground (and could later
assist in transpiling the !. operator) is a "getsert" (?) method in the
standard library that takes a default value and sets it on the parent object if
that property is currently unset:
```javascript
Object.getsert = (obj, identifier, defaultvalue) => {
if (!(identifier in obj)) obj[identifier] = defaultvalue;
return obj[identifier];
}
const table = {};
console.log('before getsert:', table.user); // undefined
console.log('during getsert:', Object.getsert(table, 'user', 5)); // 5
console.log('after getsert:', table.user); // 5
```
...I have concerns about such a method's usability though, since a getsert is
far more verbose than a normal get. It'd be more convenient on Object.prototype
(e.g. `table.getsert('user', 5)` ), but I assume that's a no-go.
Oh also, I think the proposed syntax would collide with TypeScript's non-null
assertion operator
https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html#non-null-assertion-operator
-- I don't know to what degree that's a concern when proposing new JS syntax
On Sat, Apr 25, 2020 at 3:00 PM Joe Eagar
<[email protected]<mailto:[email protected]>> wrote:
Anyone have ideas on more examples? It’s tempting to make a transpiler plugin
to see how it works in practice, but I’d like to see more examples first. Thanks
On Sat, Apr 25, 2020 at 1:12 PM Jacob Bloom
<[email protected]<mailto:[email protected]>> wrote:
Maybe it would be less footgunny to support autovivification in a more
class-based way, like Python does?
```javascript
class AutoVivArray extends Array {
[Symbol.getMissing](identifier) {
/* if we're here, identifier is not an ownProperty
* and is nowhere on the prototype chain */
this[identifier] = new Whatever();
return this[identifier];
}
}
```
Though I can't see how that's much more useful than Proxies besides saving you
a little boilerplate
On Fri, Apr 24, 2020 at 3:23 PM Thomas Shinnick
<[email protected]<mailto:[email protected]>> wrote:
You are describing Perl's autovivification feature. Also possible (in that
syntax) for arrays and mixed object/array chains. I liked it, but many saw it
as a footgun. There was even a compile time module to turn off the feature, if
the coder wanted more caution. Having mentioned Perl I will assume this is DOA?
On Fri, Apr 24, 2020, 14:36 Tobias Buschor
<[email protected]<mailto:[email protected]>> wrote:
Since we now have the "Optional Chaninig Operator" , perhaps a "Forced Chaining
Operator" would also be worth considering.
I, personally, could use it:
let table;
table!.user!.id!.type = 'int'
will evaluate to:
let table;
if ( ! ( table instanceOf Object) ) table = {};
if ( ! ( table.user instanceOf Object) ) table.user = {};
if ( ! ( table.user.id<http://table.user.id> instanceOf Object) )
table.user.id<http://table.user.id> = {};
table.user.id.type = 'int';
Also to be noted:
Sometimes a fallback to `Object.create(null)` or something other might be
desirable.
But since `{}` is syntactical sugar for `Object.create(Object.prototype)`, this
would be consistent.
_______________________________________________
es-discuss mailing list
[email protected]<mailto:[email protected]>
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]<mailto:[email protected]>
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]<mailto:[email protected]>
https://mail.mozilla.org/listinfo/es-discuss
_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss