Giter Club home page Giter Club logo

Comments (10)

bergus avatar bergus commented on June 2, 2024

It means "If Type(x) is Object", as we are talking about spec-level semantics here. There is no other meaning of "object" that could be relevant in this context.

The "or function" addendum was put there as a gentle reminder that all functions are objects as well, i.e. that the callability of x doesn't matter.

Your (4) expression is an implementation of the predicate, but not more than that. There are many other possible implementations, and none should be used in the specification.

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

@bergus, thanks for your reply and helpful links.

I know your wikipedia link was at least half-joking, but I do want to point out in seriousness that there are at least 3 different meanings of "object" in the context of javascript, and it doesn't look to me like the ECMAScript 2105 spec is very successful at sorting them out.

It means "If Type(x) is Object", as we are talking about spec-level semantics here. There is no other meaning of "object" that could be relevant in this context.

Perhaps that's true, but it's not at all obvious to me, even after you pointed it out and after I've gone over sections 4 and 6 of the ECMAScript spec to which you referred. In particular, my (1) and (2) still look like pretty good guesses to me, aside from the fact that the compliance test suite flunks them (which could actually be a bug in the test suite, for all I know).
I doubt I'm alone in this, among your intended audience of promise implementers.

Your (4) expression is an implementation of the predicate, but not more than that. There are many other possible implementations,

I'd be interested to see some of the "many other possible implementations" you have in mind, if you care to share. I only know of (4), and I got that by fumbling around in the dark til the test passed.

and none should be used in the specification.

Can you say more about why you feel that none of them should be mentioned? From my point of view, spelling out one of them for definiteness sure sounds like a good thing-- it would have saved me a substantial amount of time and aggravation.

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

Actually, my reading of Table 35 is that my (4) is not a valid test for the Object type after all, despite the fact that the compliance test suite passes it. The reason I believe (4) isn't valid is that, according to the last line of that table, if x is an "Object (non-standard exotic and does not implement [[Call]])" it might be that typeof(x) is "foobar". In that case (4) will wrongly conclude x is not an Object.
Please confirm.

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

In fact, it looks to me like Table 35 completely nails down the relationship between Object-ness and the typeof operator.
This appears to be more solid than I previously thought.

So, it looks to me like the following is a (the?) correct test for Object-ness:

x !== null &&
typeof x !== "undefined" &&
typeof x !== "boolean" &&
typeof x !== "number" &&
typeof x !== "symbol" &&
typeof x !== "string"

Assuming I have that right so far,
this is the only correct test for Object-ness that I know of at this time: my (1),(2),(3),(4) are all wrong, the compliance test suite's characterization is wrong, and I'll go out on a limb and say that I suspect some or all of the other "many possible implementations" that @bergus has in mind are wrong too. Of course I'm willing to be proven wrong :-)

It may be that there is an alternative implementation that uses instanceof in some way;
I don't know since I got lost trying to follow the discussion of instanceof in the ECMAScript spec.

from promises-spec.

bergus avatar bergus commented on June 2, 2024

I had Object(o) === o in mind, which is the other (next to 4) idiomatic test for object-ness in JavaScript. That they differ about special host objects doesn't really matter, because host objects which overwrite their typeof behaviour don't want to be recognised as objects.

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

@bergus thanks for the example. Yes, it looks to me like Object(o)===o is a correct test, according to the MDN doc:

The Object constructor creates an object wrapper for the given value.
If the value is null or undefined, it will create and return an empty object,
otherwise, it will return an object of a Type that corresponds to the given value.
If the value is an object already, it will return the value.

More material here: http://stackoverflow.com/questions/8511281/check-if-a-value-is-an-object-in-javascript . In particular, Oriol correctly points out that my proposed test using instanceof from above (2 comments ago), while correct, isn't as good as your Object(o)===o since mine will break if a future standard introduces a new primitive type.

Idiomatic (I guess that means "commonly used"?) or not, (4) is simply wrong according to the ECMAScript spec that you claim to be following.
Since you're insisting that promise/A+ spec's object means ECMAscript spec's notion of Object from part 6, and that's the only thing it could possibly mean, don't you think you should actually adhere to that definition? Otherwise it keeps looking like you're making up rules and exceptions as you go along
and then expecting people to read your mind.

That they differ about special host objects doesn't really matter, because host objects which overwrite their typeof behaviour don't want to be recognised as objects.

That sentence really doesn't hold up very well at all.
Two immediate objections:
(I) Such objects don't want that? Really? All of them? That's a bold thing to say, isn't it? I admit I'm not familiar with the context we're talking about, but it seems really odd to be making a claim about the wants of every object fitting this description that anyone might ever write, so I'm skeptical.
(II) If indeed you're right that some/most/all such objects don't want to be recognized as objects (which I read as "want to be treated as non-objects" per common English usage), then won't they be disappointed when your test Object(x)===x correctly identifies them as objects? Especially ones that also happen to be thenables, which will find that different promise libraries actually treat them differently.

Don't you think it would be better to actually follow and enforce the definition of Object that you're citing, instead of coming up with reasons to do some other thing based on presumptions of what all pathological objects want and shaky logic? The definition is actually looking fairly clear to me now, to my surprise.

I believe it's clear at this point that (4) simply fails to comply with the promises/A+ spec,
while the compliance suite lets it pass.
This inconsistency could be resolved in one of two ways:
(A) fix the compliance suite so that it correctly flunks (4), as required by the spec,
or,
(B) change the spec to allow (4), so that it will agree with the compliance suite.
I don't have a preference.

In any case, I'd also strongly recommend addressing the original issue, as follows:

  • Mention (perhaps even recommend) Object(x)===x. There are evidently lots of ways to do it right and lots of ways to do it wrong; mentioning this simple right way would be significantly helpful in guiding implementers toward success.
  • Also mention that "object" is being used as in the ECMAscript spec section 6. That's nowhere near as obvious as you've made it out to be, to many of the people of varying levels of javascript expertise who make up your audience. Referring to the ECMAscript spec would go a long way towards clearing the fog, as it did when you linked to it in this thread.

from promises-spec.

bergus avatar bergus commented on June 2, 2024

These objects you are talking about are ignored because they're basically non-existent. They are absolutely non-standard, and while the ES spec does permit them it explicitly discourages implementations from using them.
This is also the reason why the compliance suite doesn't test them: there's no way to create such an object in node.js.

The only examples that come to my mind are document.all and some host objects from the IE7 era (like ActiveX), which were also known for not returning "function" despite being callable. Nobody gives a f*** about them, and none of them is thenable anyway.

The other reason why x != null && (typeof x == "object" || typeof x == "function") is commonly used over Object(x) === x is that it is significantly faster, not involving a global function call.

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

@bergus, thanks, good to know all these things.

Well, I guess flunking (4) isn't really an option then. In that case it would be great if the spec could be changed to match the suite. Not that I give a f*** about those objects, it's just that if there wasn't this apparent hole in the logic, it would have saved me from worrying or thinking much about it; likewise for others in my position in the future, and people out on the web who are trying to make sense of the spec.

In chrome: document.all.then = function(){}. Now it's a thenable. :-) Whatever.

Yeah, the lack of any efficient bulltetproof way to ask is-an-object is pretty bizarre.
And, isn't Object(x) more than just a function call-- it actually creates a new object in memory (in the case x wasn't an object), right? That sounds like quite a big deal for something that should be a lightweight check; but maybe it's not as big a deal in javascript as it is in C++, I'm not sure. On the other hand I suppose a javascript compiler/interpreter could optimize Object(x)===x into something that's even more efficient than x != null && (typeof x == "object" || typeof x == "function"), couldn't it?

from promises-spec.

donhatch avatar donhatch commented on June 2, 2024

Actually... it looks like document.all isn't an example of the last line of Table 35 for which typeof doesn't return "object".
From typeof doc on MDN:

All current browsers expose a non-standard host object document.all with type Undefined.
    typeof document.all === 'undefined';
Although the specification allows custom type tags for non-standard exotic objects,
it requires those type tags to be different from the predefined ones.
The case of document.all having type tag 'undefined' must be classified as an
exceptional violation of the rules.

So, as far as I know, neither nodejs nor chrome has any way of creating an object whose behavior is described by the last line of Table 35 and whose typeof doesn't return "object". Basically non-existent, as you say.

from promises-spec.

gowpen avatar gowpen commented on June 2, 2024

I second @donhatch that this should be specified. The definition of thenable aims directly at specifying duck typing tests:

2.3. It introduces the term “thenable” as distinct from “promise”, so as to more precisely talk about the duck-typing tests necessary for implementation interoperation.

The definition uses this language:

1.2. “thenable” is an object or function that defines a then method.

Yet how to correctly detect "is an object or function" is left unclear. Referencing abstract operations in the ECMAScript spec is reasonable, and if that's the intention it should be explicit.

from promises-spec.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.