-
Notifications
You must be signed in to change notification settings - Fork 20
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
Why there is no creed.of
method?
#177
Comments
Hi @dmitriz. The FL has changed slightly over time with regard to where So, creed had placed it at
The language has changed to "type representative". The of section as well as the last paragraph of the type representative section seem to indicate that it's still required to be named
So, I think creed still satisfies Applicative / Pointed Functor. To be honest, I haven't read the FL spec in depth in a while, so I hope I'm reading all of that correctly! It may still be perfectly reasonable to add |
Thank you @briancavalier for the explanation, I would have never guessed it is on the > creed
{ enableAsyncTraces: [Function: enableAsyncTraces],
disableAsyncTraces: [Function: disableAsyncTraces],
resolve: [Function: resolve],
reject: [Function: reject],
future: [Function: future],
never: [Function: never],
fulfill: [Function: fulfill],
all: [Function: all],
race: [Function: race],
isFulfilled: [Function: isFulfilled],
isRejected: [Function: isRejected],
isSettled: [Function: isSettled],
isPending: [Function: isPending],
isNever: [Function: isNever],
isHandled: [Function: isHandled],
getValue: [Function: getValue],
getReason: [Function: getReason],
coroutine: [Function: coroutine],
fromNode: [Function: fromNode],
runNode: [Function: runNode$1],
runPromise: [Function: runPromise$1],
delay: [Function: delay],
timeout: [Function: timeout],
any: [Function: any],
settle: [Function: settle],
merge: [Function: merge],
shim: [Function: shim],
Promise:
{ [Function: CreedPromise]
resolve: [Function: resolve],
reject: [Function: reject],
all: [Function: all],
race: [Function: race] } } My personal reaction is, whether the nested namespace is really necessary and not adding any extra complexity making the library harder to use (and discover its features). I can also see another Would it not be simpler to have the main library On the other hand, the |
That's the whole idea. The Creed |
Hm... Then why not just use the native |
tl;dr I'm open to simplifying/streamlining the API for a 2.0 release @dmitriz Creed was intended to help bridge between A+ / ES and FL. It was created at a time when native promises had significant performance problems, async/await wasn't easy to use everywhere, and FL was still fairly new. So, many of the 1.x API decisions were made under quite different circumstances than exist today. It's easier to see some of the API inconsistencies with hindsight. I'm sure there's plenty of room for improvement, and I do appreciate your fresh perspective on it. The API is intended to be used primarily as named exports, and creed.Promise is exported mostly just in case someone might ever need it. Perhaps not the best reason, but again, hindsight. As @bergus mentioned, creed's Promise was intended as a drop in replacement for A+/ES. The
All of that said, I'd certainly be open to simplifying/streamlining the API for a 2.0 release. |
Correction: Creed's async stack traces are awesome! |
@briancavalier I can see the benefits for both replacing the native
A big selling point of creed.map(someFunction, nativePromise) which would return what I would call a "creed promise", Now I understand that My guess is that the currently intended way is creed.resolve(nativePromise).map(someFunction) which does not feel as obvious and straightforward, Perhaps something like let creedPromise = creed.fromPromise(nativePromise) could be a lightweight way of cooking up a "creed promise" Another suggestion, since the native promise is by now established, |
Again, there is history: Static land didn't exist (or at least, I wasn't aware of it) when creed was created, and FL did exist, so picking a "standard" on which to base the API was easy 😄 . Also, tree-shaking wasn't practical and/or widely used, and function composition (which will tend to require partial application) as a programming model in JS wasn't prevalent. Since then, I decided to implement both SL and "functions-mostly" in another project, and then eventually transition to functions-only. I've been watching this closely to see when the time is right to adopt it. I might rather go in that direction, once it gets a bit more consensus, but it seems to leave the tree-shaking question open. Methods aren't all bad: they allow typeclass-like dispatching, whereas functions require either using switch statements or passing around typeclass dictionaries to achieve the same, both of which can be cumbersome. IIUC, the latter is one reason FL chose methods as its primary typeclass representation. Creed's design takes advantage of that to provide optimized implementations for fulfilled, rejected, and never promises. I've found that representing some small-ish number of core low-level operations via methods plus a public API via functions works quite well. Creed simply uses methods where there was opportunity for different promise variants to provide a specialized implementation. It would be an interesting research project to see how shifting more toward functions compares, both readability/maintainability-wise and the ability to optimize cases like fulfilled, rejected, and never. |
I like being explicit with
Yes, that seems helpful now that "promise" tends to mean ES |
Aha, interesting to know, thanks!
That looks very interesting.
I find both useful to have. promise.map(f).map(g).flatMap(res => doSmth(a, res)) whereas functions can be nicer to use with non-native but conforming promises pipe(map(f), map(g), flatMap(res => doSmth(a, res))) that you can run against any promise with the same abstract code,
That makes perfect sense.
This discussion for |
The FL Applicative spec includes the
of
method but it does not seem to be available oncreed
:> creed.of(1) TypeError: creed.of is not a function
Any reason not to have it?
It could be mentioned that
of
is actually more basic than Applicative and is part of the Pointed Functor Spec, see also https://github.com/MostlyAdequate/mostly-adequate-guide-it/blob/master/ch9.md#pointy-functor-factory.It seems that
creed.fulfill
is doing whatof
is meant to do,which is somewhat non-standard name and is longer to write.
Also, when it is not called
of
, the question arises whether it conformsto the Pointed Functor spec, which I understand it does.
If
creed.fulfill
is indeed intended to satisfy the Pointed Functor spec (together withmap
),maybe also alias it as
of
and add tests for the spec?The text was updated successfully, but these errors were encountered: