Sorry I misread your first positive changes regarding
text not being readily available. I thought there was something special about
bytestring that makes it more available than
text without being part of base.
Sorry I misread your first positive changes regarding
The immediate technical challenge is text-2.0.1: dependencies | Hackage. Do we expect to fold every (transitive) dependency into
I think making
cabal init to add
build-depends for new projects would give most of the benefits for almost zero costs.
A modern language should have a proper packed textual type in its standard library. This is a matter of straightforward pragmatism. Since Haskell doesn’t currently have that, frankly I’d be embarrassed to recommend it as a language useful for serious work. I just don’t understand the opposition. Can you imagine if the Rust people were talking about splitting
String out of
std into a separate library? I’d assume they’d lost their minds.
I was not aware that
cabal init supports choosing alternative Preludes interactively through mixins. Did I miss something? Or you misread my comment?
Why not all boot libraries?
Not all, but I’d be in favor of these: base, binary, bytestring, containers, deepseq, directory, exceptions, filepath, mtl, process, stm, text, time, and transformers.
In particular I wouldn’t add
parsec because they aren’t the most popular libraries in their domain any more. Instead we could add
megaparsec, but I personally think vector is too complicated and megaparsec is too specific to always be included. Personally I prefer
primitive) for arrays, but that package isn’t very popular yet (and it currently has quite a large amount of transitive dependencies).
Misread your comment indeed.
If we move
text and possible other libraries directly to
base this will affect the development process, so I quite like the idea of having
standard library which wraps multiple libraries. Does anybody know how haddock presents re-exports? I think it does the right thing (although I am not 100% sure), if it does then
standard would be a sensible step forward. We’d only need to move
base if we want to change the representation of
String at the same time, but that might be quite difficult anyway right now. Anyway I’d be happy with either choice.
This makes a lot of sense as well. It’s a bit dumb that a vanilla
ghci session has access to
cabal repl after
cabal init suddenly pretends to know nothing about boot libraries.
One more avenue to explore is to split
text-type, providing only
data Text with instances, and
text proper, providing everything else. In this case it’s likely that only
text-type should remain a boot package, because the only other consumers of
parsec, both for superficial reasons. If the resulting
text-type appears slim enough, in future one could discuss merging it into
Just to be clear: I’m not going to put my efforts into any of this, treat it as a cheap talk
I have a take on a different solution RE: adding core libraries at cabal init, but it’ll be up to cabal developers to know how feasible it is.
(1) the problem I see with the current “just base” setup is that when starting a project, I don’t know which libraries I’ll need. By the time I need text, I
import Data.Text but then there I have to go add text to the packages. Then the same thing happens for
import Data.Set, etc… This cost varies across domains, and while for me it’s repetitive boilerplate work I can see it be more problematic when e.g. teaching Haskell!
(2) the problem I see with the solution to “add all core libraries at cabal init” is that I want my dependencies to match the things I’m using. If we starting adding them all by default I would eventually prune the dependencies of the project before e.g. publishing (I wouldn’t want my haddock dependencies list to be unnecessarily large). If big enough, I can imagine I’d just comment all and re-add them by compiler need, as I wouldn’t remember which ones are being used, and would end up doing the boilerplate work I was trying to avoid in the first place.
My proposed solution that addresses (1) and (2) is a mechanism we’re already familiar with implemented in cabal:
Previously, if I had a cabal project with a module
A and imported a new module
B from it:
module A where import B ...
When compiled it would fail unless I added
other-modules: B to the project.
However, this was fixed and now we have it quite nice. If we compile
A without adding
other-modules, we’ll get a warning:
<no location info>: warning: [-Wmissing-home-modules] These modules are needed for compilation but not listed in your .cabal file's other-modules: B
And this exact mechanic is what I think might be a good solution for our case.
The solution concretely:
I say (if possible) it would be great if I could from anywhere in my project
import Data.Text and
import Data.Map – everything would work – and I would simply get a warning:
<unlisted package info>: warning: [-Wunlisted-core-package] These core packages are needed for compilation but not listed in your .cabal file's dependencies: text, containers
This doesn’t address the issue of a standard library which doesn’t require extra imports for things like a Map and a good textual representation. It doesn’t address the fact base functions still can’t rely on
Text. But I think it’s a nice compromise between not having any help from cabal and adding all core libraries on
RE: @rae 's
standard: It’s a good idea, but would say it has to be backed by the haskell foundation/ship with GHC. Otherwise isn’t it just another alternative prelude?
While I can understand the necessity of having the requirement of having qualified imports for third party libraries to alleviate a lack of extensibility, it should not be the default design whenever there are part of the same library.
You’ll coupled all subsequent libraries to the underlying compiler implementation, which may cause maintenance issues in the long run.
For the purpose of understanding the pros and cons of this decision better, it could be helpful to look at history. In 2007, when GHC 6.8.1 was released, packages
directory and many others were split from
base into separate packages.
I haven’t found the discussion with the reasons for the split. But I thought it would be interesting to know why this happened. Otherwise, it looks like just going circles: first we split things then we move them back. Lots of time was wasted and we stayed in the same spot.
Of course, circumstances and limitations may change and the situation in 2022 might be different from 2007. In that case, it would be interesting to know what has changed
…since 6.8.1, has there been any other transfers of code away from
base into other boot-libraries? If not, then comparing it to the current version of
base could help to determine how things have (apparently) “gone awry”.
This information may not be able to help in salvaging
base, but it could help to avoid making (most of) the same mistakes, if it’s impossible to practically separate GHC and
base and the two have to be rebuilt.
“there’s only two ways I know of to make money: bundling and unbundling.”
How much pain would be removed if
cabal offered to edit your
.cabal file to add the missing package
build-depends if it sees you trying to import a module from a package you aren’t depending on?
$ cabal build [snip...] app/Main.hs:3:1: error: Could not load module ‘Data.Text’ It is a member of the hidden package ‘text-22.214.171.124’. | 3 | import Data.Text | ^^^^^^^^^^^^^^^^ Automated fixes are available. Would you like to: 1. Do nothing 2. Add `build-depends: text ^>=126.96.36.199` to the target `app` -- One of these for each `common` stanza imported by the target being built 3. Add `build-depends: text ^>=188.8.131.52` to the common stanza `deps` Enter choice : 2 Successfully updated `foo.cabal`; attempting rebuild.
Perhaps only show these hints if
cabal is being run interactively, so that other build tools don’t get tripped up by a subprocess waiting for input?
I believe that much of the frustration in this thread would be solved by (either of):
- Adding better default packages to
cabal init(with an optional
- Having HLS suggest adding new packages when importing from a hidden package
There is already progress for (2) in HLS, and I encourage people to send some emojis/love to the relevant PR: https://github.com/haskell/haskell-language-server/pull/2954
(1) seems like a good thing to do. Please add feedback/support on the new issue in Cabal.
Let’s push for either of these solutions. We can always find the right solution after we pick the low-hanging fruit.
Also: a much hotter point of cabal frustration is module discovery. I encourage everyone to read the thread here and add thought to the conversation so that progress happens!
This is not generally a job for cabal (which afaik does not know about type checking errors that come from GHC). But it’s certainly reasonable for HLS to handle.
I don’t understand what this means. Boot libraries are already coupled to GHC versions: version history · Wiki · Glasgow Haskell Compiler / GHC · GitLab