Small Proposal "!in"

classic Classic list List threaded Threaded
45 messages Options
123
Reply | Threaded
Open this post in threaded view
|

Re: Small Proposal "!in"

Isiah Meadows-2
> "on" is a good name.  Agree on separate.

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

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

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

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

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

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

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

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

-----

Isiah Meadows
[hidden email]
www.isiahmeadows.com


On Thu, Jul 19, 2018 at 1:03 PM, Mike Samuel <[hidden email]> wrote:

>
>
> On Thu, Jul 19, 2018 at 11:56 AM Michael Theriot
> <[hidden email]> wrote:
>>>>
>>>> For me, `hasOwn` with the different operand order isn't a problem, but
>>>> others may take a different view. Trying to keep the same order takes us
>>>> down a route like `inOwn` which I can't say I care for.
>>>
>>>
>>> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
>>> footgun (especially for Colemak users) and maybe isn't clear enough about
>>> its semantics.  I would argue that operators aren't camel cased in JS
>>> though, so `hasown`/`inown`.
>>
>>
>> For what it's worth I was also thinking of an "on" operator when reading
>> this message, so this is intuitive to me. I also think that is a separate
>> idea to propose though.
>
>
> "on" is a good name.  Agree on separate.
>
>
>>>>
>>>> Of couse the usage of `in` is most of the time is not recommended, but
>>>> it has it place.
>>>
>>>
>>> What places does it have?
>>> I remain unconvinced that `in` has significant enough use cases to
>>> warrant high-level ergonomics
>>> were it being proposed today.
>>>
>>> It exists, and it'll probably never be removed from the language, but I
>>> don't think it should be taught
>>> as a good part of the language, and linters should probably flag it.
>>
>>
>> Maybe a radical thought, but does this not apply to hasOwnProperty? If you
>> have strong type management why test for a property? The one case I can
>> think of is parsing JSON but I handle that with destructuring. Are there
>> significant use cases for it? Should linters flag it?
>
>
> Good questions.
> Linters should flag
>    x.hasOwnProperty(y)
> since if you're unsure whether x has an own property y you're probably
> unsure whether x has an own property 'hasOwnProperty'.
>
> IIRC, destructuring traverses prototypes so see caveat about library code
> and monkeypatching below.
> const { toString: f } = {}
> typeof f // 'funciton'
>
> You're right that in the middle of an application an instance's type should
> determine whether a property is present.
> There are use cases at the periphery.
>
> Use cases in bleeding edge JS include
> * As you noted, operations on parsed JSON.  Even if you use revivers to
> parse JSON to Maps instead of Objects
>   you either need own property checks or Object.setPrototypeOf(parsed, null)
> when populating the Map.
> * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> overwrite existing properties in the assignee.
> * Reliable hole detection in arrays: (1 !on [0, , 2])
> * Adapters that use naming conventions between JS objects and external
> systems, like between database field names and JS property names.
> * Distinguishing between user-code-defined properties on a host object like
> an HTML element and readonly host properties.
>
> Many use cases for hasOwnProperty could be better supported by Map, Set, and
> Object.create(null) including:
> * Objects used as lookup tables.
> * Lookup tables with special purpose fallback logic like message bundles
> that fall back from locale 'aa-BB' to 'aa'.
> * Configuration objects.
> * Function options bundles.
> but idiomatic JS hasn't caught up and some library code has to run on old
> interpreters, so a transpiling `on` would be nice.
> The last two are mostly an issue in library code that needs to be resilient
> when loaded alongside monkeypatched prototypes.
>
> Honorable mention:
> * for(...in...) iteration broken
> solved by for(...of...):
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Small Proposal "!in"

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

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

jhpratt

On Thu, Jul 19, 2018 at 8:56 PM, Isiah Meadows <[hidden email]> wrote:
> "on" is a good name.  Agree on separate.

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

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

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

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

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

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

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

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

-----

Isiah Meadows
[hidden email]
www.isiahmeadows.com


On Thu, Jul 19, 2018 at 1:03 PM, Mike Samuel <[hidden email]> wrote:
>
>
> On Thu, Jul 19, 2018 at 11:56 AM Michael Theriot
> <[hidden email]> wrote:
>>>>
>>>> For me, `hasOwn` with the different operand order isn't a problem, but
>>>> others may take a different view. Trying to keep the same order takes us
>>>> down a route like `inOwn` which I can't say I care for.
>>>
>>>
>>> Nor me. I would argue for `on` (`'a' on b`), but that is a huge typo
>>> footgun (especially for Colemak users) and maybe isn't clear enough about
>>> its semantics.  I would argue that operators aren't camel cased in JS
>>> though, so `hasown`/`inown`.
>>
>>
>> For what it's worth I was also thinking of an "on" operator when reading
>> this message, so this is intuitive to me. I also think that is a separate
>> idea to propose though.
>
>
> "on" is a good name.  Agree on separate.
>
>
>>>>
>>>> Of couse the usage of `in` is most of the time is not recommended, but
>>>> it has it place.
>>>
>>>
>>> What places does it have?
>>> I remain unconvinced that `in` has significant enough use cases to
>>> warrant high-level ergonomics
>>> were it being proposed today.
>>>
>>> It exists, and it'll probably never be removed from the language, but I
>>> don't think it should be taught
>>> as a good part of the language, and linters should probably flag it.
>>
>>
>> Maybe a radical thought, but does this not apply to hasOwnProperty? If you
>> have strong type management why test for a property? The one case I can
>> think of is parsing JSON but I handle that with destructuring. Are there
>> significant use cases for it? Should linters flag it?
>
>
> Good questions.
> Linters should flag
>    x.hasOwnProperty(y)
> since if you're unsure whether x has an own property y you're probably
> unsure whether x has an own property 'hasOwnProperty'.
>
> IIRC, destructuring traverses prototypes so see caveat about library code
> and monkeypatching below.
> const { toString: f } = {}
> typeof f // 'funciton'
>
> You're right that in the middle of an application an instance's type should
> determine whether a property is present.
> There are use cases at the periphery.
>
> Use cases in bleeding edge JS include
> * As you noted, operations on parsed JSON.  Even if you use revivers to
> parse JSON to Maps instead of Objects
>   you either need own property checks or Object.setPrototypeOf(parsed, null)
> when populating the Map.
> * Non-clobbering mass assignment.  Like Object.assign but that doesn't
> overwrite existing properties in the assignee.
> * Reliable hole detection in arrays: (1 !on [0, , 2])
> * Adapters that use naming conventions between JS objects and external
> systems, like between database field names and JS property names.
> * Distinguishing between user-code-defined properties on a host object like
> an HTML element and readonly host properties.
>
> Many use cases for hasOwnProperty could be better supported by Map, Set, and
> Object.create(null) including:
> * Objects used as lookup tables.
> * Lookup tables with special purpose fallback logic like message bundles
> that fall back from locale 'aa-BB' to 'aa'.
> * Configuration objects.
> * Function options bundles.
> but idiomatic JS hasn't caught up and some library code has to run on old
> interpreters, so a transpiling `on` would be nice.
> The last two are mostly an issue in library code that needs to be resilient
> when loaded alongside monkeypatched prototypes.
>
> Honorable mention:
> * for(...in...) iteration broken
> solved by for(...of...):
>
>
> _______________________________________________
> es-discuss mailing list
> [hidden email]
> https://mail.mozilla.org/listinfo/es-discuss
>
_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Small Proposal "!in"

Augusto Moura
In reply to this post by Mike Samuel
The only use that came to mind was detecting a property descriptor in a prototype chain. Sure is not a day to day use case, but it's useful when writing libraries that involve descriptor modifications (decorators, for example, will largely involve it). Recently I had to get the descriptor of properties in a potencial deep inheritance (current Object helpers only return own descriptors), and used the `in` operator to guard the prototype recursive search.

``` js
const searchRecursivelyPropDescriptor = (obj, prop) =>
  !obj
    ? undefined
    : Object.getOwnPropertyDescriptor(obj, prop) || searchRecursivelyPropDescriptor(Object.getPrototypeOf(obj), prop);

const getPropertyDescriptor = (obj, prop) => 
  prop in obj ? searchRecursivelyPropDescriptor(obj, prop) : undefined;
```

Anyways, we can't simply ignore the operator, if we are getting a `!instance` and opening precedence to future operators (`!on` or `!hasOwn`) I don't see any problems with a `!in`. Legacy bad design should not affect language consistency of new features.

Em qui, 19 de jul de 2018 às 12:07, Mike Samuel <[hidden email]> escreveu:
On Thu, Jul 19, 2018 at 10:40 AM Augusto Moura <[hidden email]> wrote:
Of couse the usage of `in` is most of the time is not recommended, but it has it place. 

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

It exists, and it'll probably never be removed from the language, but I don't think it should be taught
as a good part of the language, and linters should probably flag it.

--
Augusto Moura

_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Small Proposal "!in"

Steve Fink
This reads a little oddly, but another syntax option would be `prop in.own obj` (equivalent to `obj.hasOwnProperty(prop)`) and then `prop !in.own obj`.

Or perhaps `in.own` should be Object.prototype.hasOwnProperty.call(obj, prop)?

Though this makes me think it would be nice to have something like `name in.map mymap` (equivalent to `mymap.has(name)`)


On 07/20/2018 10:09 AM, Augusto Moura wrote:
The only use that came to mind was detecting a property descriptor in a prototype chain. Sure is not a day to day use case, but it's useful when writing libraries that involve descriptor modifications (decorators, for example, will largely involve it). Recently I had to get the descriptor of properties in a potencial deep inheritance (current Object helpers only return own descriptors), and used the `in` operator to guard the prototype recursive search.

``` js
const searchRecursivelyPropDescriptor = (obj, prop) =>
  !obj
    ? undefined
    : Object.getOwnPropertyDescriptor(obj, prop) || searchRecursivelyPropDescriptor(Object.getPrototypeOf(obj), prop);

const getPropertyDescriptor = (obj, prop) => 
  prop in obj ? searchRecursivelyPropDescriptor(obj, prop) : undefined;
```

Anyways, we can't simply ignore the operator, if we are getting a `!instance` and opening precedence to future operators (`!on` or `!hasOwn`) I don't see any problems with a `!in`. Legacy bad design should not affect language consistency of new features.

Em qui, 19 de jul de 2018 às 12:07, Mike Samuel <[hidden email]> escreveu:
On Thu, Jul 19, 2018 at 10:40 AM Augusto Moura <[hidden email]> wrote:
Of couse the usage of `in` is most of the time is not recommended, but it has it place. 

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

It exists, and it'll probably never be removed from the language, but I don't think it should be taught
as a good part of the language, and linters should probably flag it.

--
Augusto Moura


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss



_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
Reply | Threaded
Open this post in threaded view
|

Re: Small Proposal "!in"

T.J. Crowder-2
On Tue, Jul 24, 2018 at 12:28 AM, Steve Fink
<[hidden email]> wrote:
> Or perhaps `in.own` should be Object.prototype.hasOwnProperty.call(obj,
> prop)?

It should just use the abstract [HasOwnProperty][1] operation directly.

-- T.J. Crowder


_______________________________________________
es-discuss mailing list
[hidden email]
https://mail.mozilla.org/listinfo/es-discuss
123