Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to use underscore symbol _ instead of * to define anonymous type lambdas #188

Merged
merged 5 commits into from May 15, 2021

Conversation

neko-kai
Copy link
Contributor

@neko-kai neko-kai commented May 7, 2021

== Dev Notes

This PR depends on the following scalac changes:

To be widely applicable (without these changes the user would not have a way to write wildcards when using this mode and would have to write +_ and -_ with backticks – both would hinder cross-compilation with Scala 3)

The tests pass on all scalac versions (I've quoted +_, -_ for 2.10/2.11) compat. I've found the built-in test suite to be comprehensive, but small, so I've made sure that this change works by porting 7mind/izumi#1479 to the new syntax, with unquoted +_/-_ and, well, it works on my machine.

Fixes #120

== Description

The syntax roughly follows the proposed new syntax for wildcards and placeholders for Scala 3.2+ and is designed to allow cross-compilation of libraries between Scala 2 and Scala 3 while using the new Scala 3 syntax for both versions.

To enable this mode, add -P:kind-projector:underscore-placeholders to your scalac command-line. In sbt you may do this as follows:

ThisBuild / scalacOptions += "-P:kind-projector:underscore-placeholders"

This mode is designed to be used with scalac versions 2.12.14+ and 2.13.6+, these versions add an the ability to use ? as the existential type wildcard (scala/scala#9560), allowing to repurpose the underscore without losing the ability to write existential types. It is not advised that you use this mode with older versions of scalac or without -Xsource:3 flag, since you will lose the underscore syntax entirely.

Here are a few examples:

Tuple2[_, Double]        // equivalent to: type R[A] = Tuple2[A, Double]
Either[Int, +_]          // equivalent to: type R[+A] = Either[Int, A]
Function2[-_, Long, +_]  // equivalent to: type R[-A, +B] = Function2[A, Long, B]
EitherT[_[_], Int, _]    // equivalent to: type R[F[_], B] = EitherT[F, Int, B]

Examples with -Xsource:3's ?-wildcard:

Tuple2[_, ?]        // equivalent to: type R[A] = Tuple2[A, x] forSome { type x }
Either[?, +_]          // equivalent to: type R[+A] = Either[x, A] forSome { type x }
Function2[-_, ?, +_]  // equivalent to: type R[-A, +B] = Function2[A, x, B] forSome { type x }
EitherT[_[_], ?, _]    // equivalent to: type R[F[_], B] = EitherT[F, x, B] forSome { type x }

…ymous type lambdas

The syntax roughly follows the [proposed new syntax for wildcards and placeholders](https://dotty.epfl.ch/docs/reference/changed-features/wildcards.html#migration-strategy) for Scala 3.2+ and is designed to allow cross-compilation of libraries between Scala 2 and Scala 3 while using the new Scala 3 syntax for both versions.

To enable this mode, add `-P:kind-projector:underscore-placeholders` to your scalac command-line. In sbt you may do this as follows:

```scala
ThisBuild / scalacOptions += "-P:kind-projector:underscore-placeholders"
```

This mode is designed to be used with scalac versions `2.12.14`+ and `2.13.6`+, these versions add an the ability to use `?` as the existential type wildcard ([scala/scala#9560](scala/scala#9560)), allowing to repurpose the underscore without losing the ability to write existential types. It is not advised that you use this mode with older versions of scalac or without `-Xsource:3` flag, since you will lose the underscore syntax entirely.

Here are a few examples:

```scala
Tuple2[_, Double]        // equivalent to: type R[A] = Tuple2[A, Double]
Either[Int, +_]          // equivalent to: type R[+A] = Either[Int, A]
Function2[-_, Long, +_]  // equivalent to: type R[-A, +B] = Function2[A, Long, B]
EitherT[_[_], Int, _]    // equivalent to: type R[F[_], B] = EitherT[F, Int, B]
```

Examples with `-Xsource:3`'s `?`-wildcard:

```scala
Tuple2[_, ?]        // equivalent to: type R[A] = Tuple2[A, x] forSome { type x }
Either[?, +_]          // equivalent to: type R[+A] = Either[x, A] forSome { type x }
Function2[-_, ?, +_]  // equivalent to: type R[-A, +B] = Function2[A, x, B] forSome { type x }
EitherT[_[_], ?, _]    // equivalent to: type R[F[_], B] = EitherT[F, x, B] forSome { type x }
```
@neko-kai
Copy link
Contributor Author

@larsrh @SethTisue The Scalac / Dotty PRs supporting this have been merged, so I think this could be merged, unless there are issues?

build.sbt Outdated
@@ -84,6 +84,11 @@ def hasNewParser(versionString: String) = versionString match {
case _ => false
}

def hasNewPlugin(versionString: String) = versionString match {
case HasScalaVersion(2, 10, _) => false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need the Scala 2.10 support still? Otherwise I'm inclined to drop this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larsrh Do you want me to drop 2.10 build as part of this PR? The case is required to compile on 2.10 but is not required otherwise.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would be great!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@larsrh Done in last 2 commits

@larsrh
Copy link
Contributor

larsrh commented May 15, 2021

I can't push to your branch, but you'd have to run sbt githubWorkflowGenerate for CI to pass.

Copy link
Contributor

@larsrh larsrh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, pending green build

@larsrh larsrh merged commit 2b84018 into typelevel:main May 15, 2021
@neko-kai
Copy link
Contributor Author

@larsrh Build's green now 👍

I can't push to your branch

Odd, I don't think I changed anything to prohibit this, though I do not see an 'allow edits from maintainers' checkbox on this page either.

@larsrh
Copy link
Contributor

larsrh commented May 15, 2021

Thanks!

@larsrh
Copy link
Contributor

larsrh commented May 15, 2021

Since this is a new feature, not a breaking change, I think we can roll this as 0.12.1. I will update the README accordingly.

@neko-kai
Copy link
Contributor Author

@larsrh Thanks! 🙏 For the release number, everywhere in the docs for the new feature I wrote version 0.13.0 and up (migration guide, dotty wildcards page, readme). It could be easier to release as 0.13 just to not update all of these...

@larsrh
Copy link
Contributor

larsrh commented May 15, 2021

Fair enough, running that now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Scala 3 mode with _ as a placeholder and ? as wildcard?
2 participants