Open davidchambers opened 7 years ago
Could we use peerDependencies
to express the constraint?
"dependencies": {
"sanctuary-def": "0.9.0",
"sanctuary-type-classes": "2.0.1",
"sanctuary-type-identifiers": "1.0.0"
},
"peerDependencies": {
"sanctuary-def": "0.9.0"
}
versioning the two packages such that
sanctuary@X.Y.Z
always depends on and works withsanctuary-def@X.Y.Z
This could be a handy indicator, but might also be a hassle to maintain and assure.
Could we use
peerDependencies
to express the constraint?
I've never seen peerDependencies
used like that, though I haven't come across the situation where a package is both a dependency and a plugin to another package. I guess it might win us an automatic warning when the user tries to use an incompatible def
, but I think it's all a bit messy. It relates the concerns I expressed here.
The problem, I think, is that multiple parties are creating black-box data structures (type definitions) using sanctuary-def
and multiple parties need to interpret (call def
on) those structures using sanctuary-def
. Maybe it's possible for the future to ship the interpreter with "batteries included", eg:
const sanctuary = require('sanctuary');
const $ = require('sanctuary-def');
const env = $.env.concat(sanctuary.env).concat(myEnv);
const def = TYPE_CHECKING ? $.createTypecheckedDef(env) : $.def;
const S = sanctuary.create(def);
sanctuary
would have to have a Peer Dependency on sanctuary-def
, but not direct dependency. It's compatibility with def
would only change if the type signature of def()
changes, but not when the internal data structures change. Maybe It's a bad idea. Might be one for Ideas about env ;)
Ah I just realized what the flaw in my idea above is: In order to provide an env
, we would still need sanctuary-def
, and we'd still have the "multiple parties with incompatible data-structures"-problem.
But it does seem to me like removing sanctuary-def
from dependencies and keeping it as only a peer-dependency would reduce complexity. If all these parties would do the same thing, you can be sure that the data structures will be compatible.
But it does seem to me like removing
sanctuary-def
from dependencies and keeping it as only a peer-dependency would reduce complexity.
I agree. const S = sanctuary.create(def);
seems very nice to me! Let's seriously consider this change once we get v0.12.0 out the door. :)
Here's what I think we should do:
sanctuary
into small modules, each with a peer dependency on sanctuary-def
(and possibly sanctuary-type-identifiers
and other shared dependencies):
sanctuary-either
to contain the Either type, its Repr, and associated functionssanctuary-maybe
to contain the Maybe type, its Repr, and associated functionssanctuary-list
for list related functionssanctuary-string
for string related functionssanctuary-strmap
for the StrMap type, its Repr, and related functionssanctuary-prelude
library which takes from each of the above libs to provide a set of common tools.sanctuary
library will have a single function. To load sanctuary-prelude
and the shared peer dependencies like sanctuary-def
, and instantiate the prelude with a default def
.People who want an out-of-the-box experience will use sanctuary
, people who want a customized one will use sanctuary-prelude
, people who want only parts of the functionality will assemble their own utility belt from the available underlying libs.
This tackles several problems:
sanctuary-maybe-type
, sanctuary-maybe-from-nullable
. This package structure is "composable" all the way down to sanctuary
.require('sanctuary')
directly, which defeats the point of disabling type-checking": Now, I will depend only on sanctuary-prelude
, and provide my own assembly which they have to use.sanctuary-def
is not compatible with yours": Since all packages but sanctuary
have it as a peer dependency, they will all use the same version and NPM will show it when one is not compatible and should be down or upgraded.ENV_X
to determine whether to check types": The community is now free to provide many Sanctuary assemblies, since it's very easy to set up. Just depend on the compatible sanctuary-*
packages and export create(myDef)
.Is it UnaryType
that breaks things currently?
I really don't know the internals of sanctuary so I have no idea what is possible but I assume that each of those packages would need sanctuary-def (78 kb) and sanctuary-type-classes (45kb). Right now sanctuary is 100kb, let's say sanctuary-maybe would me 15kb. Would it make sense to have a separate package of 15kb with 123kb of dependencies? In that case, me as a user, I would prefer to download an es6 modularized sanctuary and tree shake it myself. Other option is to ask if you are downloading a single package probably you are working on a small project and you would not need type checking, so remove type checking on individual packages -if possible.
Sanctuary depends on sanctuary-def, as specified in package.json. Furthermore, Sanctuary is only compatible with certain versions of sanctuary-def. @codedmart recently brought it to my attention on Gitter that the example for
create
does not work if one uses the current version of Sanctuary (v0.11.1) with the current version of sanctuary-def (v0.9.0).There are (at least) two things we should consider:
sanctuary@X.Y.Z
always depends on and works withsanctuary-def@X.Y.Z
.