I find myself constantly needing to look up the documentation for io and io/ioutil to figure out which package contains the thing I want to use.
The root of the problem is that ioutil isn't a coherent abstraction boundary. The suffix util doesn't add any information — if a package has no utility, it should not exist! — and the remaining information in the package name doesn't distinguish it from io. (See also the "Bad package names" section of https://blog.golang.org/package-names.)
From what I can tell, the main purpose of separating out ioutil is to reduce the dependencies of io: specifically, the dependencies on bytes, os, and sort.
In a potential Go 2, I propose to resolve those dependencies by refactoring the ioutil package as follows:
-
Move Discard, NopCloser, and ReadAll into package io:
NopCloser has no dependencies.
Discard depends on sync, which io already depends on.
ReadAll uses a bytes.Buffer internally, but doesn't actually need very much of its API; it can be rewritten easily to avoid that dependency.
-
Move ReadDir, ReadFile, TempDir, TempFile, and WriteFile to a new package, io/fileio.
- Rename them to omit the (now-redundant)
File suffix: fileio.Read instead of ioutil.ReadFile.
I find myself constantly needing to look up the documentation for
ioandio/ioutilto figure out which package contains the thing I want to use.The root of the problem is that
ioutilisn't a coherent abstraction boundary. The suffixutildoesn't add any information — if a package has no utility, it should not exist! — and the remaining information in the package name doesn't distinguish it fromio. (See also the "Bad package names" section of https://blog.golang.org/package-names.)From what I can tell, the main purpose of separating out
ioutilis to reduce the dependencies ofio: specifically, the dependencies onbytes,os, andsort.In a potential Go 2, I propose to resolve those dependencies by refactoring the
ioutilpackage as follows:Move
Discard,NopCloser, andReadAllinto packageio:NopCloserhas no dependencies.Discarddepends onsync, whichioalready depends on.ReadAlluses abytes.Bufferinternally, but doesn't actually need very much of its API; it can be rewritten easily to avoid that dependency.Move
ReadDir,ReadFile,TempDir,TempFile, andWriteFileto a new package,io/fileio.Filesuffix:fileio.Readinstead ofioutil.ReadFile.