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
.
File
suffix: fileio.Read
instead of ioutil.ReadFile
.io.ReadFull / ioutil.ReadAll pair is especially frustrating.
To take the logic a bit further with respect to removing chattiness, how about (or: why not?) one step further: io/file
instead of io/fileio
. Then it's file.Read
instead of fileio.Read
. file
and io
together seem tautological. Especially when you throw in Read/Write, etc.
Sounding them out: file.Read
, file.Write
, file.Temp
, file.ReadDir
, file.TempDir
, etc. Side thought: Maybe the latter two would read better as dir.Read
and dir.Temp
, if there was a io/dir
package?
There may be good arguments for io/fileio
instead of io/file
? One that comes to mind is that people might want to call variables dir
and file
. Not sure if that's a much of a problem in practice or not.
One that comes to mind is that people might want to call variables dir and file. Not sure if that's a much of a problem in practice or not.
Looks like this will be a huge problem, same as net/url
or path
.
There may be good arguments for
io/fileio
instead ofio/file
? One that comes to mind is that people might want to call variablesdir
andfile
. Not sure if that's a much of a problem in practice or not.
I agree with @cristaloleg: this is absolutely a problem in practice. file
and dir
are incredibly common, useful variable names. To quote the Package names blog post from 5 years ago:
Don't steal good names from the user. Avoid giving a package a name that is commonly used in client code. For example, the buffered I/O package is called
bufio
, notbuf
, sincebuf
is a good variable name for a buffer.
Should this proposal be closed because of #42026 ?
Yes, thanks.
Most helpful comment
To take the logic a bit further with respect to removing chattiness, how about (or: why not?) one step further:
io/file
instead ofio/fileio
. Then it'sfile.Read
instead offileio.Read
.file
andio
together seem tautological. Especially when you throw in Read/Write, etc.Sounding them out:
file.Read
,file.Write
,file.Temp
,file.ReadDir
,file.TempDir
, etc. Side thought: Maybe the latter two would read better asdir.Read
anddir.Temp
, if there was aio/dir
package?There may be good arguments for
io/fileio
instead ofio/file
? One that comes to mind is that people might want to call variablesdir
andfile
. Not sure if that's a much of a problem in practice or not.