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

breaking open tuples in an anonymous function

13 replies
robey
Joined: 2008-12-24,
User offline. Last seen 1 year 21 weeks ago.

I often want to do this and I haven't figured out how to make it work:

scala> val x = Map("Robey" -> 500, "Santa" -> 505)
x: scala.collection.immutable.Map[java.lang.String,Int] = Map(Robey ->
500, Santa -> 505)

scala> x map { (k, v) => v / 5 }
:6: error: wrong number of parameters; expected = 1
x map { (k, v) => v / 5 }

scala> x map { ((k, v)) => v / 5 }
:1: error: not a legal formal parameter
x map { ((k, v)) => v / 5 }

scala> x map { ((k, v),) => v / 5 }
:1: error: not a legal formal parameter
x map { ((k, v),) => v / 5 }

Anyone got advice? :)

robey

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: breaking open tuples in an anonymous function
x map { case (k, v) => v / 5 }

--j

On Thu, Mar 19, 2009 at 2:16 PM, Robey Pointer <robeypointer [at] gmail [dot] com> wrote:
I often want to do this and I haven't figured out how to make it work:

scala> val x = Map("Robey" -> 500, "Santa" -> 505)
x: scala.collection.immutable.Map[java.lang.String,Int] = Map(Robey -> 500, Santa -> 505)

scala> x map { (k, v) => v / 5 }
<console>:6: error: wrong number of parameters; expected = 1
      x map { (k, v) => v / 5 }

scala> x map { ((k, v)) => v / 5 }
<console>:1: error: not a legal formal parameter
      x map { ((k, v)) => v / 5 }

scala> x map { ((k, v),) => v / 5 }
<console>:1: error: not a legal formal parameter
      x map { ((k, v),) => v / 5 }

Anyone got advice? :)

robey


Steven Shaw
Joined: 2009-02-01,
User offline. Last seen 2 years 39 weeks ago.
Re: breaking open tuples in an anonymous function

2009/3/20 Jorge Ortiz :
> x map { case (k, v) => v / 5 }

I like this. An alternative is

x map (_._2 / 5)

robey
Joined: 2008-12-24,
User offline. Last seen 1 year 21 weeks ago.
Re: breaking open tuples in an anonymous function

On 19 Mar 2009, at 21:13, Steven Shaw wrote:

> 2009/3/20 Jorge Ortiz :
>> x map { case (k, v) => v / 5 }
>
> I like this. An alternative is
>
> x map (_._2 / 5)

The _1, _2 things look like an ugly hack to me so I avoid them.

I like the case trick, and I'll use that, but is there any reason ((k,
v)) doesn't work? Should I file a bug?

robey

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: breaking open tuples in an anonymous function
It's not a bug, but could be an enhancement request. Function literals don't support pattern matching.

There was at some point talk about unifying tuples and function arguments, but I don't know serious that talk was.

--j

On Thu, Mar 19, 2009 at 10:55 PM, Robey Pointer <robeypointer [at] gmail [dot] com> wrote:
On 19 Mar 2009, at 21:13, Steven Shaw wrote:

2009/3/20 Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com>:
x map { case (k, v) => v / 5 }

I like this. An alternative is

 x map (_._2 / 5)

The _1, _2 things look like an ugly hack to me so I avoid them.

I like the case trick, and I'll use that, but is there any reason ((k, v)) doesn't work? Should I file a bug?

robey


Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 3 days ago.
Re: breaking open tuples in an anonymous function
Oh, there's one more trick I learned recently:

scala> import Function.tupled
import Function.tupled

scala> val x = Map("Robey" -> 500, "Santa" -> 505)
x: scala.collection.immutable.Map[java.lang.String,Int] = Map(Robey -> 500, Santa -> 505)

scala> x map tupled { (k, v) => v / 5 }
res0: Iterable[Int] = ArrayBuffer(100, 101)

--j

On Thu, Mar 19, 2009 at 11:57 PM, Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com> wrote:
It's not a bug, but could be an enhancement request. Function literals don't support pattern matching.

There was at some point talk about unifying tuples and function arguments, but I don't know serious that talk was.

--j

On Thu, Mar 19, 2009 at 10:55 PM, Robey Pointer <robeypointer [at] gmail [dot] com> wrote:
On 19 Mar 2009, at 21:13, Steven Shaw wrote:

2009/3/20 Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com>:
x map { case (k, v) => v / 5 }

I like this. An alternative is

 x map (_._2 / 5)

The _1, _2 things look like an ugly hack to me so I avoid them.

I like the case trick, and I'll use that, but is there any reason ((k, v)) doesn't work? Should I file a bug?

robey



Andreas W
Joined: 2009-01-10,
User offline. Last seen 1 year 14 weeks ago.
Re: breaking open tuples in an anonymous function

I have thought for a while now that it would be nice to have named tuples, like this:

(number=42, spelling="forty two")

Then instead of "x._1" one could write "x.number", without any need for pattern matching. Maps could return tuples with default names such as (key=, value=). These look a lot like named argument lists, and also like case classes. Maybe there is a grand unification of sorts begging to be done to simplify everything and turn the three into one?  Tuples == case classes == argument lists ?

Andreas


From: Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com>
To: Robey Pointer <robeypointer [at] gmail [dot] com>
Cc: Steven Shaw <steshaw [at] gmail [dot] com>; Scala list <scala [at] listes [dot] epfl [dot] ch>
Sent: Friday, March 20, 2009 2:57:19 AM
Subject: Re: [scala] breaking open tuples in an anonymous function

It's not a bug, but could be an enhancement request. Function literals don't support pattern matching.

There was at some point talk about unifying tuples and function arguments, but I don't know serious that talk was.

--j

On Thu, Mar 19, 2009 at 10:55 PM, Robey Pointer <robeypointer [at] gmail [dot] com" target="_blank" href="mailto:robeypointer [at] gmail [dot] com" rel="nofollow">robeypointer [at] gmail [dot] com> wrote:
On 19 Mar 2009, at 21:13, Steven Shaw wrote:

2009/3/20 Jorge Ortiz <jorge [dot] ortiz [at] gmail [dot] com" target="_blank" href="mailto:jorge [dot] ortiz [at] gmail [dot] com" rel="nofollow">jorge [dot] ortiz [at] gmail [dot] com>:
x map { case (k, v) => v / 5 }

I like this. An alternative is

 x map (_._2 / 5)

The _1, _2 things look like an ugly hack to me so I avoid them.

I like the case trick, and I'll use that, but is there any reason ((k, v)) doesn't work? Should I file a bug?

robey



Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: breaking open tuples in an anonymous function

scala> val o = new { val number = 42; val spelling = "forty two" }
o: java.lang.Object{def number: Int; def spelling: java.lang.String} =
$anon$1@39859

scala> def gimme(n: { val number: Int; val spelling: String }) = "The
answer is "+n.number+" ("+n.spelling+")"
gimme: (AnyRef{def number: Int; def spelling: String})java.lang.String

scala> gimme(o)
res0: java.lang.String = The answer is 42 (forty two)

2009/3/20 Windemuth Andreas :
>
> I have thought for a while now that it would be nice to have named tuples,
> like this:
>
> (number=42, spelling="forty two")
>
> Then instead of "x._1" one could write "x.number", without any need for
> pattern matching. Maps could return tuples with default names such as (key=,
> value=). These look a lot like named argument lists, and also like case
> classes. Maybe there is a grand unification of sorts begging to be done to
> simplify everything and turn the three into one?  Tuples == case classes ==
> argument lists ?
>
> Andreas
>
>
> ________________________________
> From: Jorge Ortiz
> To: Robey Pointer
> Cc: Steven Shaw ; Scala list
> Sent: Friday, March 20, 2009 2:57:19 AM
> Subject: Re: [scala] breaking open tuples in an anonymous function
>
> It's not a bug, but could be an enhancement request. Function literals don't
> support pattern matching.
>
> There was at some point talk about unifying tuples and function arguments,
> but I don't know serious that talk was.
>
> --j
>
> On Thu, Mar 19, 2009 at 10:55 PM, Robey Pointer
> wrote:
>>
>> On 19 Mar 2009, at 21:13, Steven Shaw wrote:
>>
>>> 2009/3/20 Jorge Ortiz :
>>>>
>>>> x map { case (k, v) => v / 5 }
>>>
>>> I like this. An alternative is
>>>
>>>  x map (_._2 / 5)
>>
>> The _1, _2 things look like an ugly hack to me so I avoid them.
>>
>> I like the case trick, and I'll use that, but is there any reason ((k, v))
>> doesn't work? Should I file a bug?
>>
>> robey
>>
>
>
>

Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: breaking open tuples in an anonymous function

Ricky Clarkson wrote:
> scala> val o = new { val number = 42; val spelling = "forty two" }
> o: java.lang.Object{def number: Int; def spelling: java.lang.String} =
> $anon$1@39859
>
> scala> def gimme(n: { val number: Int; val spelling: String }) = "The
> answer is "+n.number+" ("+n.spelling+")"
> gimme: (AnyRef{def number: Int; def spelling: String})java.lang.String
>
> scala> gimme(o)
> res0: java.lang.String = The answer is 42 (forty two)

The problem here is that neither "o" or "gimme"'s parameter list is a tuple.

/Jesper Nordenberg

Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: breaking open tuples in an anonymous function

Windemuth Andreas wrote:
>
> I have thought for a while now that it would be nice to have named
> tuples, like this:
>
> (number=42, spelling="forty two")
>
> Then instead of "x._1" one could write "x.number", without any need for
> pattern matching. Maps could return tuples with default names such as
> (key=, value=). These look a lot like named argument lists, and also
> like case classes. Maybe there is a grand unification of sorts begging
> to be done to simplify everything and turn the three into one? Tuples
> == case classes == argument lists ?

I've thought in the same general direction. Tuples with named elements
which are structurally typed would definitely be very nice thing to have
and it would integrate nicely with the concept of named/optional
parameters. Though, it would not replace case classes as the nominal
typing is important here.

However, I think it's too late to add this to Scala now. The unification
of tuples and parameter lists is such a fundamental part of the language
that it really can't be bolted on at this stage. And another
complication is that "(x=10, y=20)" is already valid Scala syntax if x
and y are vars.

/Jesper Nordenberg

Ricky Clarkson
Joined: 2008-12-19,
User offline. Last seen 3 years 2 weeks ago.
Re: Re: breaking open tuples in an anonymous function

Could you explain how that is a problem?

2009/3/20 Jesper Nordenberg :
> Ricky Clarkson wrote:
>>
>> scala> val o = new { val number = 42; val spelling = "forty two" }
>> o: java.lang.Object{def number: Int; def spelling: java.lang.String} =
>> $anon$1@39859
>>
>> scala> def gimme(n: { val number: Int; val spelling: String }) = "The
>> answer is "+n.number+" ("+n.spelling+")"
>> gimme: (AnyRef{def number: Int; def spelling: String})java.lang.String
>>
>> scala> gimme(o)
>> res0: java.lang.String = The answer is 42 (forty two)
>
> The problem here is that neither "o" or "gimme"'s parameter list is a tuple.
>
> /Jesper Nordenberg
>
>

Jesper Nordenberg
Joined: 2008-12-27,
User offline. Last seen 42 years 45 weeks ago.
Re: breaking open tuples in an anonymous function

Ricky Clarkson wrote:
> Could you explain how that is a problem?

The nice thing about tuples is that the elements are ordered, as opposed
to the members of an object/record which are unordered. Tuples with
named elements would give you "the best of both worlds", for example
(note: this is not Scala code):

def fun(x : Int, y : Int, z = 0) : (x : Int, y : Int, z : Int) => Int =
x + y + z

// Elements x and y gets assigned by order, z gets default value
fun (1, 2)

// Structural typing maps elements with same name
fun (z = 3, y = 2, x = 1)

// Define a tuple with named elements
val t : (x : Int, y : Int) = (x = 1, y = 2)

// Structural typing again
fun t

// Tuple composition
val t2 : (x : Int, y : Int, z : Int) = t :: (z = 3)

fun t2

/Jesper Nordenberg

Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: Re: breaking open tuples in an anonymous function
Interesting discussion.


I 'transformed' a program to use named tuples
of the form:

type NamedTuple[X] = Object { def px: Pred[X]; def sx: Sync[X] }

-- Pred[X] are predicates;
-- Sync[X] are kind of synchronized variables

but when creating instances using val's I had other
behavior than the original behavior when using tuples,
while, when using lazy val's I got the same behavior.

So, generally, am I right that, semantically, values
{ lazy val number: Int; lazy val spelling: String }
are similar to tuples rather than values
{ val number: Int; val spelling: String } ?


Luc


--
  __~O
 -\ <,
(*)/ (*)

reality goes far beyond imagination

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: Re: breaking open tuples in an anonymous function

On Friday March 20 2009, Jesper Nordenberg wrote:
> Ricky Clarkson wrote:
> > Could you explain how that is a problem?
>
> The nice thing about tuples is that the elements are ordered, as
> opposed to the members of an object/record which are unordered.
> Tuples with named elements would give you "the best of both worlds",
> for example (note: this is not Scala code):

In a previous Java project, I wrote a "structured value" library that
was akin to JavaScript objects (and it had JSON serialization and
deserialization). The dictionary elements had two variants, sequenced
and non-sequenced. Both allowed by-name lookup of a slot value (another
structured value, of course) but only the sequenced variant allowed
retrieval by integer index.

> ...
>
> /Jesper Nordenberg

Randall Schulz

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