Closed ljharb closed 1 year 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.
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
.
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.
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.
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.
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.
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.
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.
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.
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:
value
property or get
/set
properties (pros: consistent API, cons: boilerplate/object creation for the common case)use a different DSL for accessors - Map.prototype.size
would fail, but get Map.prototype.size
or set Map.prototype.size
would not (the former would return the getter, the latter undefined, regardless of the outcome of #6).
I like the third option because it avoids taxing the common case, and avoids the creation of a transient container for the get/set pair.
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 💖.
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.