scala-library-next icon indicating copy to clipboard operation
scala-library-next copied to clipboard

Proposals for naming and package structure

Open NthPortal opened this issue 5 years ago • 25 comments

Proposals:

  1. Only names that are planned to exist in a future Scala release can be outside of a next (sub-)package. Names that will not exist in a future Scala release MUST be in a next (sub-)package. a. Corollary: Extension methods MUST go in next (sub-)packages. b. Possible extension: All names that are planned to exist in a future Scala release MUST be outside of next (sub-)packages.
  2. Extension method value classes SHOULD be named Next<Name>Extensions, where <Name> is the name of the type. a. For example, extension methods for LazyList would go in value class named NextLazyListExtensions. b. Extension method value classes for an object that is a companion SHOULD be named Next<Name>CompanionExtensions. c. Extension method value classes for general collection types (e.g. Map, Set) should have have a prefix to <Name> that is the first letter of each package segment (e.g. NextSCISetExtensions for scala.collection.immutable.Set)

Something something RFC 2119

NthPortal avatar Oct 26 '20 00:10 NthPortal

Names that will not exist in a future Scala release MUST NOT be outside of a next (sub-)package.

The triple negation was very hard for me too read, and I understood it the wrong way the first two times I read the sentence. Perhaps consider:

-Names that will not exist in a future Scala release MUST NOT be outside of a next (sub-)package.
+Names that will not exist in a future Scala release MUST be inside of a next (sub-)package.

sjrd avatar Oct 26 '20 03:10 sjrd

I don't know why that slipped by me. yes, fixed

NthPortal avatar Oct 26 '20 03:10 NthPortal

@NthPortal How should the object holding the value class be named? Just <Name>Extensions? So for example, if I want some additional methods on LazyList I would import scala.collection.immutable.next.LazyListExtensions._?

BalmungSan avatar Oct 26 '20 16:10 BalmungSan

IMO, it can go directly in the package object.

NthPortal avatar Oct 26 '20 18:10 NthPortal

@NthPortal so importing next._ would import all extensions?

BalmungSan avatar Oct 26 '20 19:10 BalmungSan

correct. and if you wanted to import just one, you'd import next.NextLazyListExtensions or whatever

NthPortal avatar Oct 26 '20 19:10 NthPortal

Having to import next.something would mean that cross-building 3.0/3.1 won't be possible unless we ship this with empty next instances for 3.1. that'd be lame.

martijnhoekstra avatar Oct 26 '20 19:10 martijnhoekstra

then just import next._

NthPortal avatar Oct 26 '20 19:10 NthPortal

would -Yimports:... be helpful here, when cross-building? as a way of allowing the imports to be different in different Scala versions, as needed, without the user having to alter their actual source code? (cc @som-snytt)

SethTisue avatar Oct 26 '20 19:10 SethTisue

Then you'd still need to ship a version with an empty next package for 3.1. which means inflicting the transitive dependency on your dependents.

That can be sort of worked around with people taking a provided dependency for 3.1.

martijnhoekstra avatar Oct 26 '20 19:10 martijnhoekstra

Having to import next.something would mean that cross-building 3.0/3.1 won't be possible unless we ship this with empty next instances for 3.1. that'd be lame.

I think that shipping empty next instances is exactly what we'll do.

Anyway, they probably won't stay empty as we then start adding new stuff coming in 3.2 or later.

sjrd avatar Oct 26 '20 19:10 sjrd

Julien suggested on https://github.com/scala/scala-library-next/issues/25 that there wouldn't be 3.2 stuff in this library.

Per version -Yimports is probably at least as invasive/cumbersome for users as having the lame dependency on the empty next package and declaring it provided for 3.1.

martijnhoekstra avatar Oct 26 '20 20:10 martijnhoekstra

I've noticed we still have a shadowing problem for names which appear in multiple packages (e.g. Set, Seq), so I've updated the proposals to account for that

NthPortal avatar Nov 02 '20 01:11 NthPortal

Did you come to a conclusion about this?

So I could update #23 and open a follow up for groupByTo & groupMapTo

BalmungSan avatar Nov 19 '20 17:11 BalmungSan

Vote by reacting to this comment (see the following comment for more granular votes)

In favour of (👍) or against (👎) proposal 1 in its entirety

In favour of (🚀) or agains (👀) proposal 2 in its entirety

NthPortal avatar Nov 20 '20 00:11 NthPortal

Granular votes (by reacting):

In favour of proposals 1 and 1a but against 1b (👀) In favour of proposals 2 and 2a but against 2b (👎) In favour of proposals 2 and 2a but against 2c (😕)

NthPortal avatar Nov 20 '20 00:11 NthPortal

This all looks good, except I don't know what I think about 1b. What are the pros and cons there?

SethTisue avatar Nov 20 '20 00:11 SethTisue

I'll give an example of something that 1b affects.

Currently, scala.collection.concurrent.Map does not have a companion, unlike other Map types (see scala/bug#12115). We cannot add it in that package in scala-library-next, because the companion needs to be in the same compilation unit. If we were to add such a companion, it would have to be an object Map in package scala.collection.concurrent.next; however, that would violate 1b.

If we were to reject 1b and add s.c.c.next.Map, we would need an alias val Map = s.c.c.Map in package s.c.c.next in the Scala 3.1 version of this library, and couldn't just have an empty package.


As I see it,

Pros: simplicity

Cons: reduces the total set of possible changes/fixes/improvements

NthPortal avatar Nov 20 '20 01:11 NthPortal

the current proposals only take into consideration the naming of the implicit value classes, but [do] not define where they should be defined.

These proposals also make some constraints on what MUST go in a next (sub-)package, and perhaps what MUST NOT as well.

As I said before, I do not [...] think that having all of them in the package object to be a good idea, the file will be pretty big and searching for the implementation of a particular method would be difficult.

By all means feel free to create a proposal that specifies that. These proposals were not intended to specify everything that needs to be decided about the library's structure.

It's worth noting that value classes MUST live inside (top-level) objects, so having them split up necessitates a separate wrapper object for each extension method value class.


Only names that are planned to exist in a future Scala release can be outside of a next (sub-)package. Names that will not exist in a future Scala release MUST be in a next (sub-)package.

AFAIK the idea is that if something will not exist in a future scala version (or it is still not clear if it should be part or not of) then it shouldn't be here in the first place.

I was very deliberate with my wording. Names that will not exist in a future Scala version have to be in a next (sub-)package. For example, since 3.1 will not have the name NextLazyListExtensions, that value class/extension MUST be in a next (sub-)package. I said "names", not "things".

The reason 1a is a corollary is because, at least using Scala 2 syntax, extension methods require a value class and an implicit conversion to it (which are usually combined as in an implicit value class), both of which are names that are not intended to exist in a future Scala version. Thus, they MUST be in next (sub-)packages.

a. Corollary: Extension methods MUST go in next (sub-)packages.

I would also add this to the second proposal.

Proposal 1 is about package structure; proposal 2 is about the naming of value classes for extension methods. That's why 1a is where it is. Additionally, 1 strictly implies 1a; they are inseparable.

Also, I'm not sure why a particular item should be proposed twice.

NthPortal avatar Nov 20 '20 03:11 NthPortal

Isn't that what I did here and that I repeated here

I meant a separate issue/ticket

// file: src/main/scala/scala/next/Next<Name>Extensions.scala

package scala.next

private[next] final class Next<Name>Ops[A](private val col: <Name>[A]) extends AnyVal {
  // Extension methods go here.
}

Scala 2 does not permit top-level value classes

NthPortal avatar Nov 20 '20 19:11 NthPortal

I meant a separate issue/ticket

Isn't this issue for all the proposals and choosing one?

Scala 2 does not permit top-level value classes

Ham yes it does, you are confusing it with implicit classes, that is why the implicit conversion is in the package object. This is a simplified version of what libraries like cats or neotypes do.

BalmungSan avatar Nov 20 '20 19:11 BalmungSan

yes it does, you are confusing it with implicit classes

you're right, my mistake

Isn't this issue for all the proposals and choosing one?

no. it's an issue for the 2 proposals (and their sub-proposals/extensions) listed in the issue description. also, again, the proposals in this issue's description are not options, one of which gets chosen. they are two independent proposals, each to be accepted or rejected individually.

NthPortal avatar Nov 21 '20 00:11 NthPortal

I meant a separate issue/ticket

Done #46

no. it's an issue for the 2 proposals (and their sub-proposals/extensions) listed in the issue description. also, again, the proposals in this issue's description are not options, one of which gets chosen. they are two independent proposals, each to be accepted or rejected individually.

Yeah yeah, my point was that my proposal was also complementary with yours, so I thought it made sense to be in the same issue, but ok.

I also deleted all my comments in this issue that I believe are no longer relevant.

BalmungSan avatar Nov 21 '20 16:11 BalmungSan

follow-up at #46

NthPortal avatar Nov 22 '20 02:11 NthPortal

I propose that we don't wait on finalizing this and #46 to merge PRs, and we can just refactor the library once we've decided on those.

NthPortal avatar Mar 17 '21 17:03 NthPortal