tc39 / proposal-get-intrinsic

EcmaScript language proposal for a way to get intrinsics.
https://tc39.github.io/proposal-get-intrinsic/
MIT License
32 stars 4 forks source link

Open Question: what to do about accessors? #4

Closed ljharb closed 1 year ago

ljharb commented 3 years ago

When an intrinsic is an accessor property, the only use cases I have, and am aware of, require the get accessor function directly.

Although when an intrinsic is a data property getIntrinsic will just return it, one option is that when it's an accessor property, getIntrinsic returns the getter. This is what https://npmjs.com/es-abstract does, and seems the easiest to me.

Another possibility would be returning a property descriptor, but then we'd have to do that for every intrinsic - and there's no use case i'm aware of for knowing the enumerability/configurability/writability of intrinsics, and no intrinsics currently have a setter.

mhofman commented 3 years ago

I believe Web IDL does have an attribute concept that allows an interface to define attributes that end up exposed as getters/setters on the corresponding ECMAScript prototype objects.

ljharb commented 3 years ago

True, and I believe HTML does have some setters, despite 262 having none.

That's an argument towards returning some kind of descriptor object - whether it's a full descriptor, or maybe just value or get/set.

mhofman commented 3 years ago

An alternative would be to prefix the property name with get or set. E.g. "Map.prototype.get size" ? I doubt the 262 spec or any host would ever define a property name that includes a space.

ljharb commented 3 years ago

or get Map.prototype.size, perhaps - but then what happens with Map.prototype.size directly? Would that be "not an intrinsic"?

If so, I think that could work very nicely.

mhofman commented 3 years ago

I think I prefer Map.prototype.get size since get size is the name of the getter function, which is observable.

Map.prototype.size would not be an intrinsic.

ljharb commented 3 years ago

The name isn't relevant, though, otherwise Set.prototype.keys wouldn't be an intrinsic either.

Also, there could be a function named "get" - i think Map.prototype.get size looks like an intrinsic named "Map.prototype.get" to me.

mhofman commented 3 years ago

I didn't express myself clearly.

If %Foo.prototype.bar% is an intrinsic accessor and not a value, only 'Foo.prototype.get bar' and/or 'Foo.prototype.set bar' would represent the intrinsic, never 'Foo.prototype.bar' on its own.

Regarding syntax, an alternative to keep with the property access model would be "Foo.prototype['get bar']", with all the string escaping nightmares that entails.

ljharb commented 3 years ago

Since the function name isn’t relevant, i strongly feel like your suggested string syntax isn’t viable.

We can certainly bikeshed alternatives tho - i do very much like the suggestion to differentiate the strings for data vs accessor vs mutator properties.

mhofman commented 3 years ago

Since we're bikeshedding this, another alternative that also kinda solves the symbol issue is to take an array of path elements, which are either strings or symbols. E.g. ['Foo', 'prototype', 'get bar'] or ['Foo', 'prototype', Symbol.iterator].

However, it makes it less clear that getIntrinsic(['Foo', 'prototype', 'baz']) and getIntrinsic(['Foo', 'prototype']).baz are not equivalent.

ljharb commented 3 years ago

I'd prefer to avoid the path array approach; it's added boilerplate and memory usage solely for explicitness (using a list of arguments would avoid the extra array, but wouldn't address the boilerplate concerns).

So far the best options I can see are one of:

bathos commented 2 years ago

or get Map.prototype.size, perhaps - but then what happens with Map.prototype.size directly? Would that be "not an intrinsic"? If so, I think that could work very nicely.

That makes perfect sense to me — I have a strong preference for option three.

There’s a descriptor option in my lib’s DSL (#d for descriptor, #g for get, #s for set), so I can speak in the past tense and say that I’ve only found it useful a small number of times and I wouldn’t include it again if I were recreating it now. At least in web platform API stuff, retrieving get/set is very common, maybe more common than data properties, so anything that keeps that smooth is 💖.