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

Adding Clause Interleaving to method definitions #14019

Merged
merged 19 commits into from
Feb 3, 2023

Conversation

Sporarum
Copy link
Contributor

@Sporarum Sporarum commented Dec 1, 2021

This aims to add the ability to declare functions with many clauses of type parameters, instead of at most one, and to allow those clauses to be interleaved with term clauses:

def foo[A](x: A)[B](y: B) = (x, y)

All user-facing details can be found in the Scala 3 new features doc, and in the SIP proposal

The implementation details are described below in the commit messages

The community's opinion of the feature can be found on the scala contributors forum
(note however that the description there is somewhat outdated)

Dependencies

This feature has been accepted by the SIP committee for implementation, it can therefore become part of the language as an experimental feature at any time.

The feature will be available with import scala.language.experimental.clauseInterleaving

How to make non-experimental

git revert the commits named "Make clause interleaving experimental" and "Add import to tests":

git revert 6ace5b816a1845993b0f002067e65d98882667ee
git revert 1e402f3e44310dab4699fcbacbf6afc1eefb261c

Future Work

  1. Implement given aliases with clause interweaving: (to have types depends on terms)
given myGiven[T](using x: T)[U](using y: U) = (x, y)
  1. Add interleaved clauses to the left-hand side of extension methods:
extension (using Int)[A](using A)(a: A)[B](using B)
  def foo: (A, B) = ???
  1. Investigate usefulness/details of clause interweaving for classes and type currying for types:
class Foo[A](a: A)[B](b: B)
new Foo(0)("Hello!") // type: Foo[Int][String] ?

type Bar[A][B] = Map[A, B]
Bar[Char] // should this mean [B] =>> Bar[Char][B] ?

(Started as a semester project with supervision from @smarter, now part of my missions as an intern at the scala center)

@Sporarum Sporarum changed the title Adding Interweaved Type and Term Clauses to function definitions [WIP] Adding Interweaved Type and Term Clauses to function definitions Dec 8, 2021
@Sporarum Sporarum force-pushed the typeInterweaving branch 4 times, most recently from f0926c1 to 1a85e94 Compare January 22, 2022 11:36
@Sporarum Sporarum force-pushed the typeInterweaving branch 2 times, most recently from 3a5026c to 93ff8f1 Compare January 26, 2022 14:55
@Sporarum Sporarum changed the title [WIP] Adding Interweaved Type and Term Clauses to function definitions [WIP] Adding Interweaved Clauses to function definitions Feb 17, 2022
@Sporarum Sporarum marked this pull request as ready for review February 17, 2022 17:40
@Sporarum Sporarum closed this Feb 17, 2022
@Sporarum Sporarum deleted the typeInterweaving branch February 17, 2022 18:31
@Sporarum Sporarum restored the typeInterweaving branch February 17, 2022 18:33
@Sporarum Sporarum reopened this Feb 17, 2022
@Sporarum Sporarum changed the title [WIP] Adding Interweaved Clauses to function definitions Adding Interweaved Clauses to function definitions Feb 23, 2022
@Sporarum Sporarum changed the title Adding Interweaved Clauses to function definitions Adding Clause Interleaving to method definitions Aug 23, 2022
@Sporarum Sporarum force-pushed the typeInterweaving branch 2 times, most recently from ccc7657 to a2f2b9a Compare August 24, 2022 10:23
@soronpo
Copy link
Contributor

soronpo commented Aug 24, 2022

I'm not sure if you thought about the type system when a method application is split to blocks.
Before this SIP type arguments are inferred as Nothing because they all "belong" to the first block.
If this SIP is added, I expect the following to compile:

  class Box[T](x: T)
  def huge[T1, T2](
    t1: T1, t2 : T2, r : Int
  )[T3, T4](t3: T3, r2: Int, t4: T4)[T5](t5 : T5*): Box[(T1, T2, T3, T4, T5)] = ???

  val h1p1 = huge((1, 2), (3, 4), 5)
  val h1p2 = h1p1((6, 7), 8, (9, 10))
  val h1p3 = h1p2(11, 12)
  val h1pTest: Box[((Int, Int), (Int, Int), (Int, Int), (Int, Int), Int)] = h1p3

@Sporarum Sporarum force-pushed the typeInterweaving branch 2 times, most recently from a31a6c7 to 0742ffb Compare February 2, 2023 17:47
Sporarum and others added 13 commits February 2, 2023 18:50
The new syntax allows arbitrary interleaving of type and term
clauses for methods
TypelessClause{|s} is added for class constructors since they still don't
allow interleaving of type parameters

Also unifies the affected grammar variable names so that <x>s means
"one or more <x>"

Implicit clauses are moved apart from term clause to make it more
obvious they can only be the last clause
Interweaved methods still fail at use-cite, see next commit
A check is removed that forbids interleaved methods at use-site
This however breaks named type parameters, some tests are thus removed

methType implicitly assumed there could only be one leading term
parameter clause, this has been changed
This commit is only here for the sake of legibility, it breaks tests
If you want to come back in the history,
go to either the previous commit or the next
This adds back the TypeApply case that was present in Applications.scala.
With it is an improved error message that shows a potential fix.
@Sporarum Sporarum merged commit ef815fd into scala:main Feb 3, 2023
julienrf added a commit to scala/improvement-proposals that referenced this pull request Feb 3, 2023
@Kordyjan Kordyjan added this to the 3.3.1 milestone Aug 1, 2023
@hamzaremmal hamzaremmal mentioned this pull request Jun 28, 2024
hamzaremmal added a commit that referenced this pull request Jul 4, 2024
Closes #20769 

Initial implementation in #14019
odersky pushed a commit to odersky/improvement-proposals that referenced this pull request Jul 18, 2024
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.

None yet

7 participants