-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Add spec section for given
patterns reflecting existing semantics
#19723
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
base: main
Are you sure you want to change the base?
Conversation
docs/_spec/08-pattern-matching.md
Outdated
|
||
A _given pattern_ introduces an _anonymous given instance_ of the _type_ matched by `TypePat` to the scope of the clause that a given pattern occurs _within_. | ||
|
||
The rules for the _name_ synthesized for each anonymous instance is defined in the reference. If multiple names synthesized by the compiler are _not_ unique, this will result in an error. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have not put a link here, because the implicit section has not been updated to reflect given
/using
yet and I do not know whether I should link to https://docs.scala-lang.org/scala3/reference/contextual/relationship-implicits.html.
@@ -17,6 +17,8 @@ chapter: 8 | |||
| Pattern3 | |||
Pattern3 ::= SimplePattern | |||
| SimplePattern {id [nl] SimplePattern} | |||
| GivenPattern | |||
GivenPattern ::= ‘given’ TypePat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The parser considers that this a case of SimplePattern
:
https://github.com/lampepfl/dotty/blob/7f410aa1b5cbb38dc4c51da0b5772c7babfaabf0/compiler/src/dotty/tools/dotc/parsing/Parsers.scala#L3026
Also, we should update docs/_docs/internals/syntax.md
at the same time, to keep them in sync.
GivenPattern ::= TypePat | ||
``` | ||
|
||
A _given pattern_ introduces an _anonymous given instance_ of the _type_ matched by `TypePat` to the scope of the clause that a given pattern occurs _within_. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand what the last part of the sentence means, starting from "to the scope". It does not appear to be grammatically correct, or it's grammatically ambiguous at best. Rephrase?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What if the corresponding scrutinee is not statically known to have the type TypePat
? Is that a compile error or a no-match at run-time?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sjrd I was trying to refer to the scope of the case clause - is the term local scope fine?
I think that in the case that the scrutinee is known statically or not statically should be the same as for a TypePat
without a given
modifier.
Currently,
val x = 1
val y = x match {
case y: String => ???
}
gives a compile error and
val x = "asd"
def foo[A](a: A): Unit = {
a match {
case s: Int=> 1
}
}
foo(x)
Is a runtime error.
|
||
A _given pattern_ introduces an _anonymous given instance_ of the _type_ matched by `TypePat` to the scope of the clause that a given pattern occurs _within_. | ||
|
||
The rules for the _name_ synthesized for each anonymous instance is defined in the reference. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Link?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently, it does not exist in the spec; can I link to the reference in the spec or not?
```scala | ||
def foo: Int = | ||
List(1) match | ||
case given List[_] => summon[List[?]].head // returns `1` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This example does not illustrate that we statically receive an Int
. Include a val x: Int = summon[List[Int]].head
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, the return type is Int
of the function, but I can introduce a val
if it would make it clearer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scala 2
scala> List(42) match { case xs @ (_: List[_]) => xs }
val res1: List[Any] = List(42)
scala 3
scala> List(42) match { case xs @ (_: List[_]) => xs }
val res0: List[Int] = List(42)
I'm not sure if scala 2 is plain wrong here. So any clarification would be helpful.
Oh nm it's REPL output bc:
scala> val ys: List[Int] = List(42) match { case xs @ (_: List[_]) => xs }
val ys: List[Int] = List(42)
but that goes to my point that a) a semi-casual reader might not have a preconceived notion and b) if I try it in the REPL, REPL may let me down, so I rely on your examples before giving up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, the return type is
Int
of the function, but I can introduce aval
if it would make it clearer.
The reader of the spec does know that, and does not have an IDE or REPL to prove it. So yes, a val
with an expected type would make it a lot clearer.
This needs #19718 to test locally from a fresh docker build.