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

Strange behavior when combing implicit conversion with () => Unit input parameter

31 replies
Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.

Hi Scala gurus,

I've started using Scala quite recently, and came upon what seems like
a strange and inconsistent behavior of the scala compiler.
As I work quite a bit with Threads, I create Runnable implementations
(the reason I am using ThreadPoolExecutor and not Actors is out of
scope for this issue).

I hope someone here can shade some light and explain what's going on
here and why it seems (to me) like an inconsistent handling of the
scala compiler.

In order to write the most elegant code I can with Runnable, I've
played with implicit and explicit conversions from a code block to a
Runnable. What I've found can be summarized as (see the code below)

()=>Unit implicitly converted to Runnable - does not work as expected
- prints hello 1 once
()=>Unit explicitly converted to Runnable - does work as expected -
prints hello 1 twice
(String)=>Unit implicitly converted to RunnableString - does work as
expected - prints hello 1 twice
(String)=>Unit explicitly converted to RunnableString - does work as
expected - prints hello 1 twice

Cheers,
Yoav

The code -
I've tried to introduce the following implicit conversion.

implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
println("converting...")
def run = {
x
}
}

Then to use it the following way

def playRunnableImplicit() {
println("playRunnableImplicit")
playRunnable({
println("hello 1")
println("hello 2")
})
}

where the method playRunnable (a method written to make the issue here
explicit) is

def playRunnable(r: Runnable): Unit = {
println("playRunnable.playing runnable")
r.run()
println("playRunnable.playing the runnable a second time")
r.run()
println("playRunnable.played runnable")
}

when running the playRunnableImplicit, the printed output is not what
I'd expect
playRunnableImplicit
hello 1
converting...
playRunnable.playing runnable
hello 2
playRunnable.playing the runnable a second time
hello 2
playRunnable.played runnable

The problem is that the first statement of the code block given to the
conversion is executed before the implicit conversion is done.

When using explicit conversion, we get the following

def playRunnableExplicit() {
println("playRunnableExplicit")
playRunnable(funcToRunnable({
println("hello 1")
println("hello 2")
}))
}

playRunnableExplicit
converting...
playRunnable.playing runnable
hello 1
hello 2
playRunnable.playing the runnable a second time
hello 1
hello 2
playRunnable.played runnable

interesting that by just adding the explicit conversion instead of the
implicit conversion, we get a different result.

Also, If we use the same pattern for an implicit conversion from
anything other then ()=>Unit block, it all works as expected. For
instance, if we define a trait RunnableString and a conversion from
(String)=>Unit, such as below, everything works as expected

trait RunnableString {
def run(s: String)
}

implicit def funcToRunnableString(x: String => Unit): RunnableString
= new RunnableString {
println("converting...")
def run(s: String) = {
x(s)
}
}

def playRunnableString(r: RunnableString): Unit = {
println("playRunnable.playing runnable")
r.run("a")
println("playRunnable.playing the runnable a second time")
r.run("b")
println("playRunnable.played runnable")
}

def playRunnableStringImplicit() {
println("playRunnableStringImplicit")
playRunnableString({s: String =>
println("hello 1 " + s)
println("hello 2 " + s)
})
}

def playRunnableStringExplicit() {
println("playRunnableStringExplicit")
playRunnableString(funcToRunnableString({s: String =>
println("hello 1 " + s)
println("hello 2 " + s)
}))
}

and the output is then
playRunnableStringImplicit
converting...
playRunnable.playing runnable
hello 1 a
hello 2 a
playRunnable.playing the runnable a second time
hello 1 b
hello 2 b
playRunnable.played runnable

playRunnableStringExplicit
converting...
playRunnable.playing runnable
hello 1 a
hello 2 a
playRunnable.playing the runnable a second time
hello 1 b
hello 2 b
playRunnable.played runnable

iainmcgin
Joined: 2011-07-19,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =
I think what you might be bumping up against here is that blocks are not actually functions:
http://daily-scala.blogspot.com/2010/05/return-value-of-block.html http://downgra.de/2010/08/05/scala_gotcha_blocks_and_functions/
I think what you needed to do was:
def playRunnableImplicit() {
   println("playRunnableImplicit")
   playRunnable(() => {
     println("hello 1")
     println("hello 2")
   })
 }
It seems there are some funny rules which I don't claim to fully understand influencing your examples, but perhaps the above links can help clarify things (or someone else can jump in and describe much more eloquently what's happening).
Iain
On Fri, Jul 22, 2011 at 12:23 PM, Yoav Abrahami <yoavaa [at] gmail [dot] com> wrote:
Hi Scala gurus,

I've started using Scala quite recently, and came upon what seems like
a strange and inconsistent behavior of the scala compiler.
As I work quite a bit with Threads, I create Runnable implementations
(the reason I am using ThreadPoolExecutor and not Actors is out of
scope for this issue).

I hope someone here can shade some light and explain what's going on
here and why it seems (to me) like an inconsistent handling of the
scala compiler.

In order to write the most elegant code I can with Runnable, I've
played with implicit and explicit conversions from a code block to a
Runnable. What I've found can be summarized as (see the code below)

()=>Unit implicitly converted to Runnable - does not work as expected
- prints hello 1 once
()=>Unit explicitly converted to Runnable - does work as expected -
prints hello 1 twice
(String)=>Unit implicitly converted to RunnableString - does work as
expected - prints hello 1 twice
(String)=>Unit explicitly converted to RunnableString - does work as
expected - prints hello 1 twice

Cheers,
 Yoav

The code -
I've tried to introduce the following implicit conversion.

 implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
   println("converting...")
   def run = {
     x
   }
 }

Then to use it the following way

 def playRunnableImplicit() {
   println("playRunnableImplicit")
   playRunnable({
     println("hello 1")
     println("hello 2")
   })
 }

where the method playRunnable (a method written to make the issue here
explicit) is

 def playRunnable(r: Runnable): Unit = {
   println("playRunnable.playing runnable")
   r.run()
   println("playRunnable.playing the runnable a second time")
   r.run()
   println("playRunnable.played runnable")
 }

when running the playRunnableImplicit, the printed output is not what
I'd expect
playRunnableImplicit
hello 1
converting...
playRunnable.playing runnable
hello 2
playRunnable.playing the runnable a second time
hello 2
playRunnable.played runnable

The problem is that the first statement of the code block given to the
conversion is executed before the implicit conversion is done.

When using explicit conversion, we get the following

 def playRunnableExplicit() {
   println("playRunnableExplicit")
   playRunnable(funcToRunnable({
     println("hello 1")
     println("hello 2")
   }))
 }

playRunnableExplicit
converting...
playRunnable.playing runnable
hello 1
hello 2
playRunnable.playing the runnable a second time
hello 1
hello 2
playRunnable.played runnable

interesting that by just adding the explicit conversion instead of the
implicit conversion, we get a different result.

Also, If we use the same pattern for an implicit conversion from
anything other then ()=>Unit block, it all works as expected. For
instance, if we define a trait RunnableString and a conversion from
(String)=>Unit, such as below, everything works as expected


 trait RunnableString {
   def run(s: String)
 }

 implicit def funcToRunnableString(x: String => Unit): RunnableString
= new RunnableString {
   println("converting...")
   def run(s: String) = {
     x(s)
   }
 }

 def playRunnableString(r: RunnableString): Unit = {
   println("playRunnable.playing runnable")
   r.run("a")
   println("playRunnable.playing the runnable a second time")
   r.run("b")
   println("playRunnable.played runnable")
 }

 def playRunnableStringImplicit() {
   println("playRunnableStringImplicit")
   playRunnableString({s: String =>
     println("hello 1 " + s)
     println("hello 2 " + s)
   })
 }

 def playRunnableStringExplicit() {
   println("playRunnableStringExplicit")
   playRunnableString(funcToRunnableString({s: String =>
     println("hello 1 " + s)
     println("hello 2 " + s)
   }))
 }

and the output is then
playRunnableStringImplicit
converting...
playRunnable.playing runnable
hello 1 a
hello 2 a
playRunnable.playing the runnable a second time
hello 1 b
hello 2 b
playRunnable.played runnable

playRunnableStringExplicit
converting...
playRunnable.playing runnable
hello 1 a
hello 2 a
playRunnable.playing the runnable a second time
hello 1 b
hello 2 b
playRunnable.played runnable


dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Strange behavior when combing implicit conversion with () =

On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
> Hi Scala gurus,
>
> In order to write the most elegant code I can with Runnable, I've
> played with implicit and explicit conversions from a code block to a
> Runnable. What I've found can be summarized as (see the code below)

Code block is not an object. There's no "thunk" in Scala -- you either
have a function, or you don't. A code of block is simply a syntactical
scope whose value is that of the last statement. So you can't
"convert" a code block into something.

>
> ()=>Unit implicitly converted to Runnable - does not work as expected
> - prints hello 1 once

"() => Unit" is a function with one parameter list of arity 0. A
Function0, in other words.

>  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {

A "=> Unit" is not a function at all. "=> Unit" is the same thing as
"Unit", but the parameter is passed by name instead of by value. In
practice, it means whatever is passed in place of the parameter is not
first evaluated and then have its value passed but, instead, is passed
"as is", and evaluated it time it is used.

Anyway, "=> Unit" is different than "() => Unit".

>    println("converting...")
>    def run = {
>      x
>    }
>  }
>
>  def playRunnableImplicit() {
>    println("playRunnableImplicit")
>    playRunnable({
>      println("hello 1")
>      println("hello 2")
>    })

So, the parameter is { println("hello 1"); println("hello 2") }, which
does not conform to Runnable. However, there's a conversion from Unit
to Runnable, and the type of that parameter is Unit. The value of a
block is the value of it's last statement, but since Unit is being
passed by name, println("hello 2") is passed instead of just ()
(return value of println, not to be confused with empty parameter
list).

>  }

At any rate, even if what you want were doable, it wouldn't be a good
idea. That's a gratuitous implicit conversion, saving a single token.
If, instead, you named funcToRunnable just "runnable", you could then
write

playRunnable(runnable { print("hello 1"); print("hello 2") })

No implicits required, and very little syntactic overhead.

Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Iain,

thanks for your answer.
I have tried writing things like
   playRunnable(() => {
   playRunnable( => {
   playRunnable({ () =>
   playRunnable({ =>

but non of them compile.
I still did not find how to make scala consider a "code block" as a
()=>Unit func.

On Jul 22, 9:05 pm, Iain McGinniss wrote:
> I think what you might be bumping up against here is that blocks are not
> actually functions:
>
> http://daily-scala.blogspot.com/2010/05/return-value-of-block.htmlhttp:/...
>
> I think what you needed to do was:
>
> def playRunnableImplicit() {
>    println("playRunnableImplicit")
>    playRunnable(() => {
>      println("hello 1")
>      println("hello 2")
>    })
>  }
>
> It seems there are some funny rules which I don't claim to fully understand
> influencing your examples, but perhaps the above links can help clarify
> things (or someone else can jump in and describe much more eloquently what's
> happening).
>
> Iain
>
>
>
>
>
>
>
> On Fri, Jul 22, 2011 at 12:23 PM, Yoav Abrahami wrote:
> > Hi Scala gurus,
>
> > I've started using Scala quite recently, and came upon what seems like
> > a strange and inconsistent behavior of the scala compiler.
> > As I work quite a bit with Threads, I create Runnable implementations
> > (the reason I am using ThreadPoolExecutor and not Actors is out of
> > scope for this issue).
>
> > I hope someone here can shade some light and explain what's going on
> > here and why it seems (to me) like an inconsistent handling of the
> > scala compiler.
>
> > In order to write the most elegant code I can with Runnable, I've
> > played with implicit and explicit conversions from a code block to a
> > Runnable. What I've found can be summarized as (see the code below)
>
> > ()=>Unit implicitly converted to Runnable - does not work as expected
> > - prints hello 1 once
> > ()=>Unit explicitly converted to Runnable - does work as expected -
> > prints hello 1 twice
> > (String)=>Unit implicitly converted to RunnableString - does work as
> > expected - prints hello 1 twice
> > (String)=>Unit explicitly converted to RunnableString - does work as
> > expected - prints hello 1 twice
>
> > Cheers,
> >  Yoav
>
> > The code -
> > I've tried to introduce the following implicit conversion.
>
> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
> >    println("converting...")
> >    def run = {
> >      x
> >    }
> >  }
>
> > Then to use it the following way
>
> >  def playRunnableImplicit() {
> >    println("playRunnableImplicit")
> >    playRunnable({
> >      println("hello 1")
> >      println("hello 2")
> >    })
> >  }
>
> > where the method playRunnable (a method written to make the issue here
> > explicit) is
>
> >  def playRunnable(r: Runnable): Unit = {
> >    println("playRunnable.playing runnable")
> >    r.run()
> >    println("playRunnable.playing the runnable a second time")
> >    r.run()
> >    println("playRunnable.played runnable")
> >  }
>
> > when running the playRunnableImplicit, the printed output is not what
> > I'd expect
> > playRunnableImplicit
> > hello 1
> > converting...
> > playRunnable.playing runnable
> > hello 2
> > playRunnable.playing the runnable a second time
> > hello 2
> > playRunnable.played runnable
>
> > The problem is that the first statement of the code block given to the
> > conversion is executed before the implicit conversion is done.
>
> > When using explicit conversion, we get the following
>
> >  def playRunnableExplicit() {
> >    println("playRunnableExplicit")
> >    playRunnable(funcToRunnable({
> >      println("hello 1")
> >      println("hello 2")
> >    }))
> >  }
>
> > playRunnableExplicit
> > converting...
> > playRunnable.playing runnable
> > hello 1
> > hello 2
> > playRunnable.playing the runnable a second time
> > hello 1
> > hello 2
> > playRunnable.played runnable
>
> > interesting that by just adding the explicit conversion instead of the
> > implicit conversion, we get a different result.
>
> > Also, If we use the same pattern for an implicit conversion from
> > anything other then ()=>Unit block, it all works as expected. For
> > instance, if we define a trait RunnableString and a conversion from
> > (String)=>Unit, such as below, everything works as expected
>
> >  trait RunnableString {
> >    def run(s: String)
> >  }
>
> >  implicit def funcToRunnableString(x: String => Unit): RunnableString
> > = new RunnableString {
> >    println("converting...")
> >    def run(s: String) = {
> >      x(s)
> >    }
> >  }
>
> >  def playRunnableString(r: RunnableString): Unit = {
> >    println("playRunnable.playing runnable")
> >    r.run("a")
> >    println("playRunnable.playing the runnable a second time")
> >    r.run("b")
> >    println("playRunnable.played runnable")
> >  }
>
> >  def playRunnableStringImplicit() {
> >    println("playRunnableStringImplicit")
> >    playRunnableString({s: String =>
> >      println("hello 1 " + s)
> >      println("hello 2 " + s)
> >    })
> >  }
>
> >  def playRunnableStringExplicit() {
> >    println("playRunnableStringExplicit")
> >    playRunnableString(funcToRunnableString({s: String =>
> >      println("hello 1 " + s)
> >      println("hello 2 " + s)
> >    }))
> >  }
>
> > and the output is then
> > playRunnableStringImplicit
> > converting...
> > playRunnable.playing runnable
> > hello 1 a
> > hello 2 a
> > playRunnable.playing the runnable a second time
> > hello 1 b
> > hello 2 b
> > playRunnable.played runnable
>
> > playRunnableStringExplicit
> > converting...
> > playRunnable.playing runnable
> > hello 1 a
> > hello 2 a
> > playRunnable.playing the runnable a second time
> > hello 1 b
> > hello 2 b
> > playRunnable.played runnable

Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Daniel,
What I fail to understand is why I cannot create a function / method
that does not get any parameters.
The case with RunnableString clearly works as scala considers the
block
{ s: String =>
println("hello 1 " + s)
println("hello 2 " + s)
}
as a function, while it does not consider the block
{
println("hello 1")
println("hello 2")
}
as a function

is there a syntactic way to express in scala something that does not
get input parameters but such that can be evaluated later?

Thanks,
Yoav

On Jul 22, 10:20 pm, Daniel Sobral wrote:
> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
> > Hi Scala gurus,
>
> > In order to write the most elegant code I can with Runnable, I've
> > played with implicit and explicit conversions from a code block to a
> > Runnable. What I've found can be summarized as (see the code below)
>
> Code block is not an object. There's no "thunk" in Scala -- you either
> have a function, or you don't. A code of block is simply a syntactical
> scope whose value is that of the last statement. So you can't
> "convert" a code block into something.
>
>
>
> > ()=>Unit implicitly converted to Runnable - does not work as expected
> > - prints hello 1 once
>
> "() => Unit" is a function with one parameter list of arity 0. A
> Function0, in other words.
>
> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>
> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
> "Unit", but the parameter is passed by name instead of by value. In
> practice, it means whatever is passed in place of the parameter is not
> first evaluated and then have its value passed but, instead, is passed
> "as is", and evaluated it time it is used.
>
> Anyway, "=> Unit" is different than "() => Unit".
>
> >    println("converting...")
> >    def run = {
> >      x
> >    }
> >  }
>
> >  def playRunnableImplicit() {
> >    println("playRunnableImplicit")
> >    playRunnable({
> >      println("hello 1")
> >      println("hello 2")
> >    })
>
> So, the parameter is { println("hello 1"); println("hello 2") }, which
> does not conform to Runnable. However, there's a conversion from Unit
> to Runnable, and the type of that parameter is Unit. The value of a
> block is the value of it's last statement, but since Unit is being
> passed by name, println("hello 2") is passed instead of just ()
> (return value of println, not to be confused with empty parameter
> list).
>
> >  }
>
> At any rate, even if what you want were doable, it wouldn't be a good
> idea. That's a gratuitous implicit conversion, saving a single token.
> If, instead, you named funcToRunnable just "runnable", you could then
> write
>
> playRunnable(runnable { print("hello 1"); print("hello 2") })
>
> No implicits required, and very little syntactic overhead.
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

def block2fun0[T](block: => T): () => T = () => block

On Jul 23, 2011 12:46 PM, "Yoav Abrahami" <yoavaa [at] gmail [dot] com> wrote:
> Daniel,
> What I fail to understand is why I cannot create a function / method
> that does not get any parameters.
> The case with RunnableString clearly works as scala considers the
> block
> { s: String =>
> println("hello 1 " + s)
> println("hello 2 " + s)
> }
> as a function, while it does not consider the block
> {
> println("hello 1")
> println("hello 2")
> }
> as a function
>
> is there a syntactic way to express in scala something that does not
> get input parameters but such that can be evaluated later?
>
> Thanks,
> Yoav
>
>
>
> On Jul 22, 10:20 pm, Daniel Sobral <dcsob [dot] [dot] [dot] [at] gmail [dot] com> wrote:
>> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami <yoa [dot] [dot] [dot] [at] gmail [dot] com> wrote:
>> > Hi Scala gurus,
>>
>> > In order to write the most elegant code I can with Runnable, I've
>> > played with implicit and explicit conversions from a code block to a
>> > Runnable. What I've found can be summarized as (see the code below)
>>
>> Code block is not an object. There's no "thunk" in Scala -- you either
>> have a function, or you don't. A code of block is simply a syntactical
>> scope whose value is that of the last statement. So you can't
>> "convert" a code block into something.
>>
>>
>>
>> > ()=>Unit implicitly converted to Runnable - does not work as expected
>> > - prints hello 1 once
>>
>> "() => Unit" is a function with one parameter list of arity 0. A
>> Function0, in other words.
>>
>> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>>
>> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
>> "Unit", but the parameter is passed by name instead of by value. In
>> practice, it means whatever is passed in place of the parameter is not
>> first evaluated and then have its value passed but, instead, is passed
>> "as is", and evaluated it time it is used.
>>
>> Anyway, "=> Unit" is different than "() => Unit".
>>
>> >    println("converting...")
>> >    def run = {
>> >      x
>> >    }
>> >  }
>>
>> >  def playRunnableImplicit() {
>> >    println("playRunnableImplicit")
>> >    playRunnable({
>> >      println("hello 1")
>> >      println("hello 2")
>> >    })
>>
>> So, the parameter is { println("hello 1"); println("hello 2") }, which
>> does not conform to Runnable. However, there's a conversion from Unit
>> to Runnable, and the type of that parameter is Unit. The value of a
>> block is the value of it's last statement, but since Unit is being
>> passed by name, println("hello 2") is passed instead of just ()
>> (return value of println, not to be confused with empty parameter
>> list).
>>
>> >  }
>>
>> At any rate, even if what you want were doable, it wouldn't be a good
>> idea. That's a gratuitous implicit conversion, saving a single token.
>> If, instead, you named funcToRunnable just "runnable", you could then
>> write
>>
>> playRunnable(runnable { print("hello 1"); print("hello 2") })
>>
>> No implicits required, and very little syntactic overhead.
>>
>> --
>> Daniel C. Sobral
>>
>> I travel to the future all the time.
Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

hi Viktor and Daniel,
Thanks for your answer.
Viktor, the block2fun0 creates a () => T func. I am wondering about
creating a () => Unit, which is a bit different.

Let me try to clarify my question -
Consider the following code block
{println("hello 1"); println("hello 2") }

now consider using the following to convert it to a runnable
implicit def funcToRunnable(x: => Unit): Runnable = new Runnable
{ def run = { x } }

I fail to understand why Scala considers g(funcToRunnable(block)) as
one thing and g(block) (with implicit conversion) as something
else...
aren't the rules for implicit conversion are that it should do the
same thing as if we were using explicit conversion?

It seems that the Scala compiler does the following
in the case of explicit conversion - considers all the code block as a
() => Unit and passes all the block to the funcToRunnable method.
in the case of implicit conversion - executes the code block, taking
only the last statement and passes it to the funcToRunnable method.
strange, it's it?

On Jul 23, 4:21 pm, √iktor Ҡlang wrote:
> def block2fun0[T](block: => T): () => T = () => block
> On Jul 23, 2011 12:46 PM, "Yoav Abrahami" wrote:
>
>
>
>
>
>
>
> > Daniel,
> > What I fail to understand is why I cannot create a function / method
> > that does not get any parameters.
> > The case with RunnableString clearly works as scala considers the
> > block
> > { s: String =>
> > println("hello 1 " + s)
> > println("hello 2 " + s)
> > }
> > as a function, while it does not consider the block
> > {
> > println("hello 1")
> > println("hello 2")
> > }
> > as a function
>
> > is there a syntactic way to express in scala something that does not
> > get input parameters but such that can be evaluated later?
>
> > Thanks,
> > Yoav
>
> > On Jul 22, 10:20 pm, Daniel Sobral wrote:
> >> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
> >> > Hi Scala gurus,
>
> >> > In order to write the most elegant code I can with Runnable, I've
> >> > played with implicit and explicit conversions from a code block to a
> >> > Runnable. What I've found can be summarized as (see the code below)
>
> >> Code block is not an object. There's no "thunk" in Scala -- you either
> >> have a function, or you don't. A code of block is simply a syntactical
> >> scope whose value is that of the last statement. So you can't
> >> "convert" a code block into something.
>
> >> > ()=>Unit implicitly converted to Runnable - does not work as expected
> >> > - prints hello 1 once
>
> >> "() => Unit" is a function with one parameter list of arity 0. A
> >> Function0, in other words.
>
> >> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>
> >> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
> >> "Unit", but the parameter is passed by name instead of by value. In
> >> practice, it means whatever is passed in place of the parameter is not
> >> first evaluated and then have its value passed but, instead, is passed
> >> "as is", and evaluated it time it is used.
>
> >> Anyway, "=> Unit" is different than "() => Unit".
>
> >> >    println("converting...")
> >> >    def run = {
> >> >      x
> >> >    }
> >> >  }
>
> >> >  def playRunnableImplicit() {
> >> >    println("playRunnableImplicit")
> >> >    playRunnable({
> >> >      println("hello 1")
> >> >      println("hello 2")
> >> >    })
>
> >> So, the parameter is { println("hello 1"); println("hello 2") }, which
> >> does not conform to Runnable. However, there's a conversion from Unit
> >> to Runnable, and the type of that parameter is Unit. The value of a
> >> block is the value of it's last statement, but since Unit is being
> >> passed by name, println("hello 2") is passed instead of just ()
> >> (return value of println, not to be confused with empty parameter
> >> list).
>
> >> >  }
>
> >> At any rate, even if what you want were doable, it wouldn't be a good
> >> idea. That's a gratuitous implicit conversion, saving a single token.
> >> If, instead, you named funcToRunnable just "runnable", you could then
> >> write
>
> >> playRunnable(runnable { print("hello 1"); print("hello 2") })
>
> >> No implicits required, and very little syntactic overhead.
>
> >> --
> >> Daniel C. Sobral
>
> >> I travel to the future all the time.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Sat, Jul 23, 2011 at 07:46, Yoav Abrahami wrote:
> Daniel,
> What I fail to understand is why I cannot create a function / method
> that does not get any parameters.

Functions and methods are different things. Do not confuse them.
Functions must ALWAYS get at list a 0-arity parameter list, because
that's how they "apply" syntactic sugar gets invoked.

> The case with RunnableString clearly works as scala considers the
> block
> { s: String =>
> println("hello 1 " + s)
> println("hello 2 " + s)
> }

> as a function, while it does not consider the block
> {
> println("hello 1")
> println("hello 2")
> }
> as a function

Because it has no parameter list. This would be a function:

{
() =>
println("hello 1")
println("hello 2")
}

>
> is there a syntactic way to express in scala something that does not
> get input parameters but such that can be evaluated later?
>
> Thanks,
>  Yoav
>
>
>
> On Jul 22, 10:20 pm, Daniel Sobral wrote:
>> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
>> > Hi Scala gurus,
>>
>> > In order to write the most elegant code I can with Runnable, I've
>> > played with implicit and explicit conversions from a code block to a
>> > Runnable. What I've found can be summarized as (see the code below)
>>
>> Code block is not an object. There's no "thunk" in Scala -- you either
>> have a function, or you don't. A code of block is simply a syntactical
>> scope whose value is that of the last statement. So you can't
>> "convert" a code block into something.
>>
>>
>>
>> > ()=>Unit implicitly converted to Runnable - does not work as expected
>> > - prints hello 1 once
>>
>> "() => Unit" is a function with one parameter list of arity 0. A
>> Function0, in other words.
>>
>> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>>
>> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
>> "Unit", but the parameter is passed by name instead of by value. In
>> practice, it means whatever is passed in place of the parameter is not
>> first evaluated and then have its value passed but, instead, is passed
>> "as is", and evaluated it time it is used.
>>
>> Anyway, "=> Unit" is different than "() => Unit".
>>
>> >    println("converting...")
>> >    def run = {
>> >      x
>> >    }
>> >  }
>>
>> >  def playRunnableImplicit() {
>> >    println("playRunnableImplicit")
>> >    playRunnable({
>> >      println("hello 1")
>> >      println("hello 2")
>> >    })
>>
>> So, the parameter is { println("hello 1"); println("hello 2") }, which
>> does not conform to Runnable. However, there's a conversion from Unit
>> to Runnable, and the type of that parameter is Unit. The value of a
>> block is the value of it's last statement, but since Unit is being
>> passed by name, println("hello 2") is passed instead of just ()
>> (return value of println, not to be confused with empty parameter
>> list).
>>
>> >  }
>>
>> At any rate, even if what you want were doable, it wouldn't be a good
>> idea. That's a gratuitous implicit conversion, saving a single token.
>> If, instead, you named funcToRunnable just "runnable", you could then
>> write
>>
>> playRunnable(runnable { print("hello 1"); print("hello 2") })
>>
>> No implicits required, and very little syntactic overhead.
>>
>> --
>> Daniel C. Sobral
>>
>> I travel to the future all the time.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Sat, Jul 23, 2011 at 12:36, Daniel Sobral wrote:
> On Sat, Jul 23, 2011 at 07:46, Yoav Abrahami wrote:
>> Daniel,
>> What I fail to understand is why I cannot create a function / method
>> that does not get any parameters.
>
> Functions and methods are different things. Do not confuse them.
> Functions must ALWAYS get at list a 0-arity parameter list, because

I meant "at _least_ a 0-arity parameter least" here.

> that's how they "apply" syntactic sugar gets invoked.
>
>> The case with RunnableString clearly works as scala considers the
>> block
>> { s: String =>
>> println("hello 1 " + s)
>> println("hello 2 " + s)
>> }
>
>> as a function, while it does not consider the block
>> {
>> println("hello 1")
>> println("hello 2")
>> }
>> as a function
>
> Because it has no parameter list. This would be a function:
>
> {
> () =>
> println("hello 1")
> println("hello 2")
> }
>
>>
>> is there a syntactic way to express in scala something that does not
>> get input parameters but such that can be evaluated later?
>>
>> Thanks,
>>  Yoav
>>
>>
>>
>> On Jul 22, 10:20 pm, Daniel Sobral wrote:
>>> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
>>> > Hi Scala gurus,
>>>
>>> > In order to write the most elegant code I can with Runnable, I've
>>> > played with implicit and explicit conversions from a code block to a
>>> > Runnable. What I've found can be summarized as (see the code below)
>>>
>>> Code block is not an object. There's no "thunk" in Scala -- you either
>>> have a function, or you don't. A code of block is simply a syntactical
>>> scope whose value is that of the last statement. So you can't
>>> "convert" a code block into something.
>>>
>>>
>>>
>>> > ()=>Unit implicitly converted to Runnable - does not work as expected
>>> > - prints hello 1 once
>>>
>>> "() => Unit" is a function with one parameter list of arity 0. A
>>> Function0, in other words.
>>>
>>> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>>>
>>> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
>>> "Unit", but the parameter is passed by name instead of by value. In
>>> practice, it means whatever is passed in place of the parameter is not
>>> first evaluated and then have its value passed but, instead, is passed
>>> "as is", and evaluated it time it is used.
>>>
>>> Anyway, "=> Unit" is different than "() => Unit".
>>>
>>> >    println("converting...")
>>> >    def run = {
>>> >      x
>>> >    }
>>> >  }
>>>
>>> >  def playRunnableImplicit() {
>>> >    println("playRunnableImplicit")
>>> >    playRunnable({
>>> >      println("hello 1")
>>> >      println("hello 2")
>>> >    })
>>>
>>> So, the parameter is { println("hello 1"); println("hello 2") }, which
>>> does not conform to Runnable. However, there's a conversion from Unit
>>> to Runnable, and the type of that parameter is Unit. The value of a
>>> block is the value of it's last statement, but since Unit is being
>>> passed by name, println("hello 2") is passed instead of just ()
>>> (return value of println, not to be confused with empty parameter
>>> list).
>>>
>>> >  }
>>>
>>> At any rate, even if what you want were doable, it wouldn't be a good
>>> idea. That's a gratuitous implicit conversion, saving a single token.
>>> If, instead, you named funcToRunnable just "runnable", you could then
>>> write
>>>
>>> playRunnable(runnable { print("hello 1"); print("hello 2") })
>>>
>>> No implicits required, and very little syntactic overhead.
>>>
>>> --
>>> Daniel C. Sobral
>>>
>>> I travel to the future all the time.
>
>
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.
>

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Sat, Jul 23, 2011 at 12:06, Yoav Abrahami wrote:
> hi Viktor and Daniel,
> Thanks for your answer.
> Viktor, the block2fun0 creates a () => T func. I am wondering about
> creating a () => Unit, which is a bit different.
>
> Let me try to clarify my question -
> Consider the following code block
>   {println("hello 1");  println("hello 2") }
>
> now consider using the following to convert it to a runnable
>   implicit def funcToRunnable(x: => Unit): Runnable = new Runnable
> { def run = { x } }
>
> I fail to understand why Scala considers g(funcToRunnable(block)) as
> one thing and g(block) (with implicit conversion) as something
> else...
> aren't the rules for implicit conversion are that it should do the
> same thing as if we were using explicit conversion?
>
> It seems that the Scala compiler does the following
> in the case of explicit conversion - considers all the code block as a
> () => Unit and passes all the block to the funcToRunnable method.
> in the case of implicit conversion - executes the code block, taking
> only the last statement and passes it to the funcToRunnable method.
> strange, it's it?

You will *not* understand as long as you persist in thinking of "code
block". While there's something in Scala code block, it is not what
you think it is. So, first, make it clear to yourself: THERE IS NO
SUCH THING AS A CODE BLOCK. Convince yourself of that. If you start
reading the code and think "code block", stop and say that again:
there is no such thing as a code block. Once you take that completely
out of your mind, you can go back to the code:

{ s: String =>
println("hello 1 " + s)
println("hello 2 " + s)
}

This is a function literal. Function literals are either simple
expressions or delimited by () or {}, and they either have "_" in them
as placeholder parameters, or they start with "parameters =>", where
"parameters" may be a single identifier, with or without type, or a
list of identifiers inside parenthesis. Again, this is a function --
learn to recognize what marks a function.

{
println("hello 1")
println("hello 2")
}

This is nothing. It is just a couple of statements inside a scope delimiter.

After you have that fully understood, then you can start thinking of
"code block" as a delimited list of declarations and statements with a
value.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

2011/7/23 √iktor Ҡlang :
> def block2fun0[T](block: => T): () => T = () => block

This is pretty much what he had, but he is trying to make it apply
implicitly, which causes problem as I described. Specifically:

scala> implicit def block2fun0[T](block: => T): () => T = () => block
block2fun0: [T](block: => T)() => T

scala> val f: () => Unit = {
| println("hello 1")
| println("hello 2")
| }
hello 1
f: () => Unit =

scala> f()
hello 2

>
> On Jul 23, 2011 12:46 PM, "Yoav Abrahami" wrote:
>> Daniel,
>> What I fail to understand is why I cannot create a function / method
>> that does not get any parameters.
>> The case with RunnableString clearly works as scala considers the
>> block
>> { s: String =>
>> println("hello 1 " + s)
>> println("hello 2 " + s)
>> }
>> as a function, while it does not consider the block
>> {
>> println("hello 1")
>> println("hello 2")
>> }
>> as a function
>>
>> is there a syntactic way to express in scala something that does not
>> get input parameters but such that can be evaluated later?
>>
>> Thanks,
>> Yoav
>>
>>
>>
>> On Jul 22, 10:20 pm, Daniel Sobral wrote:
>>> On Fri, Jul 22, 2011 at 13:23, Yoav Abrahami wrote:
>>> > Hi Scala gurus,
>>>
>>> > In order to write the most elegant code I can with Runnable, I've
>>> > played with implicit and explicit conversions from a code block to a
>>> > Runnable. What I've found can be summarized as (see the code below)
>>>
>>> Code block is not an object. There's no "thunk" in Scala -- you either
>>> have a function, or you don't. A code of block is simply a syntactical
>>> scope whose value is that of the last statement. So you can't
>>> "convert" a code block into something.
>>>
>>>
>>>
>>> > ()=>Unit implicitly converted to Runnable - does not work as expected
>>> > - prints hello 1 once
>>>
>>> "() => Unit" is a function with one parameter list of arity 0. A
>>> Function0, in other words.
>>>
>>> >  implicit def funcToRunnable(x: => Unit): Runnable = new Runnable {
>>>
>>> A "=> Unit" is not a function at all. "=> Unit" is the same thing as
>>> "Unit", but the parameter is passed by name instead of by value. In
>>> practice, it means whatever is passed in place of the parameter is not
>>> first evaluated and then have its value passed but, instead, is passed
>>> "as is", and evaluated it time it is used.
>>>
>>> Anyway, "=> Unit" is different than "() => Unit".
>>>
>>> >    println("converting...")
>>> >    def run = {
>>> >      x
>>> >    }
>>> >  }
>>>
>>> >  def playRunnableImplicit() {
>>> >    println("playRunnableImplicit")
>>> >    playRunnable({
>>> >      println("hello 1")
>>> >      println("hello 2")
>>> >    })
>>>
>>> So, the parameter is { println("hello 1"); println("hello 2") }, which
>>> does not conform to Runnable. However, there's a conversion from Unit
>>> to Runnable, and the type of that parameter is Unit. The value of a
>>> block is the value of it's last statement, but since Unit is being
>>> passed by name, println("hello 2") is passed instead of just ()
>>> (return value of println, not to be confused with empty parameter
>>> list).
>>>
>>> >  }
>>>
>>> At any rate, even if what you want were doable, it wouldn't be a good
>>> idea. That's a gratuitous implicit conversion, saving a single token.
>>> If, instead, you named funcToRunnable just "runnable", you could then
>>> write
>>>
>>> playRunnable(runnable { print("hello 1"); print("hello 2") })
>>>
>>> No implicits required, and very little syntactic overhead.
>>>
>>> --
>>> Daniel C. Sobral
>>>
>>> I travel to the future all the time.
>

Viktor Klang
Joined: 2008-12-17,
User offline. Last seen 1 year 27 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with
So the conclusion here is:

you can have an implicit conversion between () => T and Runnable, but you'll need to use it like this:

val r: Runnable = () => println("pigdog")

which makes it a bit easier to just have a method called "runnable" that takes a by-name parameter of type T and returns a Runnable that invokes that by-name parameter:

val r = runnable { println("pigdog" }

Now, if there really is not a convincing reason to work with runnables in user code at all, I'd recommend working with () => T instead, it's way more useful.

val r  = () => println("pigdog")

On Sat, Jul 23, 2011 at 5:46 PM, Daniel Sobral <dcsobral [at] gmail [dot] com> wrote:
On Sat, Jul 23, 2011 at 12:06, Yoav Abrahami <yoavaa [at] gmail [dot] com> wrote:
> hi Viktor and Daniel,
> Thanks for your answer.
> Viktor, the block2fun0 creates a () => T func. I am wondering about
> creating a () => Unit, which is a bit different.
>
> Let me try to clarify my question -
> Consider the following code block
>   {println("hello 1");  println("hello 2") }
>
> now consider using the following to convert it to a runnable
>   implicit def funcToRunnable(x: => Unit): Runnable = new Runnable
> { def run = { x } }
>
> I fail to understand why Scala considers g(funcToRunnable(block)) as
> one thing and g(block) (with implicit conversion) as something
> else...
> aren't the rules for implicit conversion are that it should do the
> same thing as if we were using explicit conversion?
>
> It seems that the Scala compiler does the following
> in the case of explicit conversion - considers all the code block as a
> () => Unit and passes all the block to the funcToRunnable method.
> in the case of implicit conversion - executes the code block, taking
> only the last statement and passes it to the funcToRunnable method.
> strange, it's it?

You will *not* understand as long as you persist in thinking of "code
block". While there's something in Scala code block, it is not what
you think it is. So, first, make it clear to yourself: THERE IS NO
SUCH THING AS A CODE BLOCK. Convince yourself of that. If you start
reading the code and think "code block", stop and say that again:
there is no such thing as a code block. Once you take that completely
out of your mind, you can go back to the code:

{ s: String =>
println("hello 1 " + s)
println("hello 2 " + s)
}

This is a function literal. Function literals are either simple
expressions or delimited by () or {}, and they either have "_" in them
as placeholder parameters, or they start with "parameters =>", where
"parameters" may be a single identifier, with or without type, or a
list of identifiers inside parenthesis. Again, this is a function --
learn to recognize what marks a function.

{
println("hello 1")
println("hello 2")
}

This is nothing. It is just a couple of statements inside a scope delimiter.

After you have that fully understood, then you can start thinking of
"code block" as a delimited list of declarations and statements with a
value.

--
Daniel C. Sobral

I travel to the future all the time.



--
Viktor Klang

Akka Tech LeadTypesafe - Enterprise-Grade Scala from the Experts

Twitter: @viktorklang
Stephen Haberman 2
Joined: 2011-07-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

{
println("hello 1")
println("hello 2")
}

This is nothing. It is just a couple of statements inside a scope delimiter.

Okay, then how to do you explain:
https://gist.github.com/1101709

AFAICT, the "couple of statements inside a scope delimiter" can indeed be a function, as the call to doFunction shows.
It's quite odd that the same syntax (doFunction { ... } vs. doSam { ... }) results in very different behavior depending on whether an implicit conversion is involved.
- Stephen

Roland Kuhn 3
Joined: 2011-07-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

On Jul 23, 2011, at 22:44 , Stephen Haberman wrote:

{
println("hello 1")
println("hello 2")
}

This is nothing. It is just a couple of statements inside a scope delimiter.

Okay, then how to do you explain:
https://gist.github.com/1101709

AFAICT, the "couple of statements inside a scope delimiter" can indeed be a function, as the call to doFunction shows.
It's quite odd that the same syntax (doFunction { ... } vs. doSam { ... }) results in very different behavior depending on whether an implicit conversion is involved.
Well, put yourself in the position of the compiler: in the first case, you know to expect a function, and the spec says that if the argument types are fully known then a special syntax for function literals is allowed (which you use). This special case is extremely useful for writing library functions which act as if they were keywords (i.e. synchronized {} and friends). In the second case, a SAM is needed, for which a block is given, hence the return value of that block is inspected if it would fit the bill, triggering implicit conversion if needed and available.
So, in essence you are thrown off by the special case for FunctionN & PartialFunction, or more appropriately, that this special case is not applied when taking into account implicit conversions. Again, put yourself in the position of the compiler: you would have to unwind potentially a lot of stuff to re-check the whole code block when passed into the conversion method.
Regards,
Roland
dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Sat, Jul 23, 2011 at 17:44, Stephen Haberman
wrote:
>> {
>> println("hello 1")
>> println("hello 2")
>> }
>>
>> This is nothing. It is just a couple of statements inside a scope
>> delimiter.
>
> Okay, then how to do you explain:
> https://gist.github.com/1101709

I have explained it in two different ways already, but I'll try again.
Remember, first, that "=> Unit" is *not* a function. It is a parameter
passed by-name -- go look on wikipedia about that.

So, the first thing to notice is that there is no function anywhere,
and "doFunction" is incorrectly named. So, since this code has no
function in it, we can move ahead and understand how it works. If you
can't let go of the fact it has no function, then go back, re-read the
spec, re-read stuff I wrote... hell, read stack overflow about it.
There's no function signature anywhere, therefore there is no
function.

NEXT, let's see how it works:

def doFunction(f: => Unit) = { println("got " + (f _)) ; f ; f }
doFunction { println("1"); println("2") }

The grossly misnamed "doFunction" method takes a by-name Unit
parameter "f". That means that everywhere "f" appears, it is replaced
with what was passed. That means it will do this:

{ println("got " + ({ println("1"); println("2") } _)) ; {
println("1"); println("2") } ; { println("1"); println("2") } }

You might now try to take this opportunity to point out that it
printed "got ", so it must be a function. Well, I've got
two words for you: eta expansion. When you wrote "f _", Scala created
a function for you. That's what it does when you write "f _". You'd
have a stronger argument if you decompiled doFunction and showed that
it expected a function, but that's implementation, and, in fact, it is
just an interface name.

So, let's proceed:

doSam(body2sam({ println("1"); println("2") }))

becomes, because of body2sam's by-name parameter,

doSam(new SAM {
override def onSam = { println("1"); println("2") }
})

Finally, this:

doSam { println("1"); println("2") }

So, doSam does not receive a parameter by name, which means "{
println("1"); println("2") }" gets evaluated before being passed. It's
value is defined to be the value of the last statement, println("2").
Since it is not a SAM, Scala checks if it conforms to SAM through an
implicit conversion (or other means), which, in fact, it does. So it
becomes:

doSam { println("1"); body2sam(println("2")) }

All of which makes perfect sense and, while might be surprising the
first time you see it, can be easily deduced from the specification.
But only if you do pay attention to the specification, and stop
thinking of "block of code" as some sort of equivalent of a function,
never mind confusing by-name parameters with functions.

>
> AFAICT, the "couple of statements inside a scope delimiter" can indeed be a
> function, as the call to doFunction shows.
> It's quite odd that the same syntax (doFunction { ... } vs. doSam { ... })
> results in very different behavior depending on whether an implicit
> conversion is involved.

There's no oddity here -- it only looks odd because of your
presumption that there's a function here.

Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Hi Daniel, Roland,
I think the example in https://gist.github.com/1101709 says it all.

doSam(body2sam({ println("1"); println("2") }))
// got foo.Foo$$anon$1@2b86c6b2
// 1 2 1 2

doSam { println("1"); println("2") }
// 1
// got foo.Foo$$anon$1@416b13c7
// 2 2

the two functions above should (for any reasonable reader) produce the
same result. Why should the use of implicit conversion produce
something different?

If, as Roland says, this case is too complicated for the compiler, it
should be excluded - should not compile.
Something like saying "implicit conversion are not supported for
delayed evaluation of Unit parameters because of potential ambiguity"

However, having the same code (from the point of view of a developer)
do two different things is really bad for a programming language - it
is one of those things that was really bad in C++ (namely multiple
inheritance which was so bad it too 25 years for developers to
overcome). A programming language should not be ambiguous, ever.

When I say ambiguous, I mean from the point of view of the developer,
not the compiler
:-)

On Jul 25, 2:09 am, Daniel Sobral wrote:
> On Sat, Jul 23, 2011 at 17:44, Stephen Haberman
>
> wrote:
> >> {
> >> println("hello 1")
> >> println("hello 2")
> >> }
>
> >> This is nothing. It is just a couple of statements inside a scope
> >> delimiter.
>
> > Okay, then how to do you explain:
> >https://gist.github.com/1101709
>
> I have explained it in two different ways already, but I'll try again.
> Remember, first, that "=> Unit" is *not* a function. It is a parameter
> passed by-name -- go look on wikipedia about that.
>
> So, the first thing to notice is that there is no function anywhere,
> and "doFunction" is incorrectly named. So, since this code has no
> function in it, we can move ahead and understand how it works. If you
> can't let go of the fact it has no function, then go back, re-read the
> spec, re-read stuff I wrote... hell, read stack overflow about it.
> There's no function signature anywhere, therefore there is no
> function.
>
> NEXT, let's see how it works:
>
> def doFunction(f: => Unit) = { println("got " + (f _)) ; f ; f }
> doFunction { println("1"); println("2") }
>
> The grossly misnamed "doFunction" method takes a by-name Unit
> parameter "f". That means that everywhere "f" appears, it is replaced
> with what was passed. That means it will do this:
>
> { println("got " + ({ println("1"); println("2") } _)) ; {
> println("1"); println("2") } ; { println("1"); println("2") } }
>
> You might now try to take this opportunity to point out that it
> printed "got ", so it must be a function. Well, I've got
> two words for you: eta expansion. When you wrote "f _", Scala created
> a function for you. That's what it does when you write "f _". You'd
> have a stronger argument if you decompiled doFunction and showed that
> it expected a function, but that's implementation, and, in fact, it is
> just an interface name.
>
> So, let's proceed:
>
> doSam(body2sam({ println("1"); println("2") }))
>
> becomes, because of body2sam's by-name parameter,
>
> doSam(new SAM {
>     override def onSam = { println("1"); println("2") }
>   })
>
> Finally, this:
>
> doSam { println("1"); println("2") }
>
> So, doSam does not receive a parameter by name, which means "{
> println("1"); println("2") }" gets evaluated before being passed. It's
> value is defined to be the value of the last statement, println("2").
> Since it is not a SAM, Scala checks if it conforms to SAM through an
> implicit conversion (or other means), which, in fact, it does. So it
> becomes:
>
> doSam { println("1"); body2sam(println("2")) }
>
> All of which makes perfect sense and, while might be surprising the
> first time you see it, can be easily deduced from the specification.
> But only if you do pay attention to the specification, and stop
> thinking of "block of code" as some sort of equivalent of a function,
> never mind confusing by-name parameters with functions.
>
>
>
> > AFAICT, the "couple of statements inside a scope delimiter" can indeed be a
> > function, as the call to doFunction shows.
> > It's quite odd that the same syntax (doFunction { ... } vs. doSam { ... })
> > results in very different behavior depending on whether an implicit
> > conversion is involved.
>
> There's no oddity here -- it only looks odd because of your
> presumption that there's a function here.
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

Johannes Rudolph 2
Joined: 2010-02-12,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 10:58 AM, Yoav Abrahami wrote:
> the two functions above should (for any reasonable reader) produce the
> same result. Why should the use of implicit conversion produce
> something different?

Actually for those cases the reader can't expect to much as long as
implicits and by-name parameters are concerned because at the
call-site those are completely transparent. To understand a program
completely the reader has to know at least the signatures of the
callees and which implicits are in scope. With his knowledge of how
implicit conversions work he can then infer what is happening.

But those are just artifacts of a powerful, generic language where
libraries can (re-)define semantics to a certain degree.

I agree that implicits taking a by-name parameter are a potential
pitfall and seldom useful and if something can be done against this it
would probably be putting a warning at the definition site of an
implicit conversion with a by-name parameter.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 05:58, Yoav Abrahami wrote:
> Hi Daniel, Roland,
> I think the example in https://gist.github.com/1101709 says it all.
>
>    doSam(body2sam({ println("1"); println("2") }))
>    // got foo.Foo$$anon$1@2b86c6b2
>    // 1 2 1 2
>
>    doSam { println("1"); println("2") }
>    // 1
>    // got foo.Foo$$anon$1@416b13c7
>    // 2 2
>
> the two functions above should (for any reasonable reader) produce the
> same result. Why should the use of implicit conversion produce
> something different?

Because { println("1"); println("2") } is not a function!

Let me try this in a different way...

scala> { println("1"); println("2") } == println("2")
1
2
2
res0: Boolean = true

Do you consider this result (true) to be correct or incorrect?

Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Hi Daniel,

My point is not that this code fragment is a function, block, or not.
My point is that in a programming language, a code fragment (by
whatever name) should be understood by the compiler and developers as
the same thing, always.
In this case, it is not.

by your logic,
doSam(body2sam({ println("1"); println("2") }))
// got foo.Foo$$anon$1@2b86c6b2
// 1 2 1 2
is wrong. it should print

// 1
// got foo.Foo$$anon$1@416b13c7
// 2 2

because, as you say, the code {println("1"); println("2")} is not a
function.

On Jul 25, 2:55 pm, Daniel Sobral wrote:
> On Mon, Jul 25, 2011 at 05:58, Yoav Abrahami wrote:
> > Hi Daniel, Roland,
> > I think the example inhttps://gist.github.com/1101709says it all.
>
> >    doSam(body2sam({ println("1"); println("2") }))
> >    // got foo.Foo$$anon$1@2b86c6b2
> >    // 1 2 1 2
>
> >    doSam { println("1"); println("2") }
> >    // 1
> >    // got foo.Foo$$anon$1@416b13c7
> >    // 2 2
>
> > the two functions above should (for any reasonable reader) produce the
> > same result. Why should the use of implicit conversion produce
> > something different?
>
> Because { println("1"); println("2") } is not a function!
>
> Let me try this in a different way...
>
> scala> { println("1"); println("2") } == println("2")
> 1
> 2
> 2
> res0: Boolean = true
>
> Do you consider this result (true) to be correct or incorrect?
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

roland.kuhn
Joined: 2011-02-21,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: Strange behavior when combing implicit conversion with

Am 7/25/2011 3:28 PM, schrieb Yoav Abrahami:
> Hi Daniel,
>
> My point is not that this code fragment is a function, block, or not.
> My point is that in a programming language, a code fragment (by
> whatever name) should be understood by the compiler and developers as
> the same thing, always.
> In this case, it is not.
>
> by your logic,
> doSam(body2sam({ println("1"); println("2") }))
> // got foo.Foo$$anon$1@2b86c6b2
> // 1 2 1 2
> is wrong. it should print
>
> // 1
> // got foo.Foo$$anon$1@416b13c7
> // 2 2
>
> because, as you say, the code {println("1"); println("2")} is not a
> function.
>
Well, in this case it is! (see ch. 6.23 of the Scala Language Specification)

So, finally we arrive at the crucial point: as I tried to explain
earlier, this special exception is in place so that libraries can
provide methods which "feel like" control constructs. It is a conscious
design decision which is immensely important if you want to write nice
DSLs, one of Scala's central strengths.

Scala is a hammer which fits many a nail. But if your special nail
absolutely requires that { ... } never is a function, then by all means
choose a different tool.

Regards,

Roland

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 25/07/11 23:28, Yoav Abrahami wrote:
> My point is that in a programming language, a code fragment (by
> whatever name) should be understood by the compiler and developers
> as the same thing, always.

Scala is not a lazy, pure functional programming language. Just sayin'

Joshua.Suereth
Joined: 2008-09-02,
User offline. Last seen 32 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with
True.   That's not a bad thing if you're not looking for lazy, pure FP, but if you want lazy pure FP, it's going to be a bit more verbose to get it in Scala than a  language that fits that niche.
Also, the => A vs. () => A debate is a bit confusing at first to all of us in the language.  Daniel has a great explanation, but I'm not surprised it threw you for a loop at first.  It does for all of us.

On Mon, Jul 25, 2011 at 10:25 AM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 25/07/11 23:28, Yoav Abrahami wrote:
> My point is that in a programming language, a code fragment (by
> whatever name) should be understood by the compiler and developers
> as the same thing, always.

Scala is not a lazy, pure functional programming language. Just sayin'

- --
Tony Morris
http://tmorris.net/

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAk4tfOEACgkQmnpgrYe6r6052wCfe8aJOzvN56pBltyQTid3UZsU
Yp4An24ZfWsNNBvOFHiqXa86B/aVbBpd
=fnZG
-----END PGP SIGNATURE-----


Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Roland, I think you misunderstand me.
I do not object for scala to handle a code fragment as a special case
as it does.

I do object for it to allow writing implicit conversions on it that
does something completely different.

I'd like Scala to be consistent in this regard, or disallow the
implicit conversion. If we have a special case, as you say here,
disallowing the implicit conversion is the right thing to do - as a
complementary special case.

Cheers,
Yoav

On Jul 25, 5:22 pm, Roland Kuhn wrote:
> Am 7/25/2011 3:28 PM, schrieb Yoav Abrahami:
>
>
>
>
>
>
>
> > Hi Daniel,
>
> > My point is not that this code fragment is a function, block, or not.
> > My point is that in a programming language, a code fragment (by
> > whatever name) should be understood by the compiler and developers as
> > the same thing, always.
> > In this case, it is not.
>
> > by your logic,
> > doSam(body2sam({ println("1"); println("2") }))
> > // got foo.Foo$$anon$1@2b86c6b2
> > // 1 2 1 2
> > is wrong. it should print
>
> > // 1
> > // got foo.Foo$$anon$1@416b13c7
> > // 2 2
>
> > because, as you say, the code {println("1"); println("2")} is not a
> > function.
>
> Well, in this case it is! (see ch. 6.23 of the Scala Language Specification)
>
> So, finally we arrive at the crucial point: as I tried to explain
> earlier, this special exception is in place so that libraries can
> provide methods which "feel like" control constructs. It is a conscious
> design decision which is immensely important if you want to write nice
> DSLs, one of Scala's central strengths.
>
> Scala is a hammer which fits many a nail. But if your special nail
> absolutely requires that { ... } never is a function, then by all means
> choose a different tool.
>
> Regards,
>
> Roland

Stephen Haberman 2
Joined: 2011-07-23,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

> I have explained it in two different ways already, but I'll try again.

Thanks for taking the time to do so.

> Remember, first, that "=> Unit" is *not* a function.

Hm...okay, I guess that makes sense.

I still find myself tempted to think of them that way, especially for
DSLs and custom control structures where they're used (abused?) to get
syntactically-cheap functions, e.g.:

def main(args: Array[String]): Unit = {
bar { println("1"); println("2") }
bar { _ => println("1"); println("2") }
bar { s => println(s); println(s) }
}
def bar(f: String => Unit): Unit = f("hi")
def bar(f: => Unit): Unit = bar(_ => f)

Where I want the first bar call to be considered, effectively, as a
function that ignores its parameter. Here it works as expected, and is
what I was attempting to emulate against an API that takes a SAM.
Pimping the API seems to be the better way to go.

- Stephen

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 10:28, Yoav Abrahami wrote:
> Hi Daniel,
>
> My point is not that this code fragment is a function, block, or not.
> My point is that in a programming language, a code fragment (by
> whatever name) should be understood by the compiler and developers as
> the same thing, always.
> In this case, it is not.
>
> by your logic,
> doSam(body2sam({ println("1"); println("2") }))
> // got foo.Foo$$anon$1@2b86c6b2
> // 1 2 1 2
> is wrong. it should print
>
> // 1
> // got foo.Foo$$anon$1@416b13c7
> // 2 2
>
> because, as you say, the code {println("1"); println("2")} is not a
> function.

But body2sam receives a parameter by name -- you can't use by name
parameters and ignore how they work. You are being explicit in that
println("1") is part of it. Implicitly, it becomes:

{ println("1"); body2sam(println("2")) }

This is all according to the rules. The problem is not with the rules,
the problem is with your expectation that body2sam would apply over
the whole block, instead of its value. And that expectation only
exists because you insist of thinking of the block as a kind of "block
of code" object.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 12:23, Stephen Haberman
wrote:
>
> Where I want the first bar call to be considered, effectively, as a
> function that ignores its parameter. Here it works as expected, and is
> what I was attempting to emulate against an API that takes a SAM.
> Pimping the API seems to be the better way to go.

Don't go overboard with implicit conversions. It costs very little to
put a "bar" in front of the block, so do that.

roland.kuhn
Joined: 2011-02-21,
User offline. Last seen 35 weeks 3 days ago.
Re: Re: Strange behavior when combing implicit conversion with

[small erratum: I mixed up the references, it is in fact section 4.6.1
of the SLS]

Yes, there must have been some misunderstanding on my part along the
way: allowing by-name parameters on implicit conversions is
questionable. So, as long as by-name parameters in general remain
supported, we are in agreement ;-)

BTW: can someone think of a non-confusing use-case for conversions
taking by-name arguments?

Regards,

Roland

Am 7/25/2011 5:20 PM, schrieb Yoav Abrahami:
> Roland, I think you misunderstand me.
> I do not object for scala to handle a code fragment as a special case
> as it does.
>
> I do object for it to allow writing implicit conversions on it that
> does something completely different.
>
> I'd like Scala to be consistent in this regard, or disallow the
> implicit conversion. If we have a special case, as you say here,
> disallowing the implicit conversion is the right thing to do - as a
> complementary special case.
>
> Cheers,
> Yoav
>
> On Jul 25, 5:22 pm, Roland Kuhn wrote:
>> Am 7/25/2011 3:28 PM, schrieb Yoav Abrahami:
>>
>>
>>
>>
>>
>>
>>
>>> Hi Daniel,
>>> My point is not that this code fragment is a function, block, or not.
>>> My point is that in a programming language, a code fragment (by
>>> whatever name) should be understood by the compiler and developers as
>>> the same thing, always.
>>> In this case, it is not.
>>> by your logic,
>>> doSam(body2sam({ println("1"); println("2") }))
>>> // got foo.Foo$$anon$1@2b86c6b2
>>> // 1 2 1 2
>>> is wrong. it should print
>>> // 1
>>> // got foo.Foo$$anon$1@416b13c7
>>> // 2 2
>>> because, as you say, the code {println("1"); println("2")} is not a
>>> function.
>> Well, in this case it is! (see ch. 6.23 of the Scala Language Specification)
>>
>> So, finally we arrive at the crucial point: as I tried to explain
>> earlier, this special exception is in place so that libraries can
>> provide methods which "feel like" control constructs. It is a conscious
>> design decision which is immensely important if you want to write nice
>> DSLs, one of Scala's central strengths.
>>
>> Scala is a hammer which fits many a nail. But if your special nail
>> absolutely requires that { ... } never is a function, then by all means
>> choose a different tool.
>>
>> Regards,
>>
>> Roland

Mark Harrah 2
Joined: 2011-02-05,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, 25 Jul 2011 12:01:11 +0200
Johannes Rudolph wrote:
> I agree that implicits taking a by-name parameter are a potential
> pitfall and seldom useful and if something can be done against this it
> would probably be putting a warning at the definition site of an
> implicit conversion with a by-name parameter.

https://issues.scala-lang.org/browse/SI-3237

-Mark

dlandis
Joined: 2009-09-30,
User offline. Last seen 3 years 3 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 10:29 AM, Josh Suereth wrote:
> Also, the => A vs. () => A debate is a bit confusing at first to all of us
> in the language.  Daniel has a great explanation, but I'm not surprised it
> threw you for a loop at first.  It does for all of us.
>

Watch out, you almost said it was "complex". I new here, but even I
know better than that ;)

Yoav Abrahami
Joined: 2011-07-22,
User offline. Last seen 42 years 45 weeks ago.
Re: Strange behavior when combing implicit conversion with () =>

Daniel,

I think your still not getting my point.

I agree - there is no code block.
I agree - there is no function.

However, I do not agree that
body2sam({ println("1"); println("2") } )

is equivalent to
{ println("1"); body2sam(println("2")) }

because they print something completely different!

please run the code
doSam(body2sam({ println("1"); println("2") }))
// got foo.Foo$$anon$1@2b86c6b2
// 1 2 1 2

then run the code
doSam({ println("1"); body2sam(println("2")) }))
// got foo.Foo$$anon$1@2b86c6b2
// 1 2 2

those are two different things.

My observation is that if we apply body2sam as an implicit conversion
on {println("1"); println("2")}, the compiler sees code written as the
second example, not the first.
I understand that the compiler has a hard life in this case, because
when it looks were the body2sam conversion fits the code, it finds two
places.
adding body2sam to the code {println("1"); println("2")} can be done
as
body2sam({println("1"); println("2")})
or
{println("1"); body2sam(println("2"))}
And those two ways are different!
In such a case, we have ambiguity and the compiler must issue a
compilation error. The fact that it does not means there is something
broken with the Scala compiler.

Thanks for helping me clarify the issue.
Cheers,
Yoav

by your logic,
doSam(body2sam({ println("1"); println("2") }))
// got foo.Foo$$anon$1@2b86c6b2
// 1 2 1 2
is wrong. it should print
// 1
// got foo.Foo$$anon$1@416b13c7
// 2 2

On Jul 25, 6:27 pm, Daniel Sobral wrote:
> On Mon, Jul 25, 2011 at 10:28, Yoav Abrahami wrote:
> > Hi Daniel,
>
> > My point is not that this code fragment is a function, block, or not.
> > My point is that in a programming language, a code fragment (by
> > whatever name) should be understood by the compiler and developers as
> > the same thing, always.
> > In this case, it is not.
>
> > by your logic,
> > doSam(body2sam({ println("1"); println("2") }))
> > // got foo.Foo$$anon$1@2b86c6b2
> > // 1 2 1 2
> > is wrong. it should print
>
> > // 1
> > // got foo.Foo$$anon$1@416b13c7
> > // 2 2
>
> > because, as you say, the code {println("1"); println("2")} is not a
> > function.
>
> But body2sam receives a parameter by name -- you can't use by name
> parameters and ignore how they work. You are being explicit in that
> println("1") is part of it. Implicitly, it becomes:
>
> { println("1"); body2sam(println("2")) }
>
> This is all according to the rules. The problem is not with the rules,
> the problem is with your expectation that body2sam would apply over
> the whole block, instead of its value. And that expectation only
> exists because you insist of thinking of the block as a kind of "block
> of code" object.
>
> --
> Daniel C. Sobral
>
> I travel to the future all the time.

dcsobral
Joined: 2009-04-23,
User offline. Last seen 38 weeks 5 days ago.
Re: Re: Strange behavior when combing implicit conversion with

On Mon, Jul 25, 2011 at 17:35, Yoav Abrahami wrote:
> Daniel,
>
> I think your still not getting my point.
>
> I agree - there is no code block.
> I agree - there is no function.
>
> However, I do not agree that
> body2sam({ println("1"); println("2") } )
>
> is equivalent to
> { println("1"); body2sam(println("2")) }
>
> because they print something completely different!

I'm not saying they are the same, I'm saying they are different. When
you use implicits, it is the latter version that is used. When you do
it explicitly, you can do it any way you want, and the example
happened to use the former.

> My observation is that if we apply body2sam as an implicit conversion
> on {println("1"); println("2")}, the compiler sees code written as the
> second example, not the first.
> I understand that the compiler has a hard life in this case, because
> when it looks were the body2sam conversion fits the code, it finds two
> places.
> adding body2sam to the code {println("1"); println("2")} can be done
> as
> body2sam({println("1"); println("2")})
> or
> {println("1"); body2sam(println("2"))}
> And those two ways are different!
> In such a case, we have ambiguity and the compiler must issue a
> compilation error. The fact that it does not means there is something
> broken with the Scala compiler.

There are many ways things can be written in different manners with
different meanings and still be valid, why would this cause a warning?
There's no ambiguity here -- there's need of a Unit, and the last
statement of the block provides one. Since the parameter is by name,
it passes that statement by name.

The only "ambiguity" here is "I'd like it to do something else." Well,
it doesn't, but it is not ambiguous.

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Re: Strange behavior when combing implicit conversion with

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

IO is associative but does not commute.

Yoav, I suggest trying your examples in a language where the
type-checker makes some of your observations more apparent. You are
right of course, but it can be made more obvious with a type checker
that delineates between these differents type of value.

On 26/07/11 06:35, Yoav Abrahami wrote:
> Daniel,
>
> I think your still not getting my point.
>
> I agree - there is no code block. I agree - there is no function.
>
> However, I do not agree that body2sam({ println("1"); println("2")
> } )
>
> is equivalent to { println("1"); body2sam(println("2")) }
>
> because they print something completely different!
>
> please run the code doSam(body2sam({ println("1"); println("2")
> })) // got foo.Foo$$anon$1@2b86c6b2 // 1 2 1 2
>
> then run the code doSam({ println("1"); body2sam(println("2")) }))
> // got foo.Foo$$anon$1@2b86c6b2 // 1 2 2
>
> those are two different things.
>
> My observation is that if we apply body2sam as an implicit
> conversion on {println("1"); println("2")}, the compiler sees code
> written as the second example, not the first. I understand that the
> compiler has a hard life in this case, because when it looks were
> the body2sam conversion fits the code, it finds two places. adding
> body2sam to the code {println("1"); println("2")} can be done as
> body2sam({println("1"); println("2")}) or {println("1");
> body2sam(println("2"))} And those two ways are different! In such a
> case, we have ambiguity and the compiler must issue a compilation
> error. The fact that it does not means there is something broken
> with the Scala compiler.
>
> Thanks for helping me clarify the issue. Cheers, Yoav
>
>
>
> by your logic, doSam(body2sam({ println("1"); println("2") })) //
> got foo.Foo$$anon$1@2b86c6b2 // 1 2 1 2 is wrong. it should print
> // 1 // got foo.Foo$$anon$1@416b13c7 // 2 2
>
> On Jul 25, 6:27 pm, Daniel Sobral wrote:
>> On Mon, Jul 25, 2011 at 10:28, Yoav Abrahami
>> wrote:
>>> Hi Daniel,
>>
>>> My point is not that this code fragment is a function, block,
>>> or not. My point is that in a programming language, a code
>>> fragment (by whatever name) should be understood by the
>>> compiler and developers as the same thing, always. In this
>>> case, it is not.
>>
>>> by your logic, doSam(body2sam({ println("1"); println("2") }))
>>> // got foo.Foo$$anon$1@2b86c6b2 // 1 2 1 2 is wrong. it should
>>> print
>>
>>> // 1 // got foo.Foo$$anon$1@416b13c7 // 2 2
>>
>>> because, as you say, the code {println("1"); println("2")} is
>>> not a function.
>>
>> But body2sam receives a parameter by name -- you can't use by
>> name parameters and ignore how they work. You are being explicit
>> in that println("1") is part of it. Implicitly, it becomes:
>>
>> { println("1"); body2sam(println("2")) }
>>
>> This is all according to the rules. The problem is not with the
>> rules, the problem is with your expectation that body2sam would
>> apply over the whole block, instead of its value. And that
>> expectation only exists because you insist of thinking of the
>> block as a kind of "block of code" object.
>>

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