make Type(...) macro an AO and return a spec enum
The usage of Type(...) in the spec is quite strange and doesn't follow our usual editorial conventions. I would prefer if we just made it a regular AO and had it return spec enums, which can be more comfortably passed around and compared than the built-in constructor or whatever it is that is returned today. Also, we won't have to think about realm weirdness.
And the link to the definition of Type (it links to https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values) doesn't explain what it will return very clearly. (e.g. I don't know if Type(null) is null or object at the first glance)
I believe there was at least one usage where the x of Type(x) wasn’t guaranteed to be a language value. I’m using past tense because I can’t find it now and it may have been removed. OTOH, it was pretty well-hidden because the comparisons were always to language types (e.g. if Type(x) is Object), so I could just be missing it now. The current definition of Type() permits this (vaguely), so I don’t think it was a bug, but I’m guessing a clean up would want to eliminate non-language-type usage if it is till lurking out there somewhere...
@Jack-Works it returns "Null" for that, unambiguously.
@bathos that seems like it'd be an editorial error for a Type AO.
Note that most uses of Type() could be easily eliminated. E.g., replace:
If Type(_v_) is String
with:
If _v_ is a String
However, there are a few places where it wouldn't be as easy, e.g.
If Type(_next_) is not an element of _elementTypes_If Type(_x_) is different from Type(_y_)If Type(_nx_) is the same as Type(_ny_)
@bathos:
I believe there was at least one usage where the
xofType(x)wasn’t guaranteed to be a language value.
In SetFunctionName, there's a Type(_name_), where _name_ could be a Private Name, which is not a language value. (But that case disappears if you perform the above replacement.)
There are also some cases like Type(_completionRecord_.[[Value]]) where the argument might be ~empty~, although it's possible that you could prove (in those particular cases) that it can't be.
Whether it's an editorial error to pass a spec value to a Type AO would depend on whether the AO is written to accept language values or all values. I agree that restricting it to just language values would be preferable, but ensuring that a spec value is never passed to it might take some diligence.
Note that most uses of
Type()could be easily eliminated. E.g., replace:
If Type(_v_) is Stringwith:
If _v_ is a String
I just noticed that we actually already do that in a few places. Search for ]] is a String.
By my count, we use that phrasing about 270 times in algorithms. (A quarter of that is all the times we say _foo_ is an abrupt completion.)
And we used to have even more before PR #2483 hoisted parameter-assertions into parameter-types. E.g. some occurrences of
Assert: _param_ is a String.
became
_param_: a String
@jmdyck thanks for confirming usage with non-language-values does currently exist! When I didn’t find any earlier myself, I started to wonder if I'd only imagined seeing them before.
I agree that restricting it to just language values would be preferable, but ensuring that a spec value is never passed to it might take some diligence.
Main reason I’d like to see the AO-ified Type() “drop support” for spec types is that the base disjunct spec types tend not to constitute categories of values that really need to be thought of as such. Members of the hypothetical “value space” of the Record type (“spec Record type,” I mean ... Specord?*) for example don’t share semantics so much as notation and whether a Completion Record and an Object Environment Record are of one type or two is a sort of tree-falls-in-the-forest question that doesn’t need to be answered. The current non-AO description of Type() implies it “could” answer that question, which is confusing.
* At least there’s no Spoople spec type.
Opened #3339. I'd appreciate a review from anyone in this thread.