New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spec convention for branding #354

Open
domenic opened this Issue Feb 3, 2016 · 8 comments

Comments

Projects
None yet
5 participants
@domenic
Member

domenic commented Feb 3, 2016

As we write more Ecmaspeak specs (Streams, 402, Loader), we find the way that ES does branding a bit onerous and opaque. That is, it picks a privileged internal slot and says "if you have this internal slot, you can pass go."

I propose the following instead:

Potential variant: use a small badge in the heading of the method/abstract op, like streams does for throw/nothrow, like brandcheck(Map).

Does this sound interesting? If so I could work on a PR, because streams is getting really sick of defining IsStreamWhatever(x) abstract ops and repeating the boilerplate everywhere. Having ES lead the way would be great.

domenic referenced this issue in whatwg/streams Feb 3, 2016

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Feb 4, 2016

Member

We intentionally avoiding any "branding" language in the ES6 spec. because the precious use of [[Class]] as a branding mechanism had been too broadly assumed to imply things other than what was actually required by the specification. And somebody thought it was something that actually had to exist as a string value or tried to misuse it in various ways.

Generally, all that we want is to require with the replacement language is that that specified functions that depend upon specific object-level encodings of internal slot data throw an error when applied to objects that do not encode those internal slots.

Another way to describe the [[MapData]] requirement might be to say something like "is an object that was successfully allocated and initialized by invoking the [[Construct]] internal method of a built-in Map constructor" (but can't say "the Map constructor" because of multiple Realms).

I'm not particularly attached to the ES6 language, but I think we should avoid any language that implies anything more than "an object that meets the requirements of this method".

Member

allenwb commented Feb 4, 2016

We intentionally avoiding any "branding" language in the ES6 spec. because the precious use of [[Class]] as a branding mechanism had been too broadly assumed to imply things other than what was actually required by the specification. And somebody thought it was something that actually had to exist as a string value or tried to misuse it in various ways.

Generally, all that we want is to require with the replacement language is that that specified functions that depend upon specific object-level encodings of internal slot data throw an error when applied to objects that do not encode those internal slots.

Another way to describe the [[MapData]] requirement might be to say something like "is an object that was successfully allocated and initialized by invoking the [[Construct]] internal method of a built-in Map constructor" (but can't say "the Map constructor" because of multiple Realms).

I'm not particularly attached to the ES6 language, but I think we should avoid any language that implies anything more than "an object that meets the requirements of this method".

@domenic

This comment has been minimized.

Show comment
Hide comment
@domenic

domenic Feb 4, 2016

Member

That makes sense. I'd be happy to spell it as HasInternalSlotsOf(o, Class) / RequireInternalSlotsOf or WasConstructedWith(o, Class) / RequireConstructedWith. Would that address your concern?

Member

domenic commented Feb 4, 2016

That makes sense. I'd be happy to spell it as HasInternalSlotsOf(o, Class) / RequireInternalSlotsOf or WasConstructedWith(o, Class) / RequireConstructedWith. Would that address your concern?

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Feb 4, 2016

Member

I'd probably prefer either of the first two. With WasConstructedWith somebody might misinterpret it to preclude subclass instances even if they had the required slots

Member

allenwb commented Feb 4, 2016

I'd probably prefer either of the first two. With WasConstructedWith somebody might misinterpret it to preclude subclass instances even if they had the required slots

@zenparsing

This comment has been minimized.

Show comment
Hide comment
@zenparsing

zenparsing Feb 4, 2016

Contributor

FWIW, when writing these kinds of tests, I generally just want to say something like:

  1. Assert: generator is an AsyncGenerator instance.

And have that statement be equivalent to saying that the object has all of the internal slots which are associated with (in this case) AsyncGenerator.

Contributor

zenparsing commented Feb 4, 2016

FWIW, when writing these kinds of tests, I generally just want to say something like:

  1. Assert: generator is an AsyncGenerator instance.

And have that statement be equivalent to saying that the object has all of the internal slots which are associated with (in this case) AsyncGenerator.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Feb 4, 2016

Member

"Perform ? RequireInternalSlotsOf(generator, AsyncGenerator)" or "Perform ! RequireInternalSlotsOf(generator, AsyncGenerator)" (for the assert form) seems like it would work just fine - I think there's lots of places in the spec this construct would be useful.

Member

ljharb commented Feb 4, 2016

"Perform ? RequireInternalSlotsOf(generator, AsyncGenerator)" or "Perform ! RequireInternalSlotsOf(generator, AsyncGenerator)" (for the assert form) seems like it would work just fine - I think there's lots of places in the spec this construct would be useful.

@allenwb

This comment has been minimized.

Show comment
Hide comment
@allenwb

allenwb Feb 4, 2016

Member

@ljharb
If don't have any problems with that abstract operation name. But what sort of value is the second argument? Presumably instances of a constructor. But no all constructors have global names. And note that constructor functions can them selves have unique internal slots. Perhaps a section number reference is what you need.

Member

allenwb commented Feb 4, 2016

@ljharb
If don't have any problems with that abstract operation name. But what sort of value is the second argument? Presumably instances of a constructor. But no all constructors have global names. And note that constructor functions can them selves have unique internal slots. Perhaps a section number reference is what you need.

@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb Feb 4, 2016

Member

Yeah that's a good point - I more find value in the ability to concisely repeat these assertions without having to repeat the internal slot names. I'm not attached to the abstract operation name.

Member

ljharb commented Feb 4, 2016

Yeah that's a good point - I more find value in the ability to concisely repeat these assertions without having to repeat the internal slot names. I'm not attached to the abstract operation name.

@annevk

This comment has been minimized.

Show comment
Hide comment
@annevk

annevk Feb 23, 2016

Contributor

A non-require version would be great for the structured cloning algorithm, which does a ton of branching based on potential internal slots.

Contributor

annevk commented Feb 23, 2016

A non-require version would be great for the structured cloning algorithm, which does a ton of branching based on potential internal slots.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment