Skip to content
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

Take Sanctuary #105

Closed
buzzdecafe opened this issue Feb 25, 2016 · 30 comments
Closed

Take Sanctuary #105

buzzdecafe opened this issue Feb 25, 2016 · 30 comments

Comments

@buzzdecafe
Copy link
Member

Should we merge RF and Sanctuary?
What would a merger of RF an Sanctuary look like?

@davidchambers
Copy link
Member

I have quite a few thoughts on this matter. I hope to put them into writing later in the day. :)

@buzzdecafe
Copy link
Member Author

For me it boils down to:

  • much of the work is duplicated; and
  • the goals of the two projects overlap; and
  • RF was a learning project for me, now i don't devote much time to it;
  • I have an idea I want to work on that probably fits better in sanctuary than RF.

I have quite a few thoughts on this matter.

I don't doubt it

I hope to put them into writing later in the day. :)

looking forward to it

@joneshf
Copy link
Contributor

joneshf commented Feb 26, 2016

👍

@davidchambers
Copy link
Member

Sanctuary and ramda-fantasy have much in common. Both libraries provide algebraic data types and functions for operating on values of those types.

The projects came into existence for different reasons: ramda-fantasy as a playground for types; Sanctuary to address limitations imposed by our decision not to have Ramda functions take or return values of Ramda-defined types.

Sanctuary's emphasis on correctness manifests in two ways. First, it means head has type [a] -> Maybe a rather than [a] -> a. Secondly, function contracts are enforced at run time. Run-time type checking is invaluable during development, so eventually Sanctuary will provide much of the Ramda API.

It would be nice to avoid duplicated effort (@scott-christopher has made significant contributions to both projects). How might this work? There are several points to consider:

  • Name. In my view Ramda and Sanctuary are both excellent names. I also like the name ramda-fantasy, but others are not so happy with it (see name change? #99). If this project and Sanctuary are to merge, Sanctuary seems the more appropriate name for the combined project: we leverage Fantasy Land to create a refuge from unsafe JavaScript.
  • Organization. Sanctuary is currently in the plaid namespace on GitHub. This would not be an appropriate location. Perhaps the various Sanctuary projects should live in the ramda namespace. This is something we'd need to discuss with people at Plaid.
  • Tools. The tooling plays a part in making contributing to Sanctuary enjoyable. There's one source file and one test file. No build script. No JSDoc. Comments in the source code flow through the readme to generate the website. Code examples are never out of date as they're tested with every commit. Full branch coverage is a requirement. These are all things I wish to preserve.

@scott-christopher
Copy link
Member

I'm generally supportive of this, particularly to have one definitive suggestion that we can give to those who ask which library should be used for supporting data types along with Ramda.

I'm not particularly attached to names in general, so I'm happy to defer to consensus here (so long as it is easily discoverable).

The main question I have is what happens to the existing types in RF that aren't currently in Sanctuary? Does it make sense to keep all of these types in the merged project?

@davidchambers
Copy link
Member

The main question I have is what happens to the existing types in RF that aren't currently in Sanctuary? Does it make sense to keep all of these types in the merged project?

@svozza has requested S.Maybe and S.Either as standalone packages. The plan is to publish sanctuary-maybe and sanctuary-either packages upon which the sanctuary package depends. This approach would allow us to provide types, such as IO, which are not used in the main library but which are nonetheless useful. Whether to prefix the package names with ramda- or sanctuary- (or something else) could be discussed, but the idea of having one package per type seems reasonable.

@scott-christopher
Copy link
Member

That approach sounds reasonable to me too.

@CrossEye
Copy link
Member

Wow, I missed the original discussion, and only am seeing this today.

I really like the idea of getting R-F to grow up into something useful, and Sanctuary does seem to be the right place to do that. I don't have a strong feeling about the name for this, whether it's under the "ramda" or "sancutary" namespace.

And I like David's proposed process. If we do it like that, I believe we might be able to also manage the enjoyable tooling per package. (I'm not so sure that would have been a good idea for a combined package.)

🌿

@TheLudd
Copy link
Contributor

TheLudd commented Mar 14, 2016

My $0.02 on this is that if we are to change the code base for this lib, we should really split all the types into separate packages like the plan was with S.Maybe and S.Either. Where they are hosted or what name they have are of less importance to me.

@buzzdecafe
Copy link
Member Author

I have no strong feelings about the name, and I think I'm onboard with the tooling, subject to the "one package per type" design discussed above. As to the organization, I prefer the merged project under the ramda organization, so that may be the first wrinkle to iron out.

I am deeply skeptical of run-time type-checking in JavaScript, although I don't deny that it can be very useful. If we wish to merge external modules, does that mean inserting type errors into the code everywhere?

Now, static type-checking is something else altogether. I am very interested in that. I wonder if the annotations of Sanctuary types will permit some stronger static type checking? This implies a separate "compilation" step, of course ... and I've always said, if you are going to compile, then why use JavaScript at all ... but here I am ...

@davidchambers
Copy link
Member

If we wish to merge external modules, does that mean inserting type errors into the code everywhere?

You make the prospect sound so appealing. ;)

Here's the current implementation of concat for Maybe a:

Maybe.prototype.concat =
method('Maybe#concat',
       {a: [Semigroup]},
       [$Maybe(a), $Maybe(a), $Maybe(a)],
       function(mx, my) {
         return mx.isNothing ? my :
                my.isNothing ? mx : Just(mx.value.concat(my.value));
       });

Setting aside the pros and cons of run-time type checking, one must concede that the code above is self documenting.

What's your position on using sanctuary-def to enforce invariants, @buzzdecafe? Is this a deal-breaker for you?

Now, static type-checking is something else altogether. I am very interested in that.

You're selling run-time type checking short. A contract system such as Racket's can enforce invariants which cannot be enforced statically in most languages. For example, a function which takes a Point and a Rectangle could require that the Point lie within the bounds of the Rectangle.

Of course, sanctuary-def is far from this point currently. I just don't want the conversation to be based on the assumption that static type checking is strictly superior to run-time type checking.

@buzzdecafe
Copy link
Member Author

What's your position on using sanctuary-def to enforce invariants, @buzzdecafe? Is this a deal-breaker for you?

Not at all. If it's strong enough I would like to explore if it can be used for static type checking.

@davidchambers
Copy link
Member

I'm pleased to hear that, @buzzdecafe.

Performing static analysis on the arguments to def is an interesting idea. Sounds tricky, though. ;)

Avaq referenced this issue in stoeffel/awesome-fp-js Mar 15, 2016
@joneshf
Copy link
Contributor

joneshf commented Mar 19, 2016

Forgive me if this doesn't come out right, but I have a bee in my bonnet.

What do we as a community gain from splitting either repo up into smaller repos with data types? I can't think of much additional good that is going to come from this. In gitter, people regularly ask what the difference is between RF's Maybe and Sanctuary's Maybe. Similar for RF's Future and folktale's data.task. Why do we need all of these data types to exist? They're the same data types! Can we not use the data types defined in fantasyland? How does RF's Maybe or Sanctuary's Maybe differ from fantasy-options? Modulo renaming, I don't see any difference.

My suggestion is not to split the repos (ramda-fantasy or sanctuary) into separate repos for the data types. Delete the data types altogether and contribute to the fantasyland repos. I think it was a good experiment, and some great things came of it. The future implementation has some pretty nice stuff, but most of the other stuff is no different from any other library out there. Pulling back some of the ideas of future into fantasy-promises would be great!

Do we need to duplicate the work of:

?

I think the community would benefit much more if ramda and sanctuary supported the fantasyland data types, rather than adding another schism to the already fragmented js landscape.

Okay, bee is gone.

@TheLudd
Copy link
Contributor

TheLudd commented Mar 19, 2016

I agree with you @joneshf, my point is just that creating single type packages is preferable to one big package with several ones.

@mattferrin
Copy link

@joneshf brings up a good point about fragmentation. Non-deluded name recognition seems important.

Ramda is the most starred most well know functional JavaScript library I am aware of, except Facebook's immutable-js repo has more stars. Might it be best to organize under the most starred and name recognized repo? Let the Ramda name win, I think.

I'm not seeing the benefit of separate packages when JavaScript files can be imported individually, but I'm sure there is a reason people want it.

@buzzdecafe
Copy link
Member Author

@joneshf your point that external, redunant type packages are pointless is well taken. I am happy to let FL be the "repo of truth" for types. Does that mean Sanctuary's role is the "glue" between Ramda and FL?

@joneshf
Copy link
Contributor

joneshf commented Mar 19, 2016

Does that mean Sanctuary's role is the "glue" between Ramda and FL?

I don't want to suggest anything other than removing the types that are redundant. Future isn't one of those types. I'd say pull that into a fantasyland repo, or see if it can meld with fantasy-promises. At the very least, bring the ideas over to fantasy-promises. But definitely don't throw away all that work.

@CrossEye
Copy link
Member

My suggestion is not to split the repos (ramda-fantasy or sanctuary) into separate repos for the data types. Delete the data types altogether and contribute to the fantasyland repos. I think it was a good experiment, and some great things came of it. The future implementation has some pretty nice stuff, but most of the other stuff is no different from any other library out there. Pulling back some of the ideas of future into fantasy-promises would be great!

I'm more mixed about this. I have not been very active in Ramda-Fantasy, either in contributing to it or in using it. When I reach for an implementation, I tend to reach for Folktale. I've wanted to contribute to R-F, because I've always thought of it the way I originally thought of Ramda itself, as a learning exercise. But by the time I was ready to do so, it was well on its way, and I was too far behind. My own exercises have so far been entirely on the side, and somewhat at odds with the actual FantasyLand style. I use Folktale because to my eyes it is the most robust, battle-hardened, well-documented implementation available of the types I tend to want.

Do we need to duplicate the work of:

First of all, I didn't even realize these existed. They're not even on the list of implementations maintained on the FantasyLand specification site!

But more importantly, while we don't need to be the ones to do it, I'm glad someone is doing this. As tickled as I am by the success of Ramda, I find the lack of competition in this space quite disturbing. Settling on a common specification is a very good thing. Settling on an implementation mostly means a lack of innovation. I would rather that someone be working on different versions of these same ideas.

As for separate mini-libraries versus bundling, anyone who does much work in the browser world, especially on mobile tends to appreciate the ability to create small packages. Obviously it's simply not a real concern for Node or other server-side environments.

@davidchambers
Copy link
Member

Thanks for raising this point, @joneshf. To be honest, it had not occurred to me that the various fantasy- libraries are intended to be used. I'm very much in favour of consolidating our efforts.

I had a look at the string representations of values created by fantasy-eithers:

> const Right = require('fantasy-eithers').Right
undefined

> Right([Right(1), Right(2), Right(3)])
definitions {
  r: 
   [ definitions { r: 1 },
     definitions { r: 2 },
     definitions { r: 3 } ] }

> Right([Right(1), Right(2), Right(3)]).toString()
'[object Object]'

Here are Sanctuary's equivalents, in contrast:

> const Right = require('sanctuary').Right
undefined

> Right([Right(1), Right(2), Right(3)])
Right([Right(1), Right(2), Right(3)])

> Right([Right(1), Right(2), Right(3)]).toString()
'Right([Right(1), Right(2), Right(3)])'

I'm certainly willing to open a pull request to define inspect and toString methods for fantasy-eithers' Left and Right. This would require applying R.toString to the value inside the container. I'm not sure whether this idea will be popular with the FL team, but I'm keen to find out.

Playing with fantasy-eithers the first thing I discovered is that the master branch is not compatible with Node v4.4.0 unless --harmony_destructuring is provided. I raised this in fantasyland/fantasy-eithers#5.

@svozza
Copy link

svozza commented Mar 19, 2016

The only reason I asked for the types to be split out was because I wanted to do a Sanctuary date library that returned an Either for some of its functions. I didn't want a user to have to take in the whole of Sanctuary just to convert a few dates. I too was unaware of these fantasyland types so maybe they're a good option.

@joneshf
Copy link
Contributor

joneshf commented Mar 19, 2016

I use Folktale because to my eyes it is the most robust, battle-hardened, well-documented implementation available of the types I tend to want.

That's a fine choice as well. It doesn't really matter to me which implementations are used. Or even if they're from multiple places. I just don't want us as a community to have another set of libraries.

Settling on an implementation mostly means a lack of innovation. I would rather that someone be working on different versions of these same ideas.

I agree, and I hope I didn't come off as shutting down innovation or experimenting.

I'm certainly willing to open a pull request to define inspect and toString methods for fantasy-eithers' Left and Right. This would require applying R.toString to the value inside the container. I'm not sure whether this idea will be popular with the FL team, but I'm keen to find out.

That might be something daggy could/should do.

@SimonRichardson
Copy link

Indeed it does do this, but I've got a feeling the lib is using the wrong daggy.

I sometimes don't pick up all the PRs or issues so if you ping me via email or Twitter directly then I'm more likely to answer back much much quicker :)

@safareli
Copy link
Contributor

Are there any updates on this?

@davidchambers
Copy link
Member

Are there any updates on this?

I don't think so.

RF began life as a laboratory for experimentation, and while it certainly gets some use it's still rough around the edges: the Maybe and Either types lack features provided by Sanctuary's equivalents, and the Future type lacks features provided by Fluture. The other types are certainly useful, but overlap significantly with various @fantasyland projects as pointed out by @joneshf. Perhaps the question we should be asking is how to merge RF into @fantasyland?

@safareli
Copy link
Contributor

Perhaps the question we should be asking is how to merge RF into @fantasyland?

Agree!

@joneshf
Copy link
Contributor

joneshf commented Sep 18, 2016

What would be merged? As I understand RF currently, everything it provides is available in FL.

@davidchambers
Copy link
Member

What would be merged? As I understand RF currently, everything it provides is available in FL.

Everything… except documentation. 😜

@scott-christopher wrote great documentation for RF. Compare this and that, for example.

@danielo515
Copy link

Is this issue stalled ?

@CrossEye
Copy link
Member

This whole project has been halted. See #157 for details.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests