By-name parameter oddities

View: New views
4 Messages — Rating Filter:   Alert me  

By-name parameter oddities

by Blair Zajac :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

1) I'm guessing the following should be a compile error, given that you cannot
return a by-name type:

abstract class Foo {
   def identity[T](x : => T) : ( => T)
}

2) Its interesting that you can't write an identity function for a by-name
parameter, it gets evaluated immediately:

scala> def identity[T](x : T) = x
identity: [T](T)T

scala> identity { println("10") }
10

The only way I've found to not evaluate a by-name parameter seems to be to put
it in a Function0:

scala> def f(block : => Unit) = { () => { println("calling block"); block } }
f: (=> Unit)() => Unit

# Note that this println is not called here...
scala> val g = f { println("doing work") }
g: () => Unit = <function>

# ...but it is called here.
scala> g()
calling block
doing work

Blair

--
Blair Zajac, Ph.D.
CTO, OrcaWare Technologies
<blair@...>
Subversion training, consulting and support
http://www.orcaware.com/svn/

Re: By-name parameter oddities

by Martin Odersky :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On Jan 9, 2008 1:19 AM, Blair Zajac <blair@...> wrote:
> 1) I'm guessing the following should be a compile error, given that you cannot
> return a by-name type:
>
> abstract class Foo {
>    def identity[T](x : => T) : ( => T)
> }
>
Right. That should not be permitted.

 -- Martin

Re: By-name parameter oddities

by Alex Boisvert-3 :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

On 1/8/08, Blair Zajac <blair@...> wrote:
2) Its interesting that you can't write an identity function for a by-name
parameter, it gets evaluated immediately:

scala> def identity[T](x : T) = x
identity: [T](T)T

scala> identity { println("10") }
10

This code relies on type-inference to do what you expect, but there's a simpler type being inferred (Unit), and not () => Unit.

While a little more explicit syntax it works,

scala> def identity[T](x : T) = x
identity: [T](T)T

scala> identity {() => println(10)}
res0: () => Unit = <function>

alex


Re: By-name parameter oddities

by Blair Zajac :: Rate this Message:

Reply (Restricted by the Administrator) | Reply to Author | View Threaded | Show Only this Message

martin odersky wrote:

> On Jan 9, 2008 1:19 AM, Blair Zajac <blair@...> wrote:
>> 1) I'm guessing the following should be a compile error, given that you cannot
>> return a by-name type:
>>
>> abstract class Foo {
>>    def identity[T](x : => T) : ( => T)
>> }
>>
> Right. That should not be permitted.
>
>  -- Martin
>

I've opened a ticket:

http://lampsvn.epfl.ch/trac/scala/ticket/351

Blair