scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.85k stars 1.06k forks source link

Spec: Are blocks allowed in patterns? #1774

Closed liufengyun closed 6 years ago

liufengyun commented 7 years ago

Scalac doesn't parse following programs syntactically, but support it if it's synthesized.

Dotty accepts the code syntactically, but the typer generates a typing error.

object Test {
  val a = (3, 4) match {
    case ({name: Int}, {parent: Int}) => (name, parent)
  }

  val name = a._1
  val parent = a._2
}

Error message:

-- Error: examples/block.scala -------------------------------------------------
6 |  val name = a._1
  |             ^
  |             cyclic reference involving value a
-- Error: examples/block.scala -------------------------------------------------
7 |  val parent = a._2
  |               ^
  |               cyclic reference involving value a
-- Error: examples/block.scala -------------------------------------------------
3 |    case ({name: Int}, {parent: Int}) => (name, parent)
  |                                          ^^^^
  |                                        cyclic reference involving value a

three errors found
julienrf commented 7 years ago

Support could be useful for this kind of stuff:

(3, 4) match {
  case { val single = MyTupleExtractor(Snd); single(4) } => …
}

(It makes it possible to manipulate extractors in rhs position, for instance to configure them)

julienrf commented 7 years ago

But I’m not sure it is worth it… :)

liufengyun commented 7 years ago

The implementation of Quasiquote in scala.meta (link) relies on anonymous extractors like follows:

          new {
            def unapply(input: Joy) = {
              ..$preamble
              input match {
                case $lifted => $thenp
                case _       => $elsep
              }
            }
          }.unapply(..$args)

which gets expanded to a block:

      {
          class $anon {
            def unapply(input: Joy) = {
              ..$preamble
              input match {
                case $lifted => $thenp
                case _       => $elsep
              }
            }
          }

         new $anon
      }.unapply(..$args)
odersky commented 7 years ago

I think it would be good to allow this! Needs a spec change, though.

liufengyun commented 7 years ago

As a side note, we don't need this feature in order to implement Quasiquote in dotty. The quasi quote in Dotty now pass all regression set in scalameta.

liufengyun commented 6 years ago

Close this for now, I don't think it's a good idea to have blocks in patterns, the code is not readable.

propensive commented 6 years ago

It seems like it would open up a lot of new and interesting possibilities, though I'm a little scared about what should and shouldn't be allowed...