Moje zdjęcie
Software Craftsman's Blog by Marcin Pieciukiewicz
Java and Scala development

Monday, July 15, 2013

Scala - Parentheses and Curly Brackets in Anonymous Functions

Scala gives a lot of flexibility in defining anonymous functions, and that might lead to a confussion. Jacek Laskowski asked an interesting question on stackoverflow.com regarding of calling a map method on collection. To summarize it (given a list lst):

Why lst map {c:Char => 1} and lst map ((c:Char) => 1) work fine, but lst map (c:Char => 1) gives us compilation error:

 error: identifier expected but integer literal found.
       lst map (c:Char => 1)


To answer this question we should look into Scala Language Specification, into part 6.23 Anonymous Functions.There is a description how anonymous function can be defined:

Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr
ResultExpr ::= (Bindings | ([‘implicit’] id | ‘_’) ‘:’ CompoundType) ‘=>’ Block
Bindings ::= ‘(’ Binding {‘,’ Binding} ‘)’
Binding ::= (id | ‘_’) [‘:’ Type]

As you can see Bindings requires to be placed inside two surrounding parentheses. So if anonymous function defines the type of the parameter, as in our example, it has to be defined in this way:
(c:Char) => 1
And the call to map should look like that:
lst map((c:Char) => 1)
Also in the same part of reference documentation we can find:

If an anonymous function (x: T) => e with a single typed parameter appears as the result expression of a block, it can be abbreviated to x: T => e

So if anonymous function is defied as last expression in a code block, and has exacly one parameter, you can use abbreviated syntax, without parenthesis around c:Char, to define anonymous function. So, in our example, we can write c:Char => 1, but only when we place it inside a code block {c:Char => 1}. And we can call map function this way:
lst map({c:Char => 1})
or with abbreviated syntax without parenthesis:
lst map {c:Char => 1}
And that explains main question why lst map {c:Char => 1} is legal, and lst map (c:Char => 1) is not.

This is summarized in changelog at the end of the documentation (Changes in Version 2.1.7 (19-Jul-2006)):

Closure Syntax

The syntax of closures has been slightly restricted (§6.23). The form

x: T => E

is valid only when enclosed in braces, i.e. { x: T => E }. The following is illegal, because it might be read as the value x typed with the type T => E:

val f = x: T => E

Legal alternatives are:

val f = { x: T => E }
val f = (x: T) => E


Another way to specify anonymous functions:

If we look closer at specification we can see that it allows us to use another way to define anonymous function:

Expr ::= (Bindings | [‘implicit’] id | ‘_’) ‘=>’ Expr

We can see that we can define your anonymous function without parameter binding in those two ways (if we don't need to specify argument type):
lst map (c => 1)
// or
lst map (_ => 1)
I hope that this article clarified how we can declare anonymous functions and it shouldn't cause a confusion any more.

Next article: Neat and simple way to measure code performance in Scala
Previous article: Named and Default parameters inconsistency in Scala

9 comments:

  1. That is the excellent mindset, nonetheless is just not help to make every sence whatsoever preaching about that mather. Virtually any method many thanks in addition to i had endeavor to promote your own article in to delicius nevertheless it is apparently a dilemma using your information sites can you please recheck the idea. thanks once more. jobs for blockchain mobile developers

    ReplyDelete
  2. It's very useful blog post with inforamtive and insightful content and i had good experience with this information.I have gone through CRS Info Solutions Home which really nice. Learn more details About Us of CRS info solutions. Here you can see the Courses CRS Info Solutions full list. Find Student Registration page and register now. Go through Blog post of crs info solutions. I just read these Reviews of crs really great. You can now Contact Us of crs info solutions. You enroll for Pega Training at crs info solutions.

    ReplyDelete
  3. This comment has been removed by the author.

    ReplyDelete
  4. Great Article
    Cyber Security Projects

    projects for cse

    Networking Projects

    JavaScript Training in Chennai

    JavaScript Training in Chennai

    The Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals, Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer. Angular Training

    ReplyDelete
  5. Wow! Such an amazing and helpful post this is. I really really love it. I hope that you continue to do your work like this in the future also.

    Online Training for Big Data
    Big Data Hadoop Online Training

    ReplyDelete
  6. This information is really awesome thanks for sharing most valuable information.
    AWS Training in Pune
    Best RPA Training in Pune

    ReplyDelete
  7. This is most informative and also this post most user-friendly and super navigation to all posts.
    Data Science Course in Pune
    Python Classes in Pune

    ReplyDelete
  8. It is amazing and wonderful to visit your site. Thanks for sharing this information; this is very useful. We are also providing the best services click on below links to visit our website.
    Oracle Fusion HCM Training
    Workday Training
    Okta Training
    Palo Alto Training
    Adobe Analytics Training

    ReplyDelete