ramda / ramda-fantasy

:ram::sparkles: Fantasy-Land compatible types for easy integration with Ramda.js
MIT License
1.5k stars 95 forks source link

reduce data type fragmentation #139

Open davidchambers opened 7 years ago

davidchambers commented 7 years ago

Related to #105

Once sanctuary-js/sanctuary-either#1 and sanctuary-js/sanctuary-maybe#1 are resolved (within the next two months I hope) I think we should do the following:

Reducing the number of different implementations of these (and other) data types is good for interoperability and thus good for the community. @SimonRichardson has been making this point for years.

buzzdecafe commented 7 years ago

fine with me, i am ready to retire :smile:

TheLudd commented 7 years ago

While Fluture seems much more mature and complete than our Future I wouldn't want to switch unless it has parallel execution in ap.

And with that being said, if you look at promises you have libraries like q, bluebird, when, promise and now native promises. While ramda fantasy may not become the rock solid foundation of functional programming in JavaScript I see no need to remove anything just because other versions exist elsewhere.

davidchambers commented 7 years ago

While Fluture seems much more mature and complete than our Future I wouldn't want to switch unless it has parallel execution in ap.

According to fantasyland/fantasy-land#179 a Monad's fantasy-land/ap method must execute sequentially in order to be lawful. My understanding of this matter is not strong.

And with that being said, if you look at promises you have libraries like q, bluebird, when, promise and now native promises.

Yes, we do. Multiple incompatible implementations with subtly (or in some cases not so subtly) different semantics. We've replicated this unfortunate situation with our algebraic data types. :cry:

While ramda fantasy may not become the rock solid foundation of functional programming in JavaScript I see no need to remove anything just because other versions exist elsewhere.

I see several reasons:

TheLudd commented 7 years ago

According to fantasyland/fantasy-land#179 a Monad's fantasy-land/ap method must execute sequentially in order to be lawful.

This is bad news because from my experience, this will make the future type practically unusable.

This will lead to helper functions such as "parallel" to be used instead of just lift and sequence. That might not be so bad if you are working with just Futures instances but once you want to put the Future inside a transformer much of the beauty and simplicity that comes from the types is lost.

With a parallel ap you can do parallel processing and sequential processing by using functions that are applicable to all modad types. But my understanding of why this is not lawful is also not very great.

davidchambers commented 7 years ago

This strikes me as a valid concern, @TheLudd. Let's raise the issue with all N of the JavaScript Future/Task library maintainers. :stuck_out_tongue_winking_eye:

TheLudd commented 7 years ago

Seems to be more of an issue to raise with the specification people. Any maintainer can then choose to be lawful or not... =)

Meanwhile, I will listen to this... https://www.youtube.com/watch?v=9RHLY0xbA28

TheLudd commented 7 years ago

But I did interpret this comment as if there was a possibility of parallelism.

SimonRichardson commented 7 years ago

Any maintainer can then choose to be lawful or not... =)

As long as they tell people that, then it seems reasonable.

TheLudd commented 7 years ago

@SimonRichardson To clarify: I understood @davidchambers to mean that we (unfortunately) need to discuss this across many repos and maintainers since we have this problem of spread out implementations. I merely suggested that the discussion belongs in the specification, i.e. one repository.

safareli commented 7 years ago

But I did interpret this comment as if there was a possibility of parallelism.

Discussion in the referenced comment was on Alternative instance not Applicative.

safareli commented 7 years ago

also there could be non monadic Futures (Applicative) which are as parallel as possible. you can mix then in a lawful way using Concurrent like structure from https://github.com/safareli/free/pull/31

scott-christopher commented 7 years ago

If we are to remove Maybe, Either and Future, then I'd suggest we should consider closing Ramda Fantasy in full.

Should we perhaps also consider removing the Either and Maybe from Sanctuary and promote the existing Fantasy Land equivalent packages? Or perhaps just provide sanctuary-def wrappers for the FL implementations instead?

The advantages of promoting the types under the FL banner is that we can then potentially refer to Maybe and Either in the FL spec, without the having to dance around wording or introduce types like we did for ChainRec.

davidchambers commented 7 years ago

Should we perhaps also consider removing the Either and Maybe from Sanctuary and promote the existing Fantasy Land equivalent packages?

Merging the Sanctuary implementations into their respective fantasy-land packages sounds good to me. I'm happy to do this if @SimonRichardson and the rest of the fantasy-land team are happy for me to maintain these projects.

The advantages of promoting the types under the FL banner is that we can then potentially refer to Maybe and Either in the FL spec, without the having to dance around wording or introduce types like we did for ChainRec.

This would be wonderful!

safareli commented 7 years ago

that would be amazing +1

SimonRichardson commented 7 years ago

Got my vote! Amazing!

On Thu, 1 Dec 2016, 05:01 Irakli Safareli, notifications@github.com wrote:

that would be amazing +1

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/ramda/ramda-fantasy/issues/139#issuecomment-264079485, or mute the thread https://github.com/notifications/unsubscribe-auth/ACcaGCnRjgcdDEEyZQQNZaD8FbBtdWDYks5rDlSTgaJpZM4K-7fJ .

svozza commented 7 years ago

Very exciting!

CrossEye commented 7 years ago

While I would have no problem shuttering Ramda-Fantasy, I'm not in agreement with the wider point here.

Ramda itself was a learning exercise at first. @buzzdecafe and I used it and its predecessor to learn more about techniques we had had limited exposure to in other languages and wanted to see used in JS. But Ramda quickly grew beyond that and turned into a community-focused library. R-F I also saw as a way to learn more about what folks were doing with FantasyLand. But I don't think it ever turned into as serious an effort. (Perhaps my perspective is off; I never became very engaged with R-F.) I don't think it would be a big blow to lose it.

But I don't buy this at all:

Reducing the number of different implementations of these (and other) data types is good for interoperability and thus good for the community.

I believe this is good for a community only for a short time. The whole point of a specification like FantasyLand is that it specifies exactly how certain things can interoperate. But it leaves wide open the remainder of their design. This allows implementations to play around in the solution space and come up with many different designs, many competing philosophies, many implementations that choose varying trade-offs. When we settle on a single version, we lose sight of the fact that the decisions made by that version are not necessarily optimal, that there might be better ones for one's situation or even for the wider community. It's especially problematic if we settle early.

I don't know if anyone else came through the Java Web world, but I spent too much time there, and I saw this problem several times: mostly imposed systems like EJBs and more organic ones like Struts: both were pretty horrible technologies that happened to gain just enough traction at just the right time to become nearly unstoppable for years. Competitors to these did not have a chance for a very long time. If you weren't using these, you were doing something wrong.

This is the same reason that I'm very happy to have Sanctuary and Ramda coexist with very distinct, but overlapping ideas. And it's why I was very sorry to see fn.js totter and FKit disappear. I think we're made much stronger with a marketplace of concepts, of implementations, of philosophies.

When I've reached for a F-L implementation, I've sometimes pulled down Ramda Fantasy, but I've been more likely to use Folktale. I haven't yet used Fluture, but I keep hearing good things, so I'll probably grab that next time. I think these separate tools help spur one another to innovate; they inform one another about performance, about API design, about documentation, about the entire software lifecycle. This is a good thing. A very good thing.

I would resist dropping R-F, except that I think there are plenty of good alternatives. If it's being actively maintained, and people are interested in participating, by all means, keep it running. But with a thriving community, there's no reason to bother unless people really want to use it.

safareli commented 7 years ago

the problem I see, is that there are not so many maintainers and I think most of FL implementations are outdated (or are not lawful: some optionals are not Functors, and some tasks, are ignore ap=<*> law), if we agree on some specific implementations and work on them, we could at least have some implementations which are always up to date, maintained, tested and are lawful, which is better than what we we have today. once community groves there could pop other implementations as well, which also fine.

scott-christopher commented 7 years ago

there are not so many maintainers

I don't think that's necessary true, nor a problem

most of FL implementations are outdated

That's true in regards to the current version of FL, but that's also why versioning in FL was introduced (despite RF still adopting the pre-versioning version)

some optionals are not Functors

I'd be interested to see an example of this

some tasks, are ignore ap=<*> law

I don't see that law defined anywhere in FL, nor do I think it's actually necessary. This would suggest that if an implementation can be derived then it must be, rather than being able to use a more optimal one, despite both choices evaluating to the same value.

That said, I think I'm still in favour for combining efforts towards a single implementation for simple data types. There could still be room for competing implementations if the data-type defined in FL was kept to a "minimum viable data-type" that just implemented the constructors, deconstructors of some kind and the FL spec. This would allow existing libraries to implement any various supporting libraries that they wished to while keeping the core data-type reusable across libraries.

If we were to consolidate efforts and promote the use of the FL data types, I would like to see a greater effort placed on documentation and discovery of the data types. Whether that's through a simple website that linked to (or displayed) the spec and the various available data types, along with their documented APIs or something else, I don't mind.

safareli commented 7 years ago

there are not so many maintainers

To be precise I meant there are not so many maintainers with much time. if the limited resource of maintainers were focused on small set of libs, we would have much better quality libs which are up to date, correct and documented, but I might be wrong.

some optionals are not Functors

I meant Optionals which trate null/undefined in special way i.e ignoring functor laws, like this:

Optional.prototype.map = function(f) {
 return this.value == null : this ? f(this.value)
}

(don't know of an lib exactly, but have seen it in couple articles)

I don't see that law defined anywhere in FL, nor do I think it's actually necessary. This would suggest that if an implementation can be derived then it must be, rather than being able to use a more optimal one, despite both choices evaluating to the same value.

From FL:

If a data type provides a method which could be derived, its behaviour must be equivalent to that of the derivation (or derivations).

Executing Tasks in parallel is not equivalent to executing Tasks in sequence, even if they evaluate to the same value, this was discussed in https://github.com/fantasyland/fantasy-land/issues/179 and https://github.com/rpominov/fun-task/issues/28.

davidchambers commented 7 years ago

There could still be room for competing implementations if the data-type defined in FL was kept to a "minimum viable data-type" that just implemented the constructors, deconstructors of some kind and the FL spec. This would allow existing libraries to implement any various supporting libraries that they wished to while keeping the core data-type reusable across libraries.

This is exactly what I have in mind. :thumbsup:

Competition is a good thing in many cases, @CrossEye, but I believe the value of having multiple competing implementations of an ADT with the same set of methods with (presumably) identical behaviour is outweighed by the loss of interoperability.

Competition is more beneficial at the level above the basic ADT implementations. For example, it would be exciting to see Folktale and Sanctuary depend on fantasy-eithers, but for one to provide a Scala-inspired object-oriented interface while the other provides a Haskell-inspired function-based interface (with optional type checking).