Could you perhaps flesh out the motivation?
I think itād be nice to have the option to keep module files colocated in the same place, in general
I donāt understand if thatās a motivation of the proposal or a description of the status quo. I suppose I donāt understand it because I donāt understand what ākeep module files colocated in the same placeā means.
itās also a minor annoyance when browsing GitHub, and GitHub puts all directories above files, so you have to scroll up and down when navigating between
X/Y.hs
andX/Y/Z.hs
.
I donāt find it particularly convincing that we need to introduce a new module location scheme in onder to avoid minor annoyances with the Github file viewer!
Iād imagine the pushback will be āyou can just re-export all modules in a subdir - this is a known idiom.ā But maybe the idiom popular enough that it merits some automation?
Can this be first implemented as a plugin?
You can do that without a plugin:
@tomjaguarpaw sure I can flesh out the proposal more later. But to answer your question, by ācolocatedā, I mean in the same directory, e.g.
-- current
Foo.hs
Foo/Bar.hs
-- proposal, would act the same as current
Foo/Mod.hs
Foo/Bar.hs
Yes, the GitHub comment is certainly not enough to drive the whole change, itās just a bonus to the overall proposal. I had assumed people have experience with Rust or Typescript, which use this idiom extensively, but perhaps I shouldnāt assume that. Hereās a more concrete reason:
I like to have my tests match the same module structure as my source code. If I want to test a module and a submodule, I have to do
src/Foo.hs
src/Foo/Bar.hs
test/FooTest.hs
test/Foo/BarTest.hs
Itās a little awkward that Foo/BarTest.hs is testing a submodule under the module FooTest.hs is testing.
The proposal would allow
src/Foo/Mod.hs
src/Foo/Bar.hs
test/Foo/ModTest.hs
test/Foo/BarTest.hs
Which makes it much clearer that ModTest.hs and BarTest.hs are testing behavior in the same area. The module names will be a bit different (Foo/Mod.hs => Foo, Foo/ModTest.hs => Foo.ModTest), but Iām willing to live with that.
@Ambrose thatās a bit different from what Iām proposing. I donāt want Mod.hs to reexport everything in all submodules. The same way you might implement some stuff in Foo.Bar and break out some helpers into Foo.Bar.Baz, I want the same thing, except putting the file containing Foo.Bar in the same directory as Foo.Bar.Baz.
@taylorfausak yes, that preprocessor does what @Ambrose suggested, but not what Iām asking for. I want to change the compiler to automatically find Foo/Bar/Mod.hs for an import Foo.Bar when Foo/Bar.hs doesnt exist.
Is it? Why?
š¤· Call it personal preference.
This concept is just pretty widespread in other languages, and I miss it every so often in Haskell, and was wondering if anyone else feels similarly. Seems like probably not
For what itās worth, I do. I doubt the Haskell community will want to flex on this for such a minor benefit as āconvenience of people clicking around unfamiliar projectsā, but I am also inconvenienced when Iām rifling through SomeProject/Frobber/
searching for the reason something is being frobbed in an unexpected way, only to find that I needed to jump up a level to read SomeProject/Frobber.hs
.
ā¦like the old WWW custom of having an index.html
file in directories so that:
https://www.example.org/look/here/
is expanded to
https://www.example.org/look/here/index.html
ā¦?
Agreed - itās their problem, so let them solve it (or provide a patch). We already have enough āconveniencesā to quarrel over e.g:
> chdir that/path/to/SomeProject/Frobber
> view ../Frobber.hs
ā¦?
Correct. As I said, an inconvenience, not a blocker.
This simply doesnāt match how directories are used most of the time, outside of module systems that resemble Haskellās. If I told you I have a taxes
directory, with files taxes/2020.pdf
, taxes/2021.pdf
, taxes/2022.pdf
, etc., where would you expect to find a text file that contains data spanning multiple years? In taxes/all-years.txt
? Or taxes.txt
alongside the taxes
directory? If I told you that system service vorpal
writes error logs to /var/log/vorpal/error.log
, where would you be more surprised to see non-error, normal operation logs? /var/log/vorpal/info.log
, or /var/log/vorpal.log
?
Tools like ripgrep will automatically search for their needles recursively in the directory you are in, or in the directory you specify. They donāt reach out to the parent directory, look for a file whose base name matches your current directory, and search there too. Why would they?
So if Iām in SomeProject/Frobber
, of course I can manually run rg "some text" . ../Frobber.hs
, if I remember to. I can also spend five minutes writing a shell function that I train myself to use in place of rg
that does this for me. I can do any number of things to work around this minor inconvenience. But the OP thought he might be alone in experiencing it, and he isnāt.
Questions:
-
if
AnotherProject/Blagger/Mod.hs
, already exists, what happens then? -
If
Mod.hs
is the only file inSomeOtherProject/Grebber
, should:SomeOtherProject/Grebber/Mod.hs
be considered āthe same asā :
SomeOtherProject/Grebber.hs
ā¦?
My idea was to only fallback to Foo/Bar/Mod.hs if Foo/Bar.hs does not exist. And one could still explicitly import Foo.Bar.Mod
if they wish
And yes, Mod.hs works independent of any other file. Literally the only change would be changing the behavior from
let f = replace "." "/" importMod <> ".hs"
to
let f' = replace "." "/" importMod
f <- bool (f' <> "/Mod.hs") (f' <> ".hs") <$> doesFileExist (f' <> ".hs")
Making a toolchain chain to appease a MS-funded tool is totally silly. Talk about putting the horse in the cart and giving it the reins lmao.
ā¦and no doubt it only took a few patches/s for do
notation to āgo viralā too. Moreover, this to me looks far too similar to how Subversion worked back in āits heydayā - one .svn
sub-directory for each directory of a codebase it managed. So itās bemusing to be told that other presumably-newer languages are now (to an extent) following Subversion in that way.
I donāt personally see the benefit of this specific change, but I do like the idea of being able to separate the concern of āwhere the file is on a filesystemā from the concern of āwhat Haskell module does this file containā. I suspect that belongs in a build too though, not GHC. (Maybe some tool already has it. I donāt know.)
Where have I encountered this idea beforeā¦thatās right, it was here:
Sigh ā¦ I also still (still!) get tripped up by logically related modules getting forced into different directories, and would probably use something like Mod.hs if it existed.
That said, there is a certain simple usefulness in modules corresponding 1-1 with the directory tree, and the proposal is a change thatās too disruptive to the ecosystem to have legs.
On the upside, no tooling support is required if you simply stop using Foo directly and only use Foo.Mod I might try something like that some timeā¦
Sigh ā¦ I also still (still!) get tripped up by logically related modules getting forced into different directories, and would probably use something like
Mod.hs
if it existed.
If theyāre that ālogically relatedā, could you just move such modules to their own (sub)directory?
[ā¦] no tooling support is required if you simply stop using
Foo
directly and only useFoo.Mod
[ā¦]
ā¦but will you be happy with staring at the ".Mod"
suffix on every third, fourth or fifth import
everywhere? For a while, Rust had a reserved word (but for a different purpose) and it was eventually removed due to overuse, to the point of being irrelevant:
https://mail.mozilla.org/pipermail/rust-dev/2013-April/003926.html
Alternatively, how many here thought -XBlockArgument
āseemed reasonable at the timeā ?
Iām confused. Your first two paragraphs seem to contradict each other, or at least lead directly to the solution which youāve been arguing against. That is, tooling support for having logically related modules in the same directory, without requiring one of them to have a suffix in the module name.
Maybe that Mozilla link would make things clearer, but itās broken.
Also, I continue to think BlockArguments
is reasonable, and donāt seriously expect anyone to abuse it as in the thread you linked. So Iād say any parallels are a stretch.
Like @chreekat, Iām sympathetic to this idea, and would probably use it if it became standard, but Iām not sure itās worth the hassle.