Idea for easier mapping on method calls

73 views
Skip to first unread message

Sebastian Meßmer

unread,
Nov 8, 2012, 5:05:59 PM11/8/12
to scala-l...@googlegroups.com
Hello,

when working with futures, options or list, one often has long map chains that
just call member methods like

val optString = Some("String1")
val characterCounts = optString.map(_.groupBy(id=>id).map(_._2.size))

Therefore I'm in favor of a way to simplify calls like x.map(_.y).
A proposal would be to just write x->y.

I think the following approach doesn't work, but maybe there is a similar
solution to it.

--------------------------------------
class Option[T] {
...
def -> :T = macro ...
...
}

So the -> operator returns an object of type T on which we could call the
member function. The macro takes this call to -> and adds .map() around it.
--------------------

Best regards,
Sebastian Meßmer

√iktor Ҡlang

unread,
Nov 8, 2012, 5:17:07 PM11/8/12
to scala-l...@googlegroups.com
scala> val x, y = 1
x: Int = 1
y: Int = 1

scala> x -> y
res0: (Int, Int) = (1,1)

Already taken?

--
Viktor Klang

Akka Tech Lead
Typesafe - The software stack for applications that scale

Twitter: @viktorklang

Vlad Patryshev

unread,
Nov 8, 2012, 5:20:46 PM11/8/12
to scala-l...@googlegroups.com

Might make sense to have a lightweight way to define composition, so that you'd have something like

option map (f ; g ; h), something like this.

Thanks,
-Vlad

Sebastian Meßmer

unread,
Nov 8, 2012, 5:41:35 PM11/8/12
to scala-l...@googlegroups.com

Am Donnerstag, 8. November 2012, 23:17:07 schrieb √iktor Ҡlang:

scala> val x, y = 1 x: Int = 1 y: Int = 1 scala> x -> y res0: (Int, Int) = (1,1) Already taken?



Right, didn't think about tuples. So we'd need a different operator for this.

Johannes Rudolph

unread,
Nov 9, 2012, 3:36:54 AM11/9/12
to scala-l...@googlegroups.com
You can use `Function1.andThen` and `.compose` to simplify those calls.

Here's a previous suggestion in similar spirit:

http://scala-programming-language.1934581.n4.nabble.com/is-there-a-way-to-have-NaN-for-Int-Long-Boolean-tp2289486p2294625.html
--
Johannes

-----------------------------------------------
Johannes Rudolph
http://virtual-void.net

Stephen Compall

unread,
Nov 10, 2012, 5:22:30 PM11/10/12
to scala-l...@googlegroups.com

On Nov 8, 2012 5:06 PM, "Sebastian Meßmer" <ma...@smessmer.de> wrote:
> when working with futures, options or list, one often has long map chains that
> just call member methods like
>
> val optString = Some("String1")
> val characterCounts = optString.map(_.groupBy(id=>id).map(_._2.size))
>
> Therefore I'm in favor of a way to simplify calls like x.map(_.y).

Your example isn't a map chain; map chains for genuine functors can always be restructured into a single map with the functions joined via function composition.

A truly pointfree way to write method-calling lambdas would be welcome, though.  However, I am not sure this would be so useful without the ability to delay inference of lambda argument types further.

--
Stephen Compall
If anyone in the MSA is online, you should watch this flythrough.

Sebastian Meßmer

unread,
Nov 11, 2012, 12:16:21 AM11/11/12
to scala-l...@googlegroups.com

Am Samstag, 10. November 2012, 17:22:30 schrieb Stephen Compall:

> Your example isn't a map chain; map chains for genuine functors can always
> be restructured into a single map with the functions joined via function
> composition.

 

You're right, the example isn't exactly a chain. You can't replace a map chain by function composition when there are other calls inbetween. An example is

val stringMap=Map("Key1"->"Value1","key2"->"Value2")
val characterCountOfLowercaseKeys = stringMap.map(_._1).filter(r=>r==r.toLowerCase).map(_.size).sum

This example looks very artificial for you could change the function call order and write

val characterCountOfLowercaseKeys = stringMap.filter(r=>r._1==r._1.toLowerCase).map(_._1.size).sum

But I already had cases where I really needed filtering inbetween two map calls.
And I think also if you don't have a map chain but a single map call, a more concise way to write it would be preferable. So shortening the first variant above:

val characterCountOfLowercaseKeys = stringMap->_1.filter(r=>r==r.toLowerCase)->_size.sum

 

As stated by Viktor, the "->" operator doesn't work because it's already used.

If we use an operator starting and ending with a dot, we could make implementation easier (for the middle part of the operator then just is the real operator name). But the dots of course reduce conciseness.

 

Sebastian Meßmer

Reply all
Reply to author
Forward
0 new messages