This page is no longer maintained — Please continue to the home page at www.scala-lang.org

List pattern matching

8 replies
ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.

Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I
couldn't find an unapply method in List - although I did find unapplySeq
method, where is that used?), so what is it? (The question would be
answered if someone explained how it's implemented - hopefully this is
not something magic just for lists)

Thanks,
Dimitris

David Pollak
Joined: 2008-12-16,
User offline. Last seen 42 years 45 weeks ago.
Re: List pattern matching
extends List[B]

See http://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_7_3_final/src/library/scala/List.scala?view=markup
No magic involved.
If you need a deeper explanation, feel free to ask.
Thanks,
David

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris



--
Lift, the simply functional web framework http://liftweb.net
Beginning Scala http://www.apress.com/book/view/1430219890
Follow me: http://twitter.com/dpp
Git some: http://github.com/dpp
Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: List pattern matching
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris

ounos
Joined: 2008-12-29,
User offline. Last seen 3 years 44 weeks ago.
Re: List pattern matching

O/H Jorge Ortiz έγραψε:
>
> Case classes of two arguments can be used with infix notation when
> pattern matching.
Thanks! This explains it all. Nice.

Szymon Jachim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: List pattern matching
There's no magic in Scalas compiler or lanugage constructs, but some rules of scala let it type system do magic things...
BTW, I was just explaining to one of my collegues the difference between scala for comprehension and for loop from "ordinary" PLs. 
    for (j <- 1 until 20) {      list.add(() => println(j))    }

When you run all those actions they print 1..19 but when you do somehting similar in other PLs (and use Clike loop) it's printing 19, 19, ... :-)
I then told him a lot of conceptual unification and how scala let's you extend itself through libs... I don't he cares. Will masses of Java developers care about such things? :-)

Szymon
On Wed, Feb 18, 2009 at 10:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris


Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: List pattern matching
Well, you can certainly get the "ordinary" behavior in Scala:

  var j = 0
  while(j < 20) {
    list.add(() => println(j))
    j += 1
  }

But for-comprehensions (thankfully) don't work that way.

--j

On Wed, Feb 18, 2009 at 3:43 PM, Szymon Jachim <sjachim@gmail.com> wrote:
There's no magic in Scalas compiler or lanugage constructs, but some rules of scala let it type system do magic things...
BTW, I was just explaining to one of my collegues the difference between scala for comprehension and for loop from "ordinary" PLs. 
    for (j <- 1 until 20) {      list.add(() => println(j))    }

When you run all those actions they print 1..19 but when you do somehting similar in other PLs (and use Clike loop) it's printing 19, 19, ... :-)
I then told him a lot of conceptual unification and how scala let's you extend itself through libs... I don't he cares. Will masses of Java developers care about such things? :-)

Szymon
On Wed, Feb 18, 2009 at 10:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris



Szymon Jachim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: List pattern matching
Yes - thankfully. 
This is how i emulated Clike loop in Scala:
var i = 0;for (j <- 0 until 10) {
  i = j;
  list.add((() => println(i))) 
}
He introduced variable to do exactly opposite in Groovy:
for (int i = 0; i < 10; i++) {
int j = i;
funcs.add({ println "$j" });
}

I was adding silly code to get surprising 19, 19, 19... and he was adding code to get what a programmer would naturally want. 1, 2, 3... 

On Thu, Feb 19, 2009 at 1:03 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
Well, you can certainly get the "ordinary" behavior in Scala:

  var j = 0
  while(j < 20) {
    list.add(() => println(j))
    j += 1
  }

But for-comprehensions (thankfully) don't work that way.

--j

On Wed, Feb 18, 2009 at 3:43 PM, Szymon Jachim <sjachim@gmail.com> wrote:
There's no magic in Scalas compiler or lanugage constructs, but some rules of scala let it type system do magic things...
BTW, I was just explaining to one of my collegues the difference between scala for comprehension and for loop from "ordinary" PLs. 
    for (j <- 1 until 20) {      list.add(() => println(j))    }

When you run all those actions they print 1..19 but when you do somehting similar in other PLs (and use Clike loop) it's printing 19, 19, ... :-)
I then told him a lot of conceptual unification and how scala let's you extend itself through libs... I don't he cares. Will masses of Java developers care about such things? :-)

Szymon
On Wed, Feb 18, 2009 at 10:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris




Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: List pattern matching
All you have to do is take out the mutation for lambdas to give fewer surprises.

2009/2/19 Szymon Jachim <sjachim@gmail.com>
Yes - thankfully. 
This is how i emulated Clike loop in Scala:
var i = 0;for (j <- 0 until 10) {
  i = j;
  list.add((() => println(i))) 
}
He introduced variable to do exactly opposite in Groovy:
for (int i = 0; i < 10; i++) {
int j = i;
funcs.add({ println "$j" });
}

I was adding silly code to get surprising 19, 19, 19... and he was adding code to get what a programmer would naturally want. 1, 2, 3... 

On Thu, Feb 19, 2009 at 1:03 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
Well, you can certainly get the "ordinary" behavior in Scala:

  var j = 0
  while(j < 20) {
    list.add(() => println(j))
    j += 1
  }

But for-comprehensions (thankfully) don't work that way.

--j

On Wed, Feb 18, 2009 at 3:43 PM, Szymon Jachim <sjachim@gmail.com> wrote:
There's no magic in Scalas compiler or lanugage constructs, but some rules of scala let it type system do magic things...
BTW, I was just explaining to one of my collegues the difference between scala for comprehension and for loop from "ordinary" PLs. 
    for (j <- 1 until 20) {      list.add(() => println(j))    }

When you run all those actions they print 1..19 but when you do somehting similar in other PLs (and use Clike loop) it's printing 19, 19, ... :-)
I then told him a lot of conceptual unification and how scala let's you extend itself through libs... I don't he cares. Will masses of Java developers care about such things? :-)

Szymon
On Wed, Feb 18, 2009 at 10:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris





Szymon Jachim
Joined: 2008-12-17,
User offline. Last seen 42 years 45 weeks ago.
Re: List pattern matching
Right. Once we do fully side effect free code, that outer variable (but shuld we still call it "variable") cannot change. So the closure does the same thing every time it's called.

Isn't it a bit like the opposite to side effecting code?
Some closures are fragile to side effects happening in the system (through the bound variables), while other - never. Hmmm.... :-)

Szymon

On Thu, Feb 19, 2009 at 3:07 PM, Ricky Clarkson <ricky.clarkson@gmail.com> wrote:
All you have to do is take out the mutation for lambdas to give fewer surprises.

2009/2/19 Szymon Jachim <sjachim@gmail.com>
Yes - thankfully. 
This is how i emulated Clike loop in Scala:
var i = 0;for (j <- 0 until 10) {
  i = j;
  list.add((() => println(i))) 
}
He introduced variable to do exactly opposite in Groovy:
for (int i = 0; i < 10; i++) {
int j = i;
funcs.add({ println "$j" });
}

I was adding silly code to get surprising 19, 19, 19... and he was adding code to get what a programmer would naturally want. 1, 2, 3... 

On Thu, Feb 19, 2009 at 1:03 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
Well, you can certainly get the "ordinary" behavior in Scala:

  var j = 0
  while(j < 20) {
    list.add(() => println(j))
    j += 1
  }

But for-comprehensions (thankfully) don't work that way.

--j

On Wed, Feb 18, 2009 at 3:43 PM, Szymon Jachim <sjachim@gmail.com> wrote:
There's no magic in Scalas compiler or lanugage constructs, but some rules of scala let it type system do magic things...
BTW, I was just explaining to one of my collegues the difference between scala for comprehension and for loop from "ordinary" PLs. 
    for (j <- 1 until 20) {      list.add(() => println(j))    }

When you run all those actions they print 1..19 but when you do somehting similar in other PLs (and use Clike loop) it's printing 19, 19, ... :-)
I then told him a lot of conceptual unification and how scala let's you extend itself through libs... I don't he cares. Will masses of Java developers care about such things? :-)

Szymon
On Wed, Feb 18, 2009 at 10:20 PM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
In Scala, nothing is magic, except for the magic bits :)

In this case, :: is the name of a case class, defined like so in List.scala:

  final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B] { ...

Case classes of two arguments can be used with infix notation when pattern matching.

  scala> case class Foo(x: Int, y: Int)
  defined class Foo

  scala> val f = Foo(1, 10)
  f: Foo = Foo(1,10)

  scala> f match {
       |   case x Foo y => println(x + y)
       | }
  11

--j

On Wed, Feb 18, 2009 at 1:02 PM, Andreou Dimitris <jim.andreou@gmail.com> wrote:
Hi,

Can someone explain in detail how the following works?

val list = List(1, 2)
list match {
 case x :: xs => ...
}

In particular, x :: xs can't be calling an extractor (or is it? I couldn't find an unapply method in List - although I did find unapplySeq method, where is that used?), so what is it? (The question would be answered if someone explained how it's implemented - hopefully this is not something magic just for lists)

Thanks,
Dimitris






Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland