-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
[RFC] Shrink the standard library #5215
Comments
I still don't have a strong opinion about this issue. Just wanted to add something we (Ary & me) have discussed last week - we could help the adoption of this blessed shards by making So they are almost part of the stdlib (ie, most projects will probably "just include them") but they aren't coupled to the compiler's release process. |
Oh, yes, that's a great idea. In fact it could ask you what you want/need:
|
I think the right boundary between usefulness is somewhere between JSON/HTTP (which should be in the stdlib) and YAML/XML (which should not). JSON is simple, and it's fairly common. HTTP (at least version 1) is simple, and very common. YAML is a lot more complex of a standard, and is much less common than JSON. XML is very common (although not as much as json) yet is extremely complex to the point that we really need a prebuilt library to parse it. Here's a list of top-level modules I (personally) don't think should be in the stdlib:
Perhaps the compression stuff ( |
I am not a crystal user, only a ruby user, so please feel free to ignore me completely. I am sure that whatever way you pick will be the one that will be right. I am a bit confused as to why json is considered superior to yaml but since it also does not affect me, But one thing about distribution packaging, e. g. debian:
I would not worry about this. Distributions such as debian will already package things up Ruby has the xmas release and it does not matter what any distributions do in regards to If you were to depend on a distribution, then that distribution has a crippling effect on |
I would love to see a stdlib shard, which would in turn depends on shards of these 'blessed' "pieces of the standard library", and likewise for other high-level groups of libraries (ui?, web?, gl?, etc). Smaller chunks [shards]; easier for community involvement and more optimizable code. [Kinda makes me think of MRuby's granularly configurable dependencies.] |
@drhuffman12 this just feels right to me. Having a shard (or group of shards) like this allows for the standard library to be even more conservative about what is considered a de-facto component of the language. If this would (as @asterite suggests) make version updates more nimble, then I'm all for it! |
I really do agree for shrinking the stdlib. Keeping the core smaller will lead to a better maintenance. Rust has a small stdlib and noone seems to complain, so I don't think it'll be a problem for Crystal too..would be nice though to keep at least HTTP/1.0 as part of the core lib. |
Is it a problem if the compiler itself ends up depending on (blessed) shards? |
I disagree on the principle of moving everything the compiler doesn't use to a shard. I believe there are many things that the compiler does depend on that should be in a shard, and many things the compiler does not depend on which should be in core. For example I think that a common batteries-included HTTP abstraction is essential for HTTP libraries and frameworks to play together. And the correct way to ensure this is to put HTTP in the stdlib. The compiler doesn't (apart from play) use this. But I still think it should be in the stdlib. |
@RX14 I agree. I think LLVM could perfectly be a shard on which the compiler depends. It makes very little sense to have it in the standard library unless you are going to develop a compiler or interpreter, or contribute with the compiler itself. I think in the Markdown discussion we concluded that it would make distributing Crystal a bit harder, but I'm not so sure about that. I also kind of agree regarding a common HTTP server base. I don't know about For now, we can discuss the YAML and XML modules. Regarding XML, I think it's always required by Regarding YAML, it seems the specs for We could then open separate issues to discuss extracting other stuff, like |
I think that if common libraries like YAML are going to get moved out of the standard library, there should be some first-party way of maintaining local copies of shards, much like how Bundler installs gems locally. A common use case for me is working on a plane or a train, where I do not have access to the internet, or it is spotty/slow at best. If I wanted to start a project while in transit, I'd be sad to find out that a common library I want/need to use isn't available because I can't download it in the moment, and won't be able to for another 5-12 hours. I can't say I'm necessarily a big fan of Bundler because it ends up keeping various versions of everything around and you end up being forced to |
As a bit of a side note: seeing how |
@faultyserver It does depend on libyaml though. |
I also think that if we include a http server we should have a http client. I don't think the current HTTP module is well designed at all though. |
I just think that shardening shall be later. Please don't touch it, it's simple before 1.0. Multiprocessing is feature I want :) |
Can the parser/compiler be used to generate a dependency tree? If so, maybe such a tree could be used to help note the 'from', to help clarify what might be easiest/harder to move to shards, and to help clarify what might need to be adjusted/de-coupled/etc in order to be moved to a shard? |
@akzhan , sounds good to me! Saving the sharding for 2.0 [or 1.x] would be fine with me. [Maybe sharding would help Crystal get to 1.0 sooner and I would love the pro's; but, I'd rather err on the side of less scope creap.] |
@akzhan It's actually simpler if we move stuff out of the standard library to shards. Right now we have to tackle YAML, XML, etc., plus parallelism. If YAML, XML, etc., were shards, maintained by others (with the core team keeping an eye on them, but not necessarily having to worry too much because it's not in the standard library) it will give the core team more time to fiddle with parallelism and other more important stuff. I actually started implementing tar some time ago, but never pushed it because it wasn't feature-complete. Now I'm thinking that I could have created a shard and others could have probably helped me fill the gaps. It doesn't matter if it's not feature-complete or if it's buggy because it's not in the standard library, and can evolve easier and separate from the language/compiler. Another way to say it: a module that's in the standard library has to be well thought, documented and complete, and will be frozen once we reach 1.0. That means the core team has to spend more time on this. Just look at how fast Elixir evolved. Their standard library is pretty small, but it has the core stuff in there. In fact, the tool for generating docs is not even included in Elixir, it's a separate tool. That lets the core developers focus on the language and a small core subset. Same goes with Rust, which already reached 1.0. Go is a different story because they had a lot more time and resources than those projects. |
I agree, an smaller stdlib will be easier to maintain and focus on parallelism or even windows support. I also think documentation generator should be moved to a separated shard. Maybe we can move some |
I agree with @faultyserver, impossibility to create anything useful without internet access seems sad. So it would be great to have offline way to install shards, so e.g. all |
remove many libs from stdlib decrease possibility to use crystal for scripting. when you need to write 10 lines script, and you don't want to create project and install shards. |
The omnibus release could prefill this "cache" with some of the blessed shards so that no internet is needed after crystal itself is installed.
We could have a shard "github/mamantoha/crest", ">0.9" # optional version restriction
require "crest"
pp Crest.get("http://example.com/resource") This can even be used for bigger project (actually, I think this is better than having a yml file, but that's another story).
The compiler can import some tool shards and expose then on the command line. This way they are both included in the compiler (transparent for the user), and with easier maintenance for the project. |
@lbguilherme Yeah, caching shards in some common place like node would be very useful, see crystal-lang/shards#180 |
@kostya Maybe we should implement |
I'm not sure I like the idea of removing doc and the formatter from the compiler. At least these tools should always be installed. They're also tied into the compiler internals, which means that refractors to the compiler will affect these tools. Which makes putting them in a seperate repo rather hard with a changing master. Also more tools means more binaries we have to distribute. |
Regarding offline usage of Crystal, I believe the problem will always be there. For example if I want to use MessagePack, well, it's not in the standard library, and I won't get it on a plane. One can always download the shards in a local directory and then reference them with I do agree about Crystal becoming less suitable for scripts. But I think scripts mostly use Array, Hash, File, IO, etc. Well, maybe JSON and CSV. We could keep those in the standard library because they have no dependencies, plus they are relatively simple. But if scripts become a bit harder to write, I wouldn't mind. In any case I don't see the point in writing a small file, saving it in (we never said Crystal is a scripting language) @faustinoaq Small side note, but doing a refactoring/renaming tool in Crystal is plain impossible, so I wouldn't spend time on that. |
Well said! 👍 :)
@asterite Maybe because crystal has the same issue that C++ about refactoring tools ? |
Should probably remove |
I think
|
Yes, pretty much always. |
Proposal to decouple stdlib with batteries included.Requirements:
This proposal requires the following minor changes:
That's the basic idea. To most developers all the commands stay the same and 2 lines are added to new shard.yaml files by default. Documentation is identical. Library availability online or off is identical. The remainder of changes are for the shards command, documentation generator, or other plumbing that doesn't concern the average user or usability of crystal. Addressing documentation and lack of batteries.Minor changes are made to the documentation generator to include stdlib dependencies in the official documentation and mark them as such. Changes to the documentation generator to include shards and annotate which shard the API is from (if it doesn't already) would have other benefits. Now documentation of each project can be generated with all available API's for the specific versions used in your projects. Going to work on a ~4yr old project would be much better with it's own documentation rather than relying on google. If you tried to search for crystal 0.x.y, it wouldn't give you documentation for libfoo 0.y.z all in one place. Addressing monolithic stdlibWithin this proposal no project needs to require stdlib. It can be removed by deleting the dependency in shard.yml and adding dependencies to the individual libraries used. In addition more focused stdlibs could be published by anyone such as stdlib-http which includes dependencies for at least [http-client, openssl, json] that are validated and tested together against various compiler versions. Addressing what to put in stdlibIt almost doesn't matter. Everything not required by the compiler (@asterite's preference) can be put in it's own library and still be available for use and documented as it is right now. Addressing compiler/stdlib incompatibilities over time.Automated testing:
Addressing individuals concerns
Why advisory versions?App "foo" is using stdlib v1 but wants to use xml v2. If stdlib is locked to v1 then it's not possible to upgrade shards a piece at a time which is often necessary for old applications. Perhaps a better name would be "default locked version". Locked to a specific version unless specified elsewhere. Shards specific (behind the scenes) changes
Best of allThe code required to implement (most) of this proposal is minimal. A handful of defaults and additional search paths. Additional glue is necessary in shards to check compiler versions but that's probably necessary over the long term anyway for all libraries not just stdlib. Should I have put this here or in a new PR? |
@RX14 Was there something I didn't address? Or some part that can be improved? |
Something that would be actionable in an iterative way and beneficial whether the std-lib is split or not is to separate the prelude from core. Letting core be a minimalistic prelude alternative will:
Currently, low-level stuff like Another example is Due to refactors is easy to end up with circular dependencies across types in the prelude. Having a core will help to put some strict boundaries there. Right now the prelude has some first modules included in a specific order, but leaving only those does not compile. Core should have the minimal runtime, most primitives (but not necessarily all), and some classes/operations but not things like map/filter/etc. I'm not sure the std should/can be splitted in the near future, but even so, I think that what I am proposing is still a step needed. |
I think this would introduce massive breaking-changes for current Crystal projects. Which will cause Crystal devs a lot of pain that is not really necessary. Especially considering the state Crystal is in now. Shards exist for this very reason. Instead of all the shards being added to the core, they are.. shards. This is already sufficient. Crystal already has great modularity. and the current codebase is in no way bloated. I'm sorry, I just don't see any justification in doing this. In fact, I beg asterite, bcarddiff, and the other lead devs to never even consider doing something like this. The lead devs decide on what is added to the core language. They've already merged what we have, as they thought it would be good for the core at the time. There is no reason to backtrack. Also, if someone thinks just because they personally don't find something useful, you can't use that as an argument to get it removed; because you don't know if another Crystal dev is already utilizing it. |
@didactic-drunk an actionable plan is the easy part: create repositories, move files there, use submodules or a shard.yml with loose patch level constraints ( There is more to the problem: confidence loss in merging changes and/or a complexified crystal test suite, interdependences, ... It would be great to see some libs like LLVM or OpenSSL extracted and each tested against different versions, to be able to install patches quicker for them, but it's not that easy to put up. |
None. No breaking changes. That's part of "Requirements 1." implemented as "minor changes 1.". |
@bcardiff What you propose sounds entirely different from splitting stdlib and core. I think you're talking about minimizing dependencies within core. I'm not up on compiler internals but stdlib is right up my alley. |
@girng Rust does something similar. The compiler and stdlib can run at different versions. The proposal I listed allows the same mixing and matching with different version for long term support in a way that's seamless. You won't know about it unless you try to change the stdlib version manually. Here's an example of how this benefits long term support:
With core + stdlib as a single package you can:
Or with stdlib split from core:
It's way less work and way less breakage. |
@ysbaddaden If crystal provided nightly ci builds to test against would this address the confidence issue? Could tests for stdlib-a run both with and without the current stdlib to check for integration issues? Without stdlib would only add it's listed dependencies to the require path. With stdlib (the default) all stdlib is available in the require path. Would a travis image with all supported crystal versions preinstalled help? Tests could run against all available or a listed set. Should there be tooling to aggregate the test results for all packages in a single place or will the existing ci infrastructure work? |
True.
This can be done without splitting the repo and the corresponding downsides. Can also be done more granularly.
And is that a good thing? If there is no HTTP client that maintains its API, what are people supposed to use?
If you mean that ignoring problems is a simplification, sure. In fact, with how PRs don't get merged, it's already pretty simple :)
Maybe the particular reason you provided is true, but I'm pretty sure that overall it will complicate things. Even starting with things like backwards-incompatible changes, though thankfully those are handled decently now.
True, but moving code to a different git repository shouldn't completely correlate with dropping all conservatism and is also not necessary for it. |
Do you have a complete solution for long term maintenance and incremental upgrades? How do you upgrade only There's also the question of whether Manas will give more people write access to crystal-lang/crystal. I suspect they don't want to which may require a split to get more contributors. |
With split stdlib if you really need old HTTP functionality you can have it by setting the version. There's additional flexibility for forward of backward versions. With that flexibility API's can evolve without pissing off as many people. Most of the complexity you worry about can be automated for crystal core developers. It doesn't concern end user developers. (Is that a term?) They still install crystal the same way they did before mostly via package managers. |
I assume the current release process is:
The shell script will get more complex to handle the split but the release process will probably stay the same. |
This is an issue about removing modules from the standard library, not splitting it up into multiple git repositories. Please create another issue about that as they are different problems. But please be aware that it'll never happen, as it creates a bunch of migratory work for the core team for almost no benefit over the code maintainers model oprypin mentioned. I don't even think crystal is large enough for that model yet. The problem is a social organisational problem, with crystal, it's community, and mostly the core team. Treating it as a technical problem won't give the correct solution. |
I think this issue can be closed. The stdlib has been consolidated since this started, and we have reached a good compromise between batteries-included and unnecessary baggage. |
This issues is very controversial, but it was never really discussed in the past.
I've been thinking more and more about moving out pieces of the standard library to shards. Examples of these are the
YAML
andXML
modules, though we could include more modules (CSV
,Zip
,Big*
, maybe evenHTTP
).These shards will most probably live under the
crystal-lang
organization, so they will be kind of "blessed".The pros of doing this are:
YAML
would have been a shard, we could already have the new functionality without having to wait for a next compiler release.libxml2
that comes with Debian 7 doesn't work in Crystal. Specs weren't (and aren't) passing there. But nobody complains, so maybe nobody uses Debian 7 anymore, or maybe nobody uses Crystal+XML in Debian 7. If XML were a shard, we wouldn't have to worry about all of this (well, yes, but not in each release, we could solve this faster and better), and we would have 0.24.0 some weeks ago.Of course there are cons too. These are:
require "xml"
we now have to write ashard.yml
, add the xml github repo, runshards
, etc.I have replies for these 3 points.
crystal-lang
organization, they are easy to find (if we put them somewhere in the docs saying these are "blessed"/recommended shards). The only inconvenient part is writing the dependencies inshards.yml
, but I wouldn't use this as the only reason not to go with this.crystal-lang
organization hosts "blessed", well-maintained, up-to-date shards, then hopefully people will look there before someone else (stars in a GitHub repo might do the trick as well for internet searches).HTTP::Client
in the standard library, people go and create others, like cossack and crest. Of courseHTTP::Client
is missing fundamental stuff like redirections but there's not enough man-power to tackle this. Moving it to an external shard would make collaboration much easier as more people could join, and it could evolve faster.Basically, I'd like to move almost everything that the compiler doesn't use to a shard.
If we agree on this, we could discuss doing so for individual modules.
I believe Crystal should come with a standard library that mostly doesn't depend on external C libraries (it's a bit impossible, but the less, the better), and one that provides a foundation for other libraries to build on top of it. Examples of that are
IO
, which is evented by default; the runtime, with its concurrency model,spawn
,Channel
, etc.;Array
,Hash
andRegex
, which are a core part of the language, mainly because they are tied to literals; and probably other types for similar reasons.The text was updated successfully, but these errors were encountered: