-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Editorial: what is a built-in object? #2608
Comments
More things that are at odds with my understanding: @allenwb wrote in #1273 (comment)
and that section 10.3.3 |
Abstract closures didn't exist in 2018, when that comment was written; if that helps. |
I didn't mean that those things contradict each other, but that both don't fit in my understanding of the term "built-in". I would have expected
|
That will run into some problems: search the spec for occurrences of "anonymous built-in function" (other than %ThrowTypeError%) and you'll find functions that are not created at startup, but rather in response to user code.
If an implementation added non-standard objects to the initial environment, I think I'd call those intrinsics too.
I'm inclined to agree. The spec definitely does define built-in exotic objects (e.g. %Array.prototype%), but they're not really the topic of 10.4.
Right. They're not "supplied" by the implementation, except in the unhelpful sense that everything is supplied by the implementation.
Given that the first sentence refers to "built-in exotic objects", my guess is that the title's intended meaning was "Internal Methods and Slots of Built-in Exotic Objects".
I wouldn't omit it, because the section isn't talking about all possible exotics, just the standard ones. So I'd vote for "Internal Methods and Slots of Standard Exotic Objects". |
That's correct. (Though I think "implemented in native code" is too specific.)
Hm, no. As I understand it, there are 3 mutually orthogonal dichotomies for objects (not just functions):
All 8 combinations are allowed, though a given implementation need not exhibit all of them.
Yes, a built-in function can be ordinary.
No, the spec explicitly says that built-in functions can be ECMAScript function objects. |
Thanks for the clarifications @jmdyck!
Ah, so "built-in" really is supposed to mean "built into the implementation" as opposed to "defined by user code", regardless whether it is an intrinsic created at startup or created dynamically.
I think this best describes my issue. Where to draw the line?
Yes, that was my guess as well, and it felt wrong.
Sure, anything that doesn't call them "built-in" is fine for me :-) I guess I just wouldn't call out "standard" since that's the implicit default for everything described in the specification, only non-standard objects need to be marked as "implementation-defined".
Oh, I didn't know that. Is it intentional that these can have an arbitrary [[SourceText]], which is not necessarily a
Ah, right, I didn't consider built-in ordinary functions. Not having read the 10.3 "Built-in Function Objects" prose properly, I thought they would always need to have exotic [[Call]] / [[Construct]] as defined in 10.3 .
Right. I would however distinguish
where user-defined functions are necessarily non-intrinsic. Also I had some trouble imagining implementation-defined (i.e. non-standard) user-defined (i.e. non-built-in) functions, but I suppose a custom function definition language like WebAssembly would qualify. Those would necessarily need to be exotic though? Also, isn't an ordinary object also necessarily a standard object? The only thing I could think of would be an object whose existence is non-standard, i.e. it's an intrinsic that but not part of the standard intrinsics… |
That might be a good way to think of it, although "built into the implementation" isn't that great from a definitional perspective. (Sometimes I think that "built-in function" doesn't really have an intensional definition, it's just whatever the spec says is created by CreateBuiltinFunction.)
I'm not sure what you're getting at there. In my understanding:
Hm. An ordinary [ECMAScript] function is required to have (i.e., behave as if it had) a
That does not appear to be guaranteed. An ordinary built-in function will have a
(Apparently, Function.p.toString wants to defy your expectations.)
I agree that that's a dichotomy, though it isn't orthogonal to the built-in/non-built-in axis. (There's no such thing as an intrinsic non-built-in. I think.)
So if an implementation implements (say)
Actually, I've lost track of what I had in mind for "standard" yesterday.
Yup.
The definition for standard object is "object whose semantics are defined by this specification". If that means an object whose internal methods have spec-supplied algorithms, then yes every ordinary object is a standard object. But by that interpretation, every built-in function (regardless of how it's implemented, and regardless of whether it's a function defined in the spec) would be a standard object. And if you can't say "a non-standard built-in function", I'm not sure that's a good meaning for "standard".
If "standard object" meant something like "object whose existence is guaranteed by the spec", then yeah it would make sense to talk about [non-]standard built-ins and [non-]standard intrinsics. |
Yeah, so it seems :-) Maybe I'll open another issue to discuss that in particular.
Yes, I meant that as a replacement (with different name and meaning) for the built-in/non-built-in axis, which seemed unhelpful with its current definition (as "objects supplied by the implementation").
Yes. It only matters that it's implemented by the ECMAScript host implementation, not whether it's an ordinary native function or an exotic native function.
How so? A built-in function could be a function object with an algorithm not defined by the ECMAScript standard, implemented either as an exotic function (with custom [[Call]]) or as an ordinary function with custom source code. |
Yup, that seems valid. (intrinsic/non-intrinsic is orthogonal to ordinary/exotic).
So isn't that the same dichotomy as built-in vs non-built-in?
Yes.
No. In general, an exotic function can have a custom I.e., a built-in function's
Yes. |
Maybe? That's why I called it "built-in function" or "native function". But the difference to the current definition of "built-in" in the spec is that my term only applies to function objects, and is only concerned with what [[Call]] does.
I understand that "conforming to these definitions" in 10.3 does specify invariants, or at best templates, not concrete algorithms. Given that "An implementation may also provide additional built-in function objects that are not defined in this specification", not all built-in functions have spec-supplied algorithms. Things like Also I think that the sentence "If a built-in function object is not implemented … it must provide …" really should only apply to standard functions. The whole section 10.3 speaks about "The built-in function objects defined in this specification", which "may be implemented as either ECMAScript function objects (10.2) whose behaviour is provided using ECMAScript code or as implementation provided function exotic objects whose behaviour is provided in some other manner." I do believe that implementations are allowed to provide exotic function objects with [[Call]] and/or [[Construct]] methods that do not conform to 10.3.1/10.3.2. Proxy function objects and bound function objects are examples of this, and I see no reason why an implementation couldn't extend this to other exotic function kinds. Some of which are implemented by user code, others I would classify as built-in. |
Okay. Are you saying that the current definition would call them built-in?
But is that particular to 10.3? Are there spec algorithms that you would say are concrete?
I think we need some more precision here. Note that there are two levels of algorithm involved. One is what a user would read to find out what the function does (call it 'behavior', say), and another is what a function's (Note that there's a similar problem with "semantics defined by this specification" in the definition of 'standard object'. If a function's
And that seems sensible to me. I was just saying it might not be compatible with an interpretation in which every ordinary object is a standard object.
Yes, the first sentence of 10.3 does have the qualification "defined in this specification", but then the last sentence of the paragraph talks about "additional built-in function objects that are not defined in this specification". So, having introduced built-in functions both defined in the spec and not, it would be reasonable to think that subsequent references to "built-in functions" without qualification include both.
Sure they are. I said as much in my previous comment.
Yup.
Are you saying that the current definition of "built-in" allows you to classify them that way, or that you would like it to have a definition that allows you to classify them that way? |
Yes. Or: it could at least be misunderstood so. The current spec does (wrongly imo) call proxies and arrays "built-in objects", and I guess the definition "specified and supplied by the implementation" could reasonably be construed to also mean iterator result objects and property descriptor objects. But this stretch is what makes the current definition rather useless.
Yes, that was particular to 10.3.1 and 10.3.2. They have gaping holes that say "fill in the actual algorithm here" :-) But you're right:
I knew you'd call me out on that - I noticed but I can't come up with a good definition for this "behaviour". Of course even ordinary, user-defined ECMAScript function objects do have a [[Call]] method with an algorithm that is spelled out in the specification (namely, to interpret the source code of the function).
Oh, good call!
Hm, yeah.
So would you just not count these as built-in functions?
I would like to have a term with a definition that would classify them that way. I thought "built-in" would be that term, but would also be happy to call them "native" instead or something like that. |
Yeah, I'm doubtful I'd be able to either.
Right, so its
(Ah, sorry, when you said "provide", you meant as built-ins (or, to avoid the problematic term, as intrinsics). I had something else in my head when I said "Sure they are".) As I understand it, if an implementation provides an exotic intrinsic function that doesn't conform to 10.3.1/2, then that's a non-conforming implementation. (So whether I'd count that function as "built-in" is kind of beside the point. I guess if it's a non-conforming implementation, they can call it whatever they like.) More practically, I wonder if conforming to 10.3.1/2 is much of a burden. It seems like sort of the minimum housekeeping for the function call to make sense.
Note that I'm claiming that, that's just how it seems to me sometimes. (That clarification is more for the benefit of someone dipping into the conversation at this point.) Some history: The term "built-in object" has been in the spec since ES1. Up to and including ES5.1, the definition included the phrase "that is present at the start of the execution of an ECMAScript program". ES6 dropped that phrase from the definition and introduced "anonymous built-in functions" that are created (if at all) in response to the execution of user code.
(See also #1278.) |
I was thinking of something like a
Oh, that's an extra source of confusion. So "built-in" basically did mean "intrinsic" until ES5! Now, how do we resolve this situation? Would you accept a pull request where I try to straighten this out? Do we need to involve anyone else from the committee? Or is it deemed unnecessary to change the specification for this? |
Yeah, I don't think that's a problem. The within-standard analogy is
Yeah, the distinction we now have between "built-in" and "intrinsic" wasn't really needed until ES6, I think.
It's not up to me to accept or reject, though I'd probably have comments. If you're only straightening out terminology, then you'd theoretically only need approval from the editors. |
Ok, so yes you don't consider these to be built-in. They would be "native" (with implementation-defined behavior) functions though?
Good! Then I'll wait for comments from the editors whether they consider this to be a problem worth fixing before drafting a PR. |
(On second thought, it's tricky. One could try to argue that (e.g.) a bound function's
Presumably you would define "native" so that they are. Note that the spec has used the term "native" in the past, with a different meaning. From ES1 to ES5.1, it went something like:
(Not that that precludes a new definition of "native", it's just maybe worth mentioning, so that it's not a source of confusion.)
You might want to re-state your current understanding of the problem(s), so that people can get that without reading the whole preceding discussion. |
Ah right, that's the dichotomy I remember. I had wanted to check in which revision exactly these definitions changed, didn't get to it until now - it was ES6 apparently. So yeah, maybe re-defining "native" is not the best idea.
I suggest the following editorial changes:
I suggest the following changes with possible normative impact:
|
While writing this StackOverflow answer, I was not quite certain about the definition of built-in objects:
I've tried to dichotomise them with "user-defined objects", where the built-ins are created by the implementation at startup, providing the environment that user code can interact with, and the user-defined ones are constructed by user code at runtime.
In #1540 I also found the related terms primordial and intrinsic as defined at https://github.com/tc39/how-we-work/blob/master/terminology.md, which basically mean "standard builtins" (built-in objects required by the ECMAScript standard) according to my understanding.
However, what confused me is the section 10.4 "Built-in Exotic Object Internal Methods and Slots":
Either my understanding of built-in objects as statically created intrinsics is wrong, or this really should say "standard objects" not "built-in objects". Bound functions, Array instances, String instances, arguments objects and typed array instances are all constructed at runtime, by user code. I would not classify them as built-in objects? I think they should be named "standard exotic objects".
The only exception in this section would be Immutable Prototype Exotic Objects, where
%Object.prototype%
is indeed a builtin (but still a standard exotic built-in object), and Module Namespace Exotic Objects, which cannot be constructed by user code.(I'm also missing proxy exotic objects under 10.4, no idea why they got a separate section 10.5)
The title of the section "Built-in Exotic Object Internal Methods and Slots" has an ambiguity where "built-in" may refer to either the "exotic object" or to the "internal methods and slots". The latter are indeed built-in, just like there are also "built-in types" or "built-in operators" in the spec, but I'd change it to "Standard …" either way (or omit it altogether). The adjective "Standard" has also been brought up here when discussing 10.3 "Built-in Function Objects".
Or is my understanding completely wrong, and the term "built-in objects" actually does mean to include arrays, bound functions etc, as they are "specified and supplied by an ECMAScript implementation"? But what does count as a non-built-in object then? Is any object supplied by a call to
OrdinaryObjectCreate
also a built-in object?The text was updated successfully, but these errors were encountered: