News for hackers. Stuff that matters.
Re:A one-line package broke `npm create-react-app` by chvid on Saturday April 25, 2020 @01:17PM (#22979544)
And the source code of the library is:

   function isPromise(obj) {
     return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';
   }
Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @01:36PM (#22979707)
Here's my off-the-cuff take that will not be popular.

A function like this should be a package. Or, really, part of standard js, maybe.

A) The problem it solves is real. It's dumb, but JS has tons of dumb stuff, so that changes nothing. Sometimes you want to know "is this thing a promise", and that's not trivial (for reasons).

B) The problem it solves is not straightforward. If you Google around you'll get people saying "Anything with a .then is a promise' or other different ways of testing it. The code being convoluted shows that.

Should this problem be solved elsewhere? Sure, again, JavaScript is bad and no one's on the other side of that argument, but it's what we have. Is "just copy paste a wrong answer from SO and end up with 50 different functions in your codebase to check something" like other languages that make package management hard so much better ? I don't think so.

Re:A one-line package broke `npm create-react-app` by forty on Sunday April 26, 2020 @04:54AM (#22985667)
No. There is no reason why it should be a package by itself. It should be part of a bigger util package, which which is well maintained, tested, and with many maintainers actively looking at it, with good processes, such as systematic code reviews, etc.

At work, our big webapp depended at some point indirectly on "isobject" "isobj" and "is-object", which were all one liners (some of them even had dependencies themselves!!). Please let's all just depend on lodash and it will actually eventually reduce space and bandwith usage.

Re:A one-line package broke `npm create-react-app` by therealdrag0 on Monday April 27, 2020 @12:44PM (#22997483)
Yep, in Java-land this would be in an Apache Common's (or Guava, etc) module with dozens and dozens of other useful functionality.
Re:A one-line package broke `npm create-react-app` by drinchev on Saturday April 25, 2020 @03:21PM (#22980588)
Yeah, but the question is how far should we go with that. Should we do :

    const isFalsy = require("is-falsy");
    const isObject = require("is-object");
    const isFunction = require( "is-function" );
    const hasThen = require( "has-then" );

    function isPromise(obj) {
      return !isFalsy(obj) && ( isObject(obj) || isFunction(obj) ) && hasThen( obj );
    }
Just because the code line is more than 50 characters, doesn't mean that we need a new library for that.
Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @05:40PM (#22981783)
All of those can be pretty much be handled natively, and obviously. They're all primitive

isFalse would be != isObject would use typeOf isFucntion would use typeOf

Where a library becomes helpful is when you have:

* A real problem (none of those are real problems, and the npm packages for them are essentially unused jokes)

* A solution that is not intuitive, or has a sharp edge, or requires non-obvious knowledge, or does not have a preexisting std approach

Checking for a promise, given the constraints of having multiple types of promises out in the world, falls into both of those. Checking if something is falsey, when Javascript provides !, does not fall into either.

Re:A one-line package broke `npm create-react-app` by enitihas on Saturday April 25, 2020 @03:28PM (#22980669)
I think all of the above might already be libraries on npm. From what I remember, npm has isInteger, isPositive, is-odd, is-even.
Re:A one-line package broke `npm create-react-app` by recursive on Saturday April 25, 2020 @03:48PM (#22980831)
All of the packages you mentioned are maintained by the same guy.
Re:A one-line package broke `npm create-react-app` by sergiotapia on Saturday April 25, 2020 @07:59PM (#22982793)
Have you seen his twitter? It's incredibly cringey. I don't understand how someone could be so arrogant to claim millions of companies use his software, when his software is isFalse. Not to mention his hundreds of packages that literally just output an emoji.
Re:A one-line package broke `npm create-react-app` by artificial on Sunday April 26, 2020 @02:15AM (#22984972)
Reminds me of Dr. Evil’s monologue about his Father making ridiculous claims about inventing the question mark.
Re:A one-line package broke `npm create-react-app` by dragonwriter on Saturday April 25, 2020 @03:30PM (#22980681)
isFalsy is just “!”; I don't think we need a new library for a more verbose way to express a one-character unary operator, no, nor does it meet the standard of “The problem it solves is not straightforward” proposed upthread.
Re:A one-line package broke `npm create-react-app` by drinchev on Saturday April 25, 2020 @03:35PM (#22980728)
Re:A one-line package broke `npm create-react-app` by dragonwriter on Saturday April 25, 2020 @04:22PM (#22981122)
I'm not surprised it exists (and literally is just a more verbose, indirect way to invoke “!” that nevertheless is a 17 sloc module with a bunch of ancillary files that has one direct and, by way of that one, 17 second-order and, while I didn't check further, probably an even more ridiculous number of more distant, transitive dependendencies.)

I'm just saying it's neither necessary nor consistent with the standard for when a library is a good idea proposed upthread, so suggesting it as part of an attempt at reductio as absurdam on that standard is misplaced.

Re:A one-line package broke `npm create-react-app` by magicalist on Saturday April 25, 2020 @04:35PM (#22981225)
> 0 Dependents

if a tree falls in the woods...?

Re:A one-line package broke `npm create-react-app` by kemitchell on Saturday April 25, 2020 @08:40PM (#22983078)
> Weekly Downloads > > 0

as of 2020-04-26T00:39+00:00

Re:A one-line package broke `npm create-react-app` by drngdds on Saturday April 25, 2020 @03:35PM (#22980730)
>Or, really, part of standard js, maybe.

I think this would be the solution. I feel like a lot of the NPM transitive dependency explosion just comes from the fact that JavaScript is a language with a ton of warts and a lack of solid built-ins compared to e.g. Python. Python also has packages and dependencies, but the full list of dependencies used by a REST service I run in production (including a web framework and ORM) is a million times smaller than any package-lock.json I've seen.

Re:A one-line package broke `npm create-react-app` by jdminhbg on Saturday April 25, 2020 @04:55PM (#22981409)
This is correct. I post the same thing every time one of these JS dependency hell issues pops up, but it's the case because it's true: The problem is the lack of a standard library. It's not that people don't know how to write a left-pad function, it's that it's dumb to rewrite it in every project and then remember what order you put the arguments in, etc. So people standardize, but they're standardizing on millions of different little packages.

I think the effort that goes into all the JS syntax and module changes would be better put into developing a solid standard library first.

Re:A one-line package broke `npm create-react-app` by galoisgirl on Monday April 27, 2020 @07:12AM (#22994743)
There's a rich standard library, you don't need a package to left-pad.
Re:A one-line package broke `npm create-react-app` by alerighi on Saturday April 25, 2020 @02:30PM (#22980124)
Lile...

    x instanceof Promise 
It works for standard promises, sure there are non standard promises, ancient stuff, that to me shouldn't be used (and a library that uses them should be avoided). So why you need that code in the first place?

Also that isPromise function will not work with TypeScript, imagine you have a function that takes something that can be a promise or not (and this is also bad design in the first place), but then you want to check if the argument is a Promise, sure with `instanceof` the compiler knows that you are doing, otherwise not.

Also, look at the repo, a ton of files for a 1 line function? Really? You take less time to write that function yourself than to include that library. But you shouldn't have to write that function in the first place.

Re:A one-line package broke `npm create-react-app` by exogen on Saturday April 25, 2020 @05:41PM (#22981795)
Your implementation is broken even if everything uses native Promises. I don't know how many times this exact thread needs to happen on HN (as it has many times before) until people realize their "no duh" implementations of things are actually worse than the thing they're criticizing.

Make an iframe.

In the iframe:

    > window.p = new Promise(() => {});
From the parent window:

    > window.frames[0].p instanceof Promise
    false
Congrats! Your isPromise function was given a Promise and returned the incorrect result. The library returns the correct result. Try again!
Re:A one-line package broke `npm create-react-app` by suyjuris on Saturday April 25, 2020 @06:33PM (#22982204)
In case someone else is also confused by this, it seems that instanceof checks whether the objects prototype matches, and these prototypes are not shared across different contexts, which iframes are [0]. (Though I would still like to know why it works like this.)

[0] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re:A one-line package broke `npm create-react-app` by odensc on Saturday April 25, 2020 @07:03PM (#22982427)
For security reasons - you can modify the prototypes and you wouldn't want iframes to inherit that.
Re:A one-line package broke `npm create-react-app` by stagas on Sunday April 26, 2020 @02:24AM (#22985002)
No, it was not given a Promise. It was given a foreign object from another window. If you want to inspect another window you should not be reusing code that is designed for single threaded operations. Instead, have a layer that translates, serializes, or explicitly defines an interface that the objects we are dealing with are foreign and need to be transformed. Then the abstraction implementation details of dealing with multiple windows become a concern of a single layer and not your entire codebase. Implicitly and magically treating a foreign window as this window, will fail in many subtle and unknown ways. The "brokenness" you mention is not in that implementation, it is correctly breaking, telling you that what you are doing is wrong, then you try to bypass the error instead of fixing your approach.
Re:A one-line package broke `npm create-react-app` by exogen on Sunday April 26, 2020 @01:10PM (#22988504)
For foreign-origin iframes, that's exactly what people do using `postMessage`. But for same-origin iframes there's no need since you can access the iframe's context directly. So people can (and do) write code exactly like this that accesses data directly.

And it was given a Promise. You just shouldn't use instanceof in multi-window contexts in JavaScript. This is why built-ins like `Array.isArray` exist and should be used instead of `arr instanceof Array`. Maybe you'd prefer to write to TC39 and tell them that `Array.isArray` is wrong and should return false for arrays from other contexts?

There's no use jumping through hoops to avoid admitting that OP made an error. They were wrong and didn't think of this.

Re:A one-line package broke `npm create-react-app` by foepys on Sunday April 26, 2020 @03:02AM (#22985171)
GP's comment screams XY problem which seem to be increasingly common these days.
Re:A one-line package broke `npm create-react-app` by exogen on Sunday April 26, 2020 @01:44PM (#22988732)
If you think pointing out a bug due to an edge case someone didn't think of is the XY problem, I'm afraid you don't know what the XY problem is.
Re:A one-line package broke `npm create-react-app` by foepys on Sunday April 26, 2020 @03:42PM (#22989601)
The problem was to get the promise out of the iframe when you shouldn't do this directly in the first place.

This literally is an XY problem: "I need to do A but it's giving me bad results, what do I need to add?" - "Don't use A, it's bad practice. Use B instead and keep using built-in tools instead of hacking something together" In this case use instanceof instead of is-promise because it's a hack around the actual problem of getting objects out of a different context that was explicitly designed to behave this way.

I'm afraid that you don't know what an XY problem is.

JavaScript developers always seem to think they are the smart ones after their 6 weeks of some random bootcamp and then you end up with some crap like NPM where a single line in a package out of hundreds maintained by amateurs can break everybody's development environment.

[dead]
Re:A one-line package broke `npm create-react-app` by dang on Tuesday April 28, 2020 @01:26AM (#23003696)
Yikes, please don't break the site guidelines like this.

https://news.ycombinator.com/newsguidelines.html

Re:A one-line package broke `npm create-react-app` by foepys on Monday April 27, 2020 @01:01AM (#22993018)
I didn't even mean you but the general JS community but if you want to think I did, okay, feel free to do so.
Re:A one-line package broke `npm create-react-app` by hombre_fatal on Saturday April 25, 2020 @09:46PM (#22983520)
Though, let's also appreciate just how niche that case is. I'd be surprised if more than 0.5% of the JS devs reading this will ever encounter that scenario where they are reaching across VMs like that in their life.

`obj instanceof Promise` and `typeof obj.then === 'function'` (is-promise) are much different checks. Frankly, I don't think either belongs in a library. You should just write that code yourself and ponder the trade-offs. Do you really just want to check if an object has a then() method or do you want to check its prototype chain?

Re:A one-line package broke `npm create-react-app` by __s on Saturday April 25, 2020 @03:10PM (#22980504)
TypeScript supports 'function f(x: any): x is T' as a way to declare that if f returns true, x may pass as type T

https://www.typescriptlang.org/docs/handbook/advanced-types....

Re:A one-line package broke `npm create-react-app` by cyral on Saturday April 25, 2020 @10:15PM (#22983722)
This package has an index.d.ts file that utilizes exactly this.
Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @02:43PM (#22980263)
1) I'm not defending the implementation of is-promise. I don't care to, I'm not a javascript developer.

2) > sure there are non standard promises, ancient stuff, that to me shouldn't be used

If you're building a library, or maintaining one that's been built over many years, you can't easily make calls like that.

Re:A one-line package broke `npm create-react-app` by dragonwriter on Saturday April 25, 2020 @03:26PM (#22980649)
> If you're building a library, or maintaining one that's been built over many years, you can't easily make calls like that.

Well, you can, and in the JS ecosystem you'll often find cases where there are two libraries (or two broad classes of libraries) for a certain function that make different choices, one of which makes the simple, modern choice that doesn't support legacy, and one that does the complex, messy thing necessary to deal with legacy code, and which you use depends on your project and it's other constraints.

Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @05:42PM (#22981807)
OK, then the legacy library can't easily make that choice. I'm not saying every single javascript developer should be accepting async or sync callbacks, just that some libraries are choosing to do that for legitimate reasons.
Re:A one-line package broke `npm create-react-app` by cyral on Saturday April 25, 2020 @10:14PM (#22983715)
Are you saying that this isPromise package will not play well with TypeScript? One of those files (index.d.ts) solves the TypeScript problem using type predicates. TypeScript WILL know that the object is a promise if it returns true.
Re:A one-line package broke `npm create-react-app` by grumple on Saturday April 25, 2020 @05:00PM (#22981439)
This function should absolutely NOT be a package. The problem is that JS has a very minimal standard library and despite tons of money going into the system, nobody's had the good sense to take a leadership role and implement that standard. In other languages you don't need to include external packages to determine the types of objects you're dealing with, or many other things.
Re:A one-line package broke `npm create-react-app` by detaro on Saturday April 25, 2020 @05:01PM (#22981455)
And there's an interesting discussion to be had if it shouldn't be one of those snippets that everyone copies from Stackoverflow instead. And how much trouble in other ways that alternative has caused.
Re:A one-line package broke `npm create-react-app` by jhanschoo on Saturday April 25, 2020 @03:23PM (#22980613)
I don't think it should be a package.

One-liners without dependencies like this should live as a function in a utility file. If justification is needed, there should be a comment with a link to this package's repo.

Re:A one-line package broke `npm create-react-app` by Pfhreak on Saturday April 25, 2020 @03:45PM (#22980804)
What's the difference between a utility file and a package? That seems like a distinction without a difference to me.

If you use the same one liners in more than one project and you copy that utility file over, the line gets even fuzzier.

Re:A one-line package broke `npm create-react-app` by Ndymium on Saturday April 25, 2020 @04:39PM (#22981259)
The utility file will never be updated and break your build without you doing it yourself.
Re:A one-line package broke `npm create-react-app` by hombre_fatal on Saturday April 25, 2020 @09:43PM (#22983500)
Also you can just read the code the same way you read any other code. And since it's in your codebase and git diffs, you will read it.

Because the implementation detail of is-promise actually is important. It just checks if an object has a .then() method. So if you use it, it's just as important that you know the limitation.

Not everything needs to be swept under the rug.

Re:A one-line package broke `npm create-react-app` by darekkay on Sunday April 26, 2020 @05:32AM (#22985839)
Also: The utility file will never be updated and fix existing issues within the utility itself (unless you look up the package and diff it yourself). It's a trade-off.
Re:A one-line package broke `npm create-react-app` by jhanschoo on Sunday April 26, 2020 @07:40AM (#22986404)
As the commenter who suggested keeping it in a utilities file, I'd say that the trade-off is heavily weighted to not importing it as a package.

When you cribbed the code you should have completely understood what exactly the package was doing, and why, and known what issues it would have had. Since it's a one-liner, it is transparent. Since it is without dependencies, it is unlikely to fail on old code. So it's unlikely to have existing issues and unlikely to develop new issues.

Of course, if you end up using new features of the language in your code, it may fail on that, but the risk old stuff failing should have already been factored in when you decided to upgrade. In fact, the one-liner solves this better since you decide the pace of adaptation of your one-liner to the new features, not the package maintainer.

Re:A one-line package broke `npm create-react-app` by darekkay on Sunday April 26, 2020 @08:59AM (#22986830)
That's the trade-off I would most likely take in the "isPromise" case. But the opening question was a generic one ("What's the difference between a utility file and a package"), so the answer should reflect both sides.
Re:A one-line package broke `npm create-react-app` by degraafc on Saturday April 25, 2020 @01:40PM (#22979731)
I'd say that it should rather be a part of the type system. Some kind of `obj isa Promise` should be the way to do this, not random property checks. But that's JS...
Re:A one-line package broke `npm create-react-app` by kroltan on Saturday April 25, 2020 @01:50PM (#22979790)
The thing is that there is the Promise "class", which is provided by the environment, but there is a interface called PromiseLike, which is defined as having a method called then that takes one or two functions. Now, JS doesn't have nominal typing for interfaces, so you have to do "random property checks".

Typescript partially solves that by declaring types, but if you have a any variable, you still need to do some probing to be able to safely convert it to a PromiseLike, because TypeScript goes to great lengths to not actually produce physical code on its output, attempting to be just a type checker.

Perhaps if TS or an extension allowed "materializing" TS, that is `value instanceof SomeInterface` generated code to check for the existence of appropriate interface members, this could be avoided, but alas, this is not the case.

Re:A one-line package broke `npm create-react-app` by ehsankia on Saturday April 25, 2020 @01:59PM (#22979882)
shouldn't it then be called is-promise-like? Also, if you're being loose about it anyways, can't you simply just go for `if (obj && typeof obj.then == 'function')` and call it a day? I'd say that's short enough to include your own version and not rely on a package for.

I think that module over complicates it as it is, and most people don't need that level of complication in their code.

Re:A one-line package broke `npm create-react-app` by zbentley on Saturday April 25, 2020 @03:20PM (#22980586)
> Perhaps if TS or an extension allowed "materializing" TS, that is `value instanceof SomeInterface` generated code to check for the existence of appropriate interface members, this could be avoided

It's not perfect and a bit of a bolt-on, but io.ts works reasonably well in this area:

https://github.com/gcanti/io-ts

Re:A one-line package broke `npm create-react-app` by odensc on Saturday April 25, 2020 @01:43PM (#22979750)
In theory `x instanceof Promise` would work, but the reason for this package is that there are many non-standard Promise implementations in the JS world.
Re:A one-line package broke `npm create-react-app` by exogen on Saturday April 25, 2020 @05:43PM (#22981814)
It wouldn't work even if everything were native – see my reply above.
Re:A one-line package broke `npm create-react-app` by odensc on Saturday April 25, 2020 @07:02PM (#22982421)
That applies for browsers, yes (though I'd argue is a rare edge-case), but create-react-app is a Node.js application.
Re:A one-line package broke `npm create-react-app` by exogen on Saturday April 25, 2020 @08:10PM (#22982869)
create-react-app isn't even using is-promise directly. It's several hops in the dependency graph away.
Re:A one-line package broke `npm create-react-app` by city41 on Saturday April 25, 2020 @03:40PM (#22980762)
Promises were not always part of the standard and for many years were implemented in user space, by many different implementations. Using duck typing like this was the only way to allow packages to interact with each other, as requiring an entire stack to say only use Bluebird promises is not realistic at all.
Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @01:42PM (#22979743)
I'm totally with you on this. It's dumb that this is a problem but it is actually a problem.
Re:A one-line package broke `npm create-react-app` by Thorentis on Sunday April 26, 2020 @12:41AM (#22984493)
I think you're on the right track. We all (I hope) agree that stuff like this should be standardized. But that's not the same as "should be a package".

At the very least, W3, or Mozilla Foundation, or something with some kind of quasi-authority should release a "JS STD" package that contains a whole bunch of helper functions like this. Or maybe a "JS Extras" package, and as function usage is tracked across the eco-system, the most popular/important stuff is considered for addition into the JS standard itself.

Having hundreds of packages that each contain one line functions, simply means that there are hundreds of vectors by which large projects can break. And those can in turn break other projects, etc.

The reason, cynically, that these all exist as separate packages, is because the person who started this fiasco wanted to put a high a download count as possible on his resume for packages he maintains. Splitting everything up into multiple packages means extra-cred for doing OSS work. Completely stupid, and I'm annoyed nobody has stepped up with a replacement for all this yet.

Re:A one-line package broke `npm create-react-app` by devit on Saturday April 25, 2020 @03:32PM (#22980699)
A function like this should not be something that anyone even thinks of writing or using.

In properly designed languages, values have either a known concrete type, or the interfaces that they have to support are listed, and the compiler checks them.

Even in JavaScript/TypeScript, if you are using this, you or a library you are using are doing it wrong, since you should know whether a value is a promise or not when writing code.

Re:A one-line package broke `npm create-react-app` by city41 on Saturday April 25, 2020 @03:38PM (#22980744)
This function is most likely an artifact of before promises got standardized. One way promises took off and became so ubiquitous is different implementations could interop seamlessly. And the reason for that is a promise was defined as 'an object or function having a then method which returns a promise when called'.

Doesn't excuse the JS ecosystem and JS as a whole, which truly is a mess. But there's a history behind these things.

Re:A one-line package broke `npm create-react-app` by stefan_ on Saturday April 25, 2020 @04:31PM (#22981198)
I think the point of the comment is: you should not be testing for this at all.

If your API works with promises, call .then() on what is handed to you. That's it. Don't make up emergent, untestable behavior on the spot.

Re:A one-line package broke `npm create-react-app` by city41 on Saturday April 25, 2020 @04:37PM (#22981238)
You need to do this test if you are creating a promise implementation. That was my point, there is a reason code like this exists.
Re:A one-line package broke `npm create-react-app` by earthboundkid on Sunday April 26, 2020 @08:07AM (#22986543)
Why would an implementation need to test for it?

ISTM that a framework may need to test for promiseness if it calls promises and functions differently, but it can and should be done as a utility in the framework, not as a separate package.

Re:A one-line package broke `npm create-react-app` by city41 on Sunday April 26, 2020 @10:22AM (#22987341)
I agree with that. I have no idea why it’s in a separate package. But I can say that about many packages :).

It’s possible to just treat everything as a promise by wrapping results in Promise.resolve() but that can have performance implications that some franeworks might want to avoid by only going down the promise route when they have to.

For promise implementations, If the callback to then() returns a promise, the promise implementation detects that and resolves that promise behind the scenes: http://www.mattgreer.org/articles/promises-in-wicked-detail/...

Re:A one-line package broke `npm create-react-app` by mikewhy on Saturday April 25, 2020 @01:48PM (#22979782)
> Or, really, part of standard js, maybe.see:

It's a part of node, at least: https://nodejs.org/docs/latest-v12.x/api/util.html#util_util...

Re:A one-line package broke `npm create-react-app` by staticassertion on Saturday April 25, 2020 @01:50PM (#22979796)
This will work for a standard Promise, which is great, but not for weirdo made up promises. It also was released, I think, in 2018.

It's one thing if you own the entire codebase, but if you're building a popular, multiple-years-old library/framework, you can't make the same assumptions.

Re:A one-line package broke `npm create-react-app` by mikewhy on Saturday April 25, 2020 @02:23PM (#22980066)
I'm only finding about it today TBH. Usually I go for what this library does:

  function isPromise(obj) {
    return typeof obj?.then === 'function'
  }
Re:A one-line package broke `npm create-react-app` by wolco on Saturday April 25, 2020 @10:38PM (#22983862)
Shouldn't a js framework exist that includes these static basic if checks in the core and offers them as a buildin method? Why load this as an external package, why not copy the code and maintain locally?
Re:A one-line package broke `npm create-react-app` by stagas on Saturday April 25, 2020 @04:06PM (#22980995)
And it doesn't even check if it's a Promise. It's violating it's own naming contract. At least it should be called: isPromiseLike? To check if something is actually a Promise all you need to do is a `foo instanceof Promise`.
Re:A one-line package broke `npm create-react-app` by exogen on Saturday April 25, 2020 @05:55PM (#22981919)
That won't work across window boundaries, since each window environment gets its own distinct version of Promise.
Re:A one-line package broke `npm create-react-app` by stagas on Sunday April 26, 2020 @02:00AM (#22984903)
Then instanceof will break for all native objects. Who writes code that checks instances across window boundaries? This is flawed beyond the idea of how to properly check an instance, it's bad architecture - the result? This post, and probably more subtle bugs surfacing along the way.
Re:A one-line package broke `npm create-react-app` by bronson on Saturday April 25, 2020 @01:32PM (#22979670)
Re:A one-line package broke `npm create-react-app` by jcelerier on Saturday April 25, 2020 @01:38PM (#22979719)
how does that make sense in any universe. Just because I have a function named "then" does not mean that my object is a promise. Maybe "then" is the name of a domain thing in my project, for instance a small DSL or something like that. arghhhhhh !
Re:A one-line package broke `npm create-react-app` by jhanschoo on Saturday April 25, 2020 @03:30PM (#22980677)
objects with a .then(...) methods are treated as though they have Promise semantics by the language

See Promise.resolve https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...

Re:A one-line package broke `npm create-react-app` by LudwigNagasena on Saturday April 25, 2020 @03:40PM (#22980764)
Consider it a special function like "__init__" in Python. I think this is one of the problems with duck typing, existence of a public function introduces possible name collision onto the whole codebase.
Re:A one-line package broke `npm create-react-app` by krapp on Saturday April 25, 2020 @01:45PM (#22979760)
It's almost as if treating a dynamically typed interpreted language as if it had static types like C++ is fundamentally broken.
Re:A one-line package broke `npm create-react-app` by ufo on Saturday April 25, 2020 @04:35PM (#22981221)
Does anyone know if it really needs the !!obj&& at the start? Isn't that redundant with checking that the type is either "object" or "function"?

And is there a reason to use '!!' inside a conditional? Wouldn't obj&& do basically the same thing?

Re:A one-line package broke `npm create-react-app` by acemarke on Saturday April 25, 2020 @04:49PM (#22981342)
Unfortunately, that's not redundant, because `typeof null` returns "object":

https://2ality.com/2013/10/typeof-null.html

Re:A one-line package broke `npm create-react-app` by megous on Saturday April 25, 2020 @05:07PM (#22981497)

    !!null && false   === false
    null && false     === null
Re:A one-line package broke `npm create-react-app` by adrianbbarkus on Monday April 27, 2020 @09:35PM (#23002374)
Irony is there's a simpler way to do it, making the library even less necessary. `const isPromise = x => Promise.resolve(x) === x`
Re:A one-line package broke `npm create-react-app` by stefan_ on Saturday April 25, 2020 @04:43PM (#22981304)
It didn't break because of the source, it broke because of all the packaging/module bullshit around it. It seems the Javascript ec(h)osystem has firmly come down on the philosophy of "make modules very easy to use, but very difficult to make (correctly)".

The predictable explosion in dependency trees has caused the predictable problems like this one. I feel I much prefer the C/C++ way of "modules are easy to make, but difficult to use".

Re:A one-line package broke `npm create-react-app` by matt2000 on Saturday April 25, 2020 @04:27PM (#22981172)
A nice one line argument for type safety.
[dead]
[dead]
Re:A one-line package broke `npm create-react-app` by smt88 on Saturday April 25, 2020 @01:36PM (#22979709)
It's not useful, interesting, or accurate to stratify people this way. You have no idea what someone's intelligence level or background is based on their usage of JS or C.

I loathe JS, but one of the best devs I know likes it. People's mileage varies.

For me personally, there's much more money in easy React products than making games. I'm not a great dev, but I'd be doing this same work even if I were.

Re:A one-line package broke `npm create-react-app` by gombosg on Saturday April 25, 2020 @01:40PM (#22979733)
I sincerely hope you're being sarcastic here.
Re:A one-line package broke `npm create-react-app` by fortran77 on Saturday April 25, 2020 @01:51PM (#22979809)
Actually VHDL / Verilog programmers are on top of the food chain.
Re:A one-line package broke `npm create-react-app` by recursive on Saturday April 25, 2020 @03:51PM (#22980867)
I don't know much about VHDL, but there seems to be a non-scientifically-measured negative correlation between the quality of candidates I've interviewed claiming VHDL experience vs. those without.
Re:A one-line package broke `npm create-react-app` by CydeWeys on Saturday April 25, 2020 @01:59PM (#22979877)
And is that reflected by their compensation, or ... ?
Re:A one-line package broke `npm create-react-app` by temac on Sunday April 26, 2020 @12:09AM (#22984334)
They will eat you.
Re:A one-line package broke `npm create-react-app` by TechBro8615 on Saturday April 25, 2020 @01:39PM (#22979722)
The “food chain?” What do you mean by that?
Re:A one-line package broke `npm create-react-app` by 2ion on Saturday April 25, 2020 @01:38PM (#22979718)
Wow just wow. So here's your new Promise object:

class World { then () { return 0; } } isPromise(new World) // true

If there really isn't a safe and better way to tell if an object is an instance of Promise…then color me impressed.

Re:A one-line package broke `npm create-react-app` by TurplePurtle on Saturday April 25, 2020 @01:58PM (#22979869)
There are custom Promise implementations (for reasons), such as bluebird.js. If you're supporting legacy browsers, there will be no standard Promise object. So the simplest way to check for the Promise contract is the code posted. But yes, in an ideal world, one would be able to just do `promise instanceof Promise`.
Re:A one-line package broke `npm create-react-app` by stagas on Saturday April 25, 2020 @04:09PM (#22981013)
These cases should really be handled at the compilation/transpilation level, since there is one, and users should just write latest generation JavaScript without these concerns.
Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @02:03PM (#22979905)
I mean, if you have to assume deliberately adversarial action on the part of your own codebase, you may have worse problems than having to duck-type promises.
Re:A one-line package broke `npm create-react-app` by gpm on Saturday April 25, 2020 @02:33PM (#22980149)
A class with a `then` method isn't a rare thing that could only come up adversarially. Below I've linked two example from the rust std-library (I just chose that language because the documentation is really easy to search for objects which have a method name then). I think we can be sure that both booleans, and the "less than, equal to, or greater than" enum are not in fact promises.

https://doc.rust-lang.org/std/primitive.bool.html#method.the...

https://doc.rust-lang.org/std/cmp/enum.Ordering.html#method....

Re:A one-line package broke `npm create-react-app` by monkpit on Saturday April 25, 2020 @03:19PM (#22980576)
Cypress.io has chainable .then functions but they are not await-able and the documentation clearly states they are not promises and cannot be treated as such. It’s a bad idea, but it is out there.
Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @03:57PM (#22980916)
I haven't used Cypress, but looking at its docs, I don't know that I'd agree its use of "then" is all that bad. I agree they'd have done better to find a different name, but this at least seems like the least possible violation of least surprise if they are going to reuse the name.

At the same time, it is intensely wild to me that their "then" is an alternative to their "should", which apparently just re-executes the callback it's given until that callback stops throwing. If your tests require to be re-run an arbitrary and varying number of times in order to pass, you have problems that need to be dealt with in some better way than having your test harness paper over them automatically for you.

Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @02:40PM (#22980227)
What do Rust idioms have to do with Javascript?
Re:A one-line package broke `npm create-react-app` by gpm on Saturday April 25, 2020 @02:46PM (#22980291)
The language has nothing to do with it. The point is just that the name "then" is a perfectly common method name.

If a small standard library is using it for things that aren't promises, you can bet your ass that there are javascript libraries using it for things that aren't promises.

Like I said, I just chose to look at rust first because it's documentation has a good search bar.

Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @02:53PM (#22980348)
The language has everything to do with it, because the language is the locus of practice. Rust practice is whatever it is, and is apparently pretty free with the use of "then" as a method name, which is fine. Javascript practice isn't the same as Rust practice, and Javascript practice includes a pretty strong norm around methods named "then".

That's why the next time I run into such a method, that doesn't belong to a promise and behave the way a promise's "then" method does, will be the first time I can remember, despite having worked primarily or exclusively in Javascript since well before promises even existed.

I'm sure there is an example somewhere on NPM of a wildcat "then", and that if you waste enough of your time you can find it. So what, though? People violate Rust idioms too from time to time, I'm sure. I doubt you'd argue that that calls Rust idioms themselves into question. Why does it do so with Javascript?

Re:A one-line package broke `npm create-react-app` by gpm on Saturday April 25, 2020 @03:07PM (#22980483)
It doesn't call into question the idioms of either language. It does call into question the idea of programmatically deciding whether or not something is a promise based on the assumption that the idiom was followed.

People bounce around between languages, especially to javascript. An expert javascript dev might not call things "then" but the many dabblers might. Going back to the original point this is a footgun, not only an avenue for malicious code to cause trouble.

Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @03:49PM (#22980845)
So your point ultimately is that duck-typing isn't ideal? I mean, I agree, but I'm not sure where this gets us that we weren't before.
Re:A one-line package broke `npm create-react-app` by gpm on Saturday April 25, 2020 @04:00PM (#22980951)
I don't actually mind duck-typing.

My primary point is just that you are mistaken when claiming that this bug could only be surfaced by malicious code.

My secondary (somewhat implicit) point is that having an "is-promise" function is a mistake when there is no way to tell if something actually is or is not a promise. This library/function name is lying to the programmers using it about what it is actually capable of, and that's likely to create bugs.

Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @04:13PM (#22981057)
I mind duck typing! That's why I'm so fond of Typescript, where everything that shows up where a promise should be is reliably either instanceof Promise, or instanceof something that implements Promise, or a compile-time error.

Absent that evolved level of tooling, and especially in an environment still dealing with the legacy of slow standardization and competing implementations that I mentioned in another comment, you're stuck with best effort no matter what. In the case of JS and promises, because of the norm I described earlier in this thread, best effort is easily good enough to be going on with. It's not ideal, but what in engineering practice ever is?

Re:A one-line package broke `npm create-react-app` by gpm on Saturday April 25, 2020 @04:24PM (#22981145)
So, I mind poorly implemented duck typing, I also mildly mind dynamic typing, but in principle I think static duck typing could be not bad.

With javascript promises in particular, the duck typing suffers from this unfortunate fact that you can't easily check if something can be awaited-upon or not. I don't think I really care if something is a promise, so long as I can do everything I want to to it. So I view the issues here as this function over-claiming what it can do, the limitation on the typesystem preventing us from checking the await-ability of an object, and the lack of static type checking. None of those are necessitated by duck typing.

I disagree that you're stuck with this best-effort function. It's perfectly possible to architect the system so you never need to query whether or not an object is a promise. Given the lack of ability to accurately answer that question, it seems like the correct thing to do. At the very least I'd prefer if this function was called "looks-vaguely-like-a-promise" instead of "is-promise".

Re:A one-line package broke `npm create-react-app` by throwanem on Saturday April 25, 2020 @04:40PM (#22981267)
Now we're kind of just litigating how "is-promise" is used in CRA, or more accurately in whichever of CRA's nth-level dependencies uses it, because CRA's codebase itself never mentions it.

I don't care enough to go dig that out on a Saturday afternoon, but I suspect that if I did, we'd end up agreeing that whoever is using it could, by dint of sufficient effort, have found a better way.

On the other hand, this appears to be the first time it's been a significant problem, and that only for the space of a few hours, none of which were business hours. That's a chance I'd be willing to take - did take, I suppose, in the sense that my team's primary product is built on CRA - because I'm an engineer, not a scientist, and my remit is thus to produce not something that's theoretically correct in all circumstances, but instead something that's exactly as solid as it has to be to get the job done, and no more. Not that this isn't, in the Javascript world as in any other, sometimes much akin to JWZ's "trying to make a bookshelf out of mashed potatoes". But hey, you know what? If the client only asks for a bookshelf that lasts for a minute, and the mashed potatoes are good enough for that, then I'll break open a box of Idaho™ Brand I Can't Believe It's Not Real Promises and get to work.

I grant this is not a situation that everyone finds satisfactory, nor should they; the untrammeled desire for perfection, given sufficient capacity on the part of its possessor and sufficient scope for them to execute on their visions, is exactly what produces tools like Typescript, that make it easier for workaday engineers like yours truly to more closely approach perfection, within budget, than we otherwise could. There's value in that. But there's value in "good enough", too.

Re:A one-line package broke `npm create-react-app` by Turing_Machine on Saturday April 25, 2020 @04:37PM (#22981242)
Re:A one-line package broke `npm create-react-app` by GlitchMr on Saturday April 25, 2020 @04:34PM (#22981212)
This is a promise as far the language is concerned (and `is-promise` package uses the same definition as the language) - it's sufficient for an value to be an object and to have a `then` property that is callable. For instance, in the following example, the `then` method is being called.

    (async () => ({
        then() {
            console.log("Called")
        }
    }))()
Re:A one-line package broke `npm create-react-app` by ehsankia on Saturday April 25, 2020 @02:01PM (#22979898)
Or just:

    const p = {then: () => 0}
Re:A one-line package broke `npm create-react-app` by hombre_fatal on Sunday April 26, 2020 @01:37PM (#22988693)
Well, an object with a then() method is a promise.

Promise.resolve({then: () => console.log('called')})

Promises autoflatten since you can't have Promise<Promise<T>>, so you'll see that this code prints 'called'.

Re:A one-line package broke `npm create-react-app` by chrisoverzero on Saturday April 25, 2020 @01:46PM (#22979764)
According this this library, maybe. According to the specification, no: https://promisesaplus.com/
Re:A one-line package broke `npm create-react-app` by shp0ngle on Sunday April 26, 2020 @03:29AM (#22985303)
Your code is indeed an example of a promise. A stupid one, since it never “resolves”, but it’s a promise.