0

I was trying to figure out if function literal could have implicit parameters.

I found out in the post below that Function literal can not, by virtue of being FunctionN Object which do not have implicit parameter.

Scala Functional Literals with Implicits

However the answer contains the folloing as a trick

val sum2 = (a: Int) => {implicit b: Int => a + b}

I try to play around with it, but i am not really sure as to why it does compile and what exactly the construct implicit b: Int => a + b stand for.

I try for instance

val sum2 = (a: Int) => {(implicit b: Int) => a + b}

or

val sum2 = (a: Int) => {implicit (b: Int) => a + b}

Both do not compile. My assumption in both case was that we are returning a function literal in implicit b: Int => a + b . If so why the constructs above do not work. And why however the following construct works:

val sum2 = (e:Int) => { (f:Int) => e + f}

Can someone help me understand what is going on here ? I find it rather strange and incomprehensible.

Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
MaatDeamon
  • 9,532
  • 9
  • 60
  • 127
  • 2
    https://stackoverflow.com/questions/12685591/implicit-keyword-before-a-parameter-in-anonymous-function-in-scala https://stackoverflow.com/questions/18854829/scala-implicit-parameters-by-passing-a-function-as-argument-to-feel-the-adnvatag https://stackoverflow.com/questions/1025181/hidden-features-of-scala/5015161#5015161 – Dmytro Mitin Sep 08 '20 at 12:56

2 Answers2

2

This is not really creating a function with an implicit parameter. The function still has just a normal explicit parameter, it is just that in the body of that function that parameter is also an implicit value.

It is exactly the same as if you would have done this:

{ b: Int => implicit val bImplicit: Int = b; a + b }

So in your case it is juts useless since you still have to pass b explicitly when calling the function: sum2(1)(2)

  • Thank you so much for the translation here. But how do you know that it translate to that. What part of the scala spec am i missing, that is not allowing me to know that {implicit b: Int => a + b} = { b: Int => implicit val bImplicit: Int = b; a + b } – MaatDeamon Sep 08 '20 at 12:30
  • 1
    @MaatDaemon Being honest no idea, it is not a common feature AFAIK. I learnt about it here, someone used it in his/her answer on a post I also answered. – Luis Miguel Mejía Suárez Sep 08 '20 at 12:36
2

If so why the constructs above do not work.

Because SLS 6.23 Anonymous Functions specifies syntax as

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

Note the difference in meaning between EBNF notation ( and ‘(’. Former means grouping. If the following was legal

(implicit b: Int) => ???

then ResultExpr rule would specify ‘(’ and ‘)’ similarly to how they are present in Bindings rule.

Furthermore from the same SLS section

A named parameter of an anonymous function may be optionally preceded by an implicit modifier. In that case the parameter is labeled implicit; however the parameter section itself does not count as an implicit parameter section. Hence, arguments to anonymous functions always have to be given explicitly.

Mario Galic
  • 47,285
  • 6
  • 56
  • 98
  • So in your own words, what is an implicit named parameter of an anonymous class useful for ? an Internal implicit resolution by a function that the anonymous function would call ? – MaatDeamon Sep 16 '20 at 13:34
  • @MaatDeamon For example, it is often used in Play Framework to avoid having to pass the `request` argument explicitly around the handler code as essentially everything will need it https://www.playframework.com/documentation/2.8.x/ScalaActions#Building-an-Action – Mario Galic Sep 16 '20 at 13:41