The only thing I hate in purescript and haskell - imports (discussion)

I completely agree that the fact that modules from different packages can conflict and that it’s impossible to tell what package a module comes from are both serious problems which need addressing. This is why I made the issue https://github.com/purescript/purescript/issues/2437 - we haven’t quite reached an agreement there, the devil is in the details. The migration is admittedly going to be painful, but with the CST parser and printer it hopefully won’t be too difficult to automate.

4 Likes

good

the psc 'src/**/*.purs' --package 'prelude:.psc-package/0.10.5/prelude/src/**/*.purs' is almost what I proposed


and I dreamed about

provide syntax sugar so that import prelude becomes, say, import prelude.Default , and encourage libraries to always provide a Default module

I always hated the directory structure

| Foo/
  | Foo1.purs
  | Foo2.purs
| Bar/
  | Bar1.purs
  | Bar2.purs
| Foo.purs
| Bar.purs

and wanted to write about

| Foo/
  | Foo1.purs
  | Foo2.purs
  | Default.purs
| Bar/
  | Bar1.purs
  | Bar2.purs
  | Default.purs

too, but decided that it would be too much


@hdgarrood, what do you think about module names should be derived from path automatically proposal?

I think the benefit of getting rid of the module Whatever where syntax is less obvious, and is too big a breaking change to be justifiable to me.

2 Likes

After seeing Harry’s issue, I’ve moved to the dark side. If we’re gonna replace the Data prefix and its fellows, I’m all for it. I was originally against it because @srghma’s code sample has a lot of repetition in its imports. So you may want to change your example @srghma.

2 Likes

Make module name derivable from path

Here’s what I currently have in my learning repo:

module Syntax.Basic.Foo where
--

via the file Syntax/src/Basic/01-Learn-Foo.purs

Shifting to your proposal would break my repo’s syntax folder as Syntax.Basic.01-Learn-Foo isn’t a valid module name. If hyphens were dropped and numbers could be included, it would no longer be a problem.

1 Like

I want to also add this post that saw about 4 months ago complaining about package, and I do agree with what the author’s argument here. I also like a lot of some of the points that @hdgarrood pointed in his github issue.

Looking at the issue, there seems to be a solution for most cases except for some possible edge cases that we might be missing. Now, I feel there is a bit resistance when it comes to aesthetic and also not wanting to be aware of the package when importing modules.

Personally, I think that the voting system that @srghma is proposing is good first step. If we don’t vote on it will just be another floating issue. I think that it’s important that we agree about the package system earlier on before 1.0 - whether you like or not its important that it’s clear early on.

Would it not be better if we collect all the points in this post and then create a separate post for votes? Of course, the voting post would display all the points.

1 Like

Wow, actually I was thinking too why not enforce domain for packages (e.g. @core/prelude), and right, there is a Java that do this

Updated proposal

Will do polls later

moved proposal to the top

added polls The only thing I hate in purescript and haskell - imports (polls), tell if you have more poll points

1 Like

I think we can get most of the benefit of package-qualified imports by requiring, that published packages have the top-level module be the package name.

Data.Functor from purescript-prelude would become Prelude.Data.Functor
etc.

Some packages already do this:
Affjax.RequestBody from purescript-affjax is already Affjax.RequestBody

That way we don’t need to break all purescript code, but still get the benefits

We started on this path already, although admittedly we didn’t go very far down it - this is why Effect lives in a module just called Effect rather than Control.Monad.Effect or whatever. I am not such a fan of this approach though, because it doesn’t solve the issue as neatly, but it would still be more or less equally big a breaking change as changing the language - if the majority of the libraries you depend on have breaking changes (renaming a module is a breaking change) that can be just as disruptive as the language itself having a breaking change.

The problem with a rule about translating package names to module names is that the translation isn’t always obvious and we would need tooling to enforce the convention if it was going to catch on. For example, a module in the strings-extra should be StringsExtra.Whatever, not Strings.Extra.Whatever, but the latter style is already common for extending an existing library, so I’m sure people would keep using that style unless we had tooling telling them not to.

1 Like

@srghma, it sounds like you’re in hurry with this. Why are you? If you like this solved then just starting discussion like this is kind of a great thing and you’re welcome to do so. Though you could relax a bit and let us (and maybe help us) find the best way to do a module system that we know of at the moment.

3 Likes

relax a bit and let us find the best way to do a module system

What this even means? I cannot write?

and maybe help us

Am I not doing this?

If you have your own vision - tell me. Right now you sound like a gatekeeper

1 Like

I had difficulty expressing it. I think it should have been “we’ll figure out”. That DuplicateModule -error needs to go like you said in the start. Btw. Albert Y. C. Lai told me a potential known solution to it and I would have not known to ask if you had not written this post.

I have no vision about this one. However I see that you hate what Purescript offers you right now with module/import declarations, and I do not hate it as much.

Why I’m unable to hate purescript’s module/import system is because I know this problem is very hard, and that purescript community figures out how to do it right eventually. Who knows perhaps you’ll figure it out, at least you’ve helped it out.

Well… I have one thing to say. That you don’t see implementation names in the import declarations might be a feature, given that your problem with them is solved. Those things separate the interfaces from their implementations. This could be useful since purescript has multiple target platforms, Javascript is only the one of them.

@srghma I found this issue https://github.com/purescript/purescript/issues/3493 in the “Intend to Implement” section, I think that it’s related. I see that a few have already voted, maybe we need to post it on slack in order to get more votes.

The next step is to understand in detail the changes needed - I think that it will help the maintainers or whoever is capable of implementing and it will keep this issue from just floating.

Since I am not too sure of the procedures myself, a goal that seems realistic to me is to try and see if we can move this issue to a stage where there is a potential agreement based on the vote and the details that the maintainers/implementer might need.

That you don’t see implementation names in the import declarations might be a feature, given that your problem with them is solved. Those things separate the interfaces from their implementations.

could you explain more

This could be useful since purescript has multiple target platforms, Javascript is only the one of them.

I cannot imagine a language that couldn’t support

import "@noname/other-strings/String" as OtherString

added a comment to the issue you posted

maybe we need to post it on slack in order to get more votes

I could, but I don’t want to bother, tnx anyway

to try and see if we can move this issue

I have mentioned in comment, let’s see how it goes

Just so you know, this issue is unlikely to get any real maintainer attention until (at the very least) after 0.14 is out.

3 Likes

@srghma My two cents about this detail:

I always hated the directory structure

and wanted to write about

Since PureScript doesn’t enforce module names matching the directory structure, you can actually have whatever structure you want. For example, you could have the Default.purs file under Foo/, but write module Foo where at the top of that file.

Personally, I’ve been using structure like this:

| Foo/
  | Foo.purs   -- module Foo where
  | Foo1.purs  -- module Foo.Foo1 where
  | Foo2.purs  -- module Foo.Foo2 where
| Bar/
  | Bar.purs
  | Bar1.purs
  | Bar2.purs
1 Like

You pointed out that when you import a module.

import Data.String.Extra

Then you’d have to do spago install strings-extra but it requires you to remember this and I agree this is an annoying thing having to recall.

Ok. I’ll explain more about the interface/implementation separation.

If you have function, eg. camelCase :: String -> String, this is an interface that lives in Data.String.Extra

The strings-extra is an implementation, a means to fill up the module Data.String.Extra. However something else can do this fill-in as well.

This is a generic system and if we look at something else like DOM interface or alternatively SDL or OpenGL. Depending on your target platform, different libraries might fill these up, or same library need to be configured differently.

Now I do not know if you’re right and we should just do it your way. Your proposed syntax at least could coexist with the old syntax.

1 Like