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

Have any clever rules for the dot mark and parameter parenthesis mark can omitting?

8 replies
Solomon Sun
Joined: 2010-01-28,
User offline. Last seen 1 year 13 weeks ago.

Hi all,
In Scala,sometimes the dot mark and parameter parenthesis mark
can omit,but sometimes can not; Have any clever rules in these case?

scala> List(1,2,3) tail map(_ + 10)
:6: error: not found: value map
List(1,2,3) tail map(_ + 10)
^

scala> List(1,2,3) tail .map(_ + 10)
:1: error: ';' expected but '.' found.
List(1,2,3) tail .map(_ + 10)
^

scala> (List(1,2,3) tail ) map(_ + 10)
res13: List[Int] = List(12, 13)

scala> List(1,2,3) tail() map(_ + 10)
:6: error: not enough arguments for method apply: (n: Int)Int in trait
LinearSeqOptimized.
Unspecified value parameter n.
List(1,2,3) tail() map(_ + 10)
^

scala> List(1,2,3) .tail map(_ + 10)
res15: List[Int] = List(12, 13)

scala> List(1,2,3) .tail map _ + 10
:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).tail.map(x$1.$plus(10)))
List(1,2,3) .tail map _ + 10
^

scala> List(1,2,3) tail map(_ + 10)
:6: error: not found: value map
List(1,2,3) tail map(_ + 10)
^

scala> List(1,2,3) drop(1) map(_ + 10)
res18: List[Int] = List(12, 13)

scala> List(1,2,3) drop(1) map _ + 10
:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).drop(1).map(x$1.$plus(10)))
List(1,2,3) drop(1) map _ + 10
^

scala> List(1,2,3) drop 1 map(_ + 10)
res20: List[Int] = List(12, 13)

scala>

Jan Kriesten
Joined: 2009-01-13,
User offline. Last seen 2 years 39 weeks ago.
Re: Have any clever rules for the dot mark and parameter parent

Hi,

> In Scala,sometimes the dot mark and parameter parenthesis mark
> can omit,but sometimes can not; Have any clever rules in these case?

it can be ommitted when the function takes exactly one argument:

List(1,2,3) drop 1 map(_ + 10)

This

List(1,2,3) tail map(_ + 10)

doesn't work, cause tail doesn't take any arguments.

Best regards, --- Jan.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Have any clever rules for the dot mark and parameter parent

On Sun, Jul 18, 2010 at 12:07:20PM +0800, qihui sun wrote:
> In Scala,sometimes the dot mark and parameter parenthesis mark
> can omit,but sometimes can not; Have any clever rules in these case?

It is a simple rule, but not very easy to intuit. I will answer a
slightly different question and throw in some semicolon inference logic,
because the real payoff comes from being hip to both of them.

Missing dots: it's always either target.op() or target.op(arg),
extending that way out to infinity.

a b // a.b()
a b c // a.b(c)
a b c d // a.b(c).d()
a b c d e f g // a.b(c).d(e).f(g)

In practice this means if you need to throw a toList or tail or size in
the middle, the rhythym is broken and you need a dot or some parens.

A subtlety which arises when you try to abandon punctuation entirely
like I do is that a.b() is the fallback parse when there is no a.b(c)
parse. So if you write:

val x = Set(1) map (_ + 1) toList
println(5)

This will not compile, because the parser goes looking for another
argument. (Those argumentative parsers.) Whereas this:

val x = Set(1) map (_ + 1) toList
val y = println(5)

will compile fine, because the presence of a member definition on the
next line renders the previous one unambiguous. Or if you can handle
the occasional semicolon:

val x = Set(1) map (_ + 1) toList;
println(5)

I (un)consciously write most of my code so I can use it in a dot free
fashion, because I like writing like this:

def compilerPhaseList(): List[SubComponent] =
nodes.values.toList filter (_.level > 0) sortBy (x => (x.level, x.phasename)) flatMap (_.phaseobj) flatten

Goosebumps!

Ken Scambler
Joined: 2009-11-07,
User offline. Last seen 42 years 45 weeks ago.
Re: Have any clever rules for the dot mark and parameter paren
Damn, this is what happens when I type and think so slowly.  Paul's explanation is much clearer. :)

On 18 July 2010 16:47, Paul Phillips <paulp [at] improving [dot] org> wrote:
On Sun, Jul 18, 2010 at 12:07:20PM +0800, qihui sun wrote:
>      In Scala,sometimes the dot mark and parameter parenthesis mark
> can omit,but sometimes can not; Have any clever rules in these case?

It is a simple rule, but not very easy to intuit.  I will answer a
slightly different question and throw in some semicolon inference logic,
because the real payoff comes from being hip to both of them.

Missing dots: it's always either target.op() or target.op(arg),
extending that way out to infinity.

a b             // a.b()
a b c           // a.b(c)
a b c d         // a.b(c).d()
a b c d e f g   // a.b(c).d(e).f(g)

In practice this means if you need to throw a toList or tail or size in
the middle, the rhythym is broken and you need a dot or some parens.

A subtlety which arises when you try to abandon punctuation entirely
like I do is that a.b() is the fallback parse when there is no a.b(c)
parse.  So if you write:

   val x = Set(1) map (_ + 1) toList
   println(5)

This will not compile, because the parser goes looking for another
argument. (Those argumentative parsers.) Whereas this:

   val x = Set(1) map (_ + 1) toList
   val y = println(5)

will compile fine, because the presence of a member definition on the
next line renders the previous one unambiguous.  Or if you can handle
the occasional semicolon:

   val x = Set(1) map (_ + 1) toList;
   println(5)

I (un)consciously write most of my code so I can use it in a dot free
fashion, because I like writing like this:

   def compilerPhaseList(): List[SubComponent] =
     nodes.values.toList filter (_.level > 0) sortBy (x => (x.level, x.phasename)) flatMap (_.phaseobj) flatten

Goosebumps!

--
Paul Phillips      | Every normal man must be tempted at times
Protagonist        | to spit on his hands, hoist the black flag,
Empiricist         | and begin to slit throats.
i'll ship a pulp   |     -- H. L. Mencken

Ken Scambler
Joined: 2009-11-07,
User offline. Last seen 42 years 45 weeks ago.
Re: Have any clever rules for the dot mark and parameter paren
Not so -- you can drop the dot and parantheses for multiple arguments too: for
class Celebrant {
  def marry(p1: Person, p1: Person)
}
val celebrant: Celebrant
val john, debra: Person
you could do

scala> celebrant marry (john, debra)
for instance.

When the parantheses and dot are omitted, it's always evaluated as so (for operators of equal precedence!):

a b c d e f g h
=
a.b(c).d(e).f(g).h

1 + 2 + 3 - 4
=
1.+(2).+(3).-(4)

if we used a method starting with a higher precedence character such as *, then it comes out slightly differently....
1 + 2 * 3 + 6 * 9
=
1.+(2.*(3)).+(6.*(9))

To take one of your examples:
List(1,2,3) tail map(_ + 10)

by the above rules, the compiler is trying to do this:

List(1,2,3).tail(map(_ + 10)

...which obviously fails.

Generally, you need to use dots to make no-arg methods work well here:

List(1,2,3).tail map (_ + 10) // This will work as expected

Although these rules might sound confusing, they operate in an intuitive way, if you keep in mind the arithmetic example above, that the feature is really designed to support.  In general though, don't try to be too clever: if it isn't obvious from reading your code how the method calls pan out, then you probably should just use the dot syntax in full.

Ken.



On 18 July 2010 14:24, Jan Kriesten <kriesten [at] mail [dot] footprint [dot] de> wrote:

Hi,

>      In Scala,sometimes the dot mark and parameter parenthesis mark
> can omit,but sometimes can not; Have any clever rules in these case?

it can be ommitted when the function takes exactly one argument:

List(1,2,3) drop 1 map(_ + 10)

This

List(1,2,3) tail map(_ + 10)

doesn't work, cause tail doesn't take any arguments.


Best regards, --- Jan.


Jan Kriesten
Joined: 2009-01-13,
User offline. Last seen 2 years 39 weeks ago.
Re: Have any clever rules for the dot mark and parameter paren

Hi Ken,

> Not so -- you can drop the dot and parantheses for multiple arguments
> too: for
> scala> celebrant marry (john, debra)
> for instance.

well, you actually didn't drop the dots for multiple arguments here -
you have your arguments within braces which makes it look like one to
the compiler!

> When the parantheses and dot are omitted, it's always evaluated as so
> (for operators of equal precedence!):
>
> a b c d e f g h
> =
> a.b(c).d(e).f(g).h

There we go - it's always evaluated as 1 function, 1 argument, not? The
last function in chain may or not have an argument, though.

Best regards, --- Jan.

extempore
Joined: 2008-12-17,
User offline. Last seen 35 weeks 3 days ago.
Re: Have any clever rules for the dot mark and parameter parent

On Sun, Jul 18, 2010 at 09:28:01AM +0200, Jan Kriesten wrote:
> well, you actually didn't drop the dots for multiple arguments here -
> you have your arguments within braces which makes it look like one to
> the compiler!

Like one argument list anyway.

> There we go - it's always evaluated as 1 function, 1 argument, not?
> The last function in chain may or not have an argument, though.

We can easily demonstrate otherwise if you are using the normal
definition of arugment.

scala> class A { def f(x: Int, y: Int) = List(x, y) }
defined class A

scala> new A f (5, 10) mkString ("a", "b", "c")
res2: String = a5b10c

Trying for multiple arguments probably opens up a can of surprise worms
due to auto-tupling, plus it's kind of confusing what's going on in
there, so I wouldn't really recommend it.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Have any clever rules for the dot mark and parameter paren
http://stackoverflow.com/questions/1181533/what-are-the-precise-rules-for-when-you-can-omit-parenthesis-dots-braces-fu


On Sun, Jul 18, 2010 at 1:07 AM, qihui sun <qihui [dot] sun [at] gmail [dot] com> wrote:
Hi all,
    In Scala,sometimes the dot mark and parameter parenthesis mark
can omit,but sometimes can not; Have any clever rules in these case?


scala> List(1,2,3) tail map(_ + 10)
<console>:6: error: not found: value map
      List(1,2,3) tail map(_ + 10)
                       ^

scala> List(1,2,3) tail .map(_ + 10)
<console>:1: error: ';' expected but '.' found.
      List(1,2,3) tail .map(_ + 10)
                       ^

scala> (List(1,2,3) tail ) map(_ + 10)
res13: List[Int] = List(12, 13)

scala> List(1,2,3) tail() map(_ + 10)
<console>:6: error: not enough arguments for method apply: (n: Int)Int in trait
LinearSeqOptimized.
Unspecified value parameter n.
      List(1,2,3) tail() map(_ + 10)
                  ^

scala> List(1,2,3) .tail map(_ + 10)
res15: List[Int] = List(12, 13)

scala> List(1,2,3) .tail map _ + 10
<console>:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).tail.map(x$1.$plus(10)))
      List(1,2,3) .tail map _ + 10
                            ^

scala> List(1,2,3) tail map(_ + 10)
<console>:6: error: not found: value map
      List(1,2,3) tail map(_ + 10)
                       ^

scala> List(1,2,3) drop(1) map(_ + 10)
res18: List[Int] = List(12, 13)

scala> List(1,2,3) drop(1) map _ + 10
<console>:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).drop(1).map(x$1.$plus(10)))
      List(1,2,3) drop(1) map _ + 10
                              ^

scala> List(1,2,3) drop 1 map(_ + 10)
res20: List[Int] = List(12, 13)

scala>



--
Daniel C. Sobral

I travel to the future all the time.
Antony Stubbs
Joined: 2009-07-10,
User offline. Last seen 1 year 4 hours ago.
Re: Have any clever rules for the dot mark and parameter parent
You beat me to it :)
On Jul 21, 2010, at 11:44 AM, Daniel Sobral wrote:
http://stackoverflow.com/questions/1181533/what-are-the-precise-rules-for-when-you-can-omit-parenthesis-dots-braces-fu


On Sun, Jul 18, 2010 at 1:07 AM, qihui sun <qihui [dot] sun [at] gmail [dot] com> wrote:
Hi all,
    In Scala,sometimes the dot mark and parameter parenthesis mark
can omit,but sometimes can not; Have any clever rules in these case?


scala> List(1,2,3) tail map(_ + 10)
<console>:6: error: not found: value map
      List(1,2,3) tail map(_ + 10)
                       ^

scala> List(1,2,3) tail .map(_ + 10)
<console>:1: error: ';' expected but '.' found.
      List(1,2,3) tail .map(_ + 10)
                       ^

scala> (List(1,2,3) tail ) map(_ + 10)
res13: List[Int] = List(12, 13)

scala> List(1,2,3) tail() map(_ + 10)
<console>:6: error: not enough arguments for method apply: (n: Int)Int in trait
LinearSeqOptimized.
Unspecified value parameter n.
      List(1,2,3) tail() map(_ + 10)
                  ^

scala> List(1,2,3) .tail map(_ + 10)
res15: List[Int] = List(12, 13)

scala> List(1,2,3) .tail map _ + 10
<console>:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).tail.map(x$1.$plus(10)))
      List(1,2,3) .tail map _ + 10
                            ^

scala> List(1,2,3) tail map(_ + 10)
<console>:6: error: not found: value map
      List(1,2,3) tail map(_ + 10)
                       ^

scala> List(1,2,3) drop(1) map(_ + 10)
res18: List[Int] = List(12, 13)

scala> List(1,2,3) drop(1) map _ + 10
<console>:6: error: missing parameter type for expanded function ((x$1) => List(
1, 2, 3).drop(1).map(x$1.$plus(10)))
      List(1,2,3) drop(1) map _ + 10
                              ^

scala> List(1,2,3) drop 1 map(_ + 10)
res20: List[Int] = List(12, 13)

scala>



--
Daniel C. Sobral

I travel to the future all the time.

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