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

Question about definitions

6 replies
Silvio Bierman
Joined: 2009-02-16,
User offline. Last seen 1 year 16 weeks ago.

Hello all,

I am a long time Java programmer with a C/C++ history starting from ~1985
and I am slowly moving stuff to Scala. I have the following question for
which I could not find a clear anwer:

Say I have this:

object Test extends Application
{
def fun1(x : Int) = x + 1
def fun2 = (x : Int) => x + 2
val fun3 = (x : Int) => x + 3

println(fun1(1) + fun2(2) + fun3(3))
}

This prints 12 as I would have expected. But what are the subtle differences
between fun1, fun2 and fun3?

Silvio

gnufied
Joined: 2008-08-19,
User offline. Last seen 3 years 18 weeks ago.
Re: Question about definitions

On Thu, Mar 12, 2009 at 2:27 PM, Silvio Bierman
wrote:
>
> Hello all,
>
> I am a long time Java programmer with a C/C++ history starting from ~1985
> and I am slowly moving stuff to Scala. I have the following question for
> which I could not find a clear anwer:
>
> Say I have this:
>
> object Test extends Application
> {
>  def fun1(x : Int) = x + 1
>  def fun2 = (x : Int) => x + 2
>  val fun3 = (x : Int) => x + 3
>
>  println(fun1(1) + fun2(2) + fun3(3))
> }
>
> This prints 12 as I would have expected. But what are the subtle differences
> between fun1, fun2 and fun3?

fun1 is obviously a method that takes an integer as argument and
returns the integer plus one as return value. Return type is inferred.

fun2 is method that returns a anonymous function. (The anonymous
function takes an integer as argument and returns integer plus 2).
Return type of both fun2 and anonymous function is inferred.

fun3 is a variable that contains a reference to a defined anonymous function.

In case of fun2 and fun3, invoking fun2(2) is akin to calling fun2.apply(2).

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: Question about definitions
That's a very good question.

I think the most important thing to know is that defs compile to Java methods and vals/vars compile to Java fields. (Ok, I'm kinda lying about vals/vars, but you can think of them that way.)

So fun1 is a (Scala and Java) method that takes an Int and returns an Int. In Java, defining and calling fun1 might look like:

  Int fun1(Int x) { return x + 1 }

  fun1(1)

Now, fun2 is also a (Scala and Java) method. But it takes no arguments. So what does it return? And why can you call it with fun2(2), as if it took an argument? It returns a Function, which is not the same as a method. More specifically, it returns a Function1. scala.Function1 is a trait (http://www.scala-lang.org/docu/files/api/scala/Function1.html) that has one abstract method: apply. It turns out that (x: Int) => x + 1 is just convenient syntax for creating instances of scala.Function1 and defining it's apply method. In Java, defining and calling fun2 might look like:

  scala.Function1<Int, Int> fun2() {
    return new scala.Function1<Int, Int> {
      Int apply(Int x) { return x + 1 }
    }
  }

  fun2().apply(2)

Finally, fun3 is a field. In Java, defining and calling fun3 might look like:

  final scala.Function1<Int, Int> fun3 = new scala.Function1<Int, Int> {
    Int apply(Int x) { return x + 1 }
  }

  fun3.apply(3)

As you can imagine, for this trivial use case, fun1 is probably most efficient. fun2 will create a new (probably short-lived) object every time it is called, and fun3 will create one object and hold onto it forever.

Note that in Scala, any object can "look" like a method, if it has an apply method. Just like fun3(3) is turned into fun3.apply(3), so will list(0) be turned into list.apply(0) /* get first element of list */ etc.

Hope this helps,

--j

On Thu, Mar 12, 2009 at 1:57 AM, Silvio Bierman <sbierman@jambo-software.com> wrote:

Hello all,

I am a long time Java programmer with a C/C++ history starting from ~1985
and I am slowly moving stuff to Scala. I have the following question for
which I could not find a clear anwer:

Say I have this:

object Test extends Application
{
 def fun1(x : Int) = x + 1
 def fun2 = (x : Int) => x + 2
 val fun3 = (x : Int) => x + 3

 println(fun1(1) + fun2(2) + fun3(3))
}

This prints 12 as I would have expected. But what are the subtle differences
between fun1, fun2 and fun3?

Silvio

--
View this message in context: http://www.nabble.com/Question-about-definitions-tp22471447p22471447.html
Sent from the Scala - User mailing list archive at Nabble.com.


Silvio Bierman
Joined: 2009-02-16,
User offline. Last seen 1 year 16 weeks ago.
Re: Question about definitions

Thanks you, guys. This was kind of what I expected but these detailed
explanations makes it all clear as a whistle to me now.
The thing that threw me off a little was that fun1, fun2 and fun3 are all
good candidates for

def stub(f : Int => Int,x : Int) = f(x)

println(stub(fun1,1) + stub(fun2,2) + stub(fun3,3))

but I now understand that fun3 is a direct match for f, fun2 needs to be
called to return such an exact match and fun1 needs some implicit coersion
to a matching value.

Am I correct?

Silvio

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: Question about definitions
Correct, but...

Remember how I said I was lying about vals/vars being Java fields? They're backed by private fields but exposed by public methods. The reason they're exposed by public methods is so that they can be overriden in subclasses. The bottom line is that they still require a method call, like fun2. However, fun2 will allocate a new Function object every time it is called, whereas fun3 will return the same (pre-allocated) Function object every time.

Methods of the form fun1 can sometimes (as in this case) be converted automatically to Function objects. If you want to explicitly force the conversion, use: fun1 _

--j

On Thu, Mar 12, 2009 at 7:03 AM, Silvio Bierman <sbierman@jambo-software.com> wrote:

Thanks you, guys. This was kind of what I expected but these detailed
explanations makes it all clear as a whistle to me now.
The thing that threw me off a little was that fun1, fun2 and fun3 are all
good candidates for

def stub(f : Int => Int,x : Int) = f(x)

println(stub(fun1,1) + stub(fun2,2) + stub(fun3,3))

but I now understand that fun3 is a direct match for f, fun2 needs to be
called to return such an exact match and fun1 needs some implicit coersion
to a matching value.

Am I correct?

Silvio
--
View this message in context: http://www.nabble.com/Question-about-definitions-tp22471447p22477052.html
Sent from the Scala - User mailing list archive at Nabble.com.


Silvio Bierman
Joined: 2009-02-16,
User offline. Last seen 1 year 16 weeks ago.
Re: Question about definitions

Thank you Jorge,

Yes, I know that part about the field access being implemented by methods
calls. I can see two advantages in this: field access can be overridden and
changing a field to a method can be implemented in such a way that it does
not require recompilation.
It complicates the interface with Java somewhat, though. Do you know where I
can find info on the naming scheme used for these methods?

Regards,

Silvio

Jorge Ortiz-3 wrote:
>
> Correct, but...
>
> Remember how I said I was lying about vals/vars being Java fields? They're
> backed by private fields but exposed by public methods. The reason they're
> exposed by public methods is so that they can be overriden in subclasses.
> The bottom line is that they still require a method call, like fun2.
> However, fun2 will allocate a new Function object every time it is called,
> whereas fun3 will return the same (pre-allocated) Function object every
> time.
>
> Methods of the form fun1 can sometimes (as in this case) be converted
> automatically to Function objects. If you want to explicitly force the
> conversion, use: fun1 _
>
> --j
>
> On Thu, Mar 12, 2009 at 7:03 AM, Silvio Bierman
> > wrote:
>
>>
>> Thanks you, guys. This was kind of what I expected but these detailed
>> explanations makes it all clear as a whistle to me now.
>> The thing that threw me off a little was that fun1, fun2 and fun3 are all
>> good candidates for
>>
>> def stub(f : Int => Int,x : Int) = f(x)
>>
>> println(stub(fun1,1) + stub(fun2,2) + stub(fun3,3))
>>
>> but I now understand that fun3 is a direct match for f, fun2 needs to be
>> called to return such an exact match and fun1 needs some implicit
>> coersion
>> to a matching value.
>>
>> Am I correct?
>>
>> Silvio
>> --
>> View this message in context:
>> http://www.nabble.com/Question-about-definitions-tp22471447p22477052.html
>> Sent from the Scala - User mailing list archive at Nabble.com.
>>
>>
>
>

Jorge Ortiz
Joined: 2008-12-16,
User offline. Last seen 29 weeks 4 days ago.
Re: Question about definitions
Naming scheme? They're named as you'd expect. The one "gotcha" is operator symbols. Those are transformed as per the compiler's scala.tools.nsc.util.NameTransformer

--j

On Sun, Mar 15, 2009 at 12:06 PM, Silvio Bierman <sbierman@jambo-software.com> wrote:

Thank you Jorge,

Yes, I know that part about the field access being implemented by methods
calls. I can see two advantages in this: field access can be overridden and
changing a field to a method can be implemented in such a way that it does
not require recompilation.
It complicates the interface with Java somewhat, though. Do you know where I
can find info on the naming scheme used for these methods?

Regards,

Silvio



Jorge Ortiz-3 wrote:
>
> Correct, but...
>
> Remember how I said I was lying about vals/vars being Java fields? They're
> backed by private fields but exposed by public methods. The reason they're
> exposed by public methods is so that they can be overriden in subclasses.
> The bottom line is that they still require a method call, like fun2.
> However, fun2 will allocate a new Function object every time it is called,
> whereas fun3 will return the same (pre-allocated) Function object every
> time.
>
> Methods of the form fun1 can sometimes (as in this case) be converted
> automatically to Function objects. If you want to explicitly force the
> conversion, use: fun1 _
>
> --j
>
> On Thu, Mar 12, 2009 at 7:03 AM, Silvio Bierman
> <sbierman@jambo-software.com
>> wrote:
>
>>
>> Thanks you, guys. This was kind of what I expected but these detailed
>> explanations makes it all clear as a whistle to me now.
>> The thing that threw me off a little was that fun1, fun2 and fun3 are all
>> good candidates for
>>
>> def stub(f : Int => Int,x : Int) = f(x)
>>
>> println(stub(fun1,1) + stub(fun2,2) + stub(fun3,3))
>>
>> but I now understand that fun3 is a direct match for f, fun2 needs to be
>> called to return such an exact match and fun1 needs some implicit
>> coersion
>> to a matching value.
>>
>> Am I correct?
>>
>> Silvio
>> --
>> View this message in context:
>> http://www.nabble.com/Question-about-definitions-tp22471447p22477052.html
>> Sent from the Scala - User mailing list archive at Nabble.com.
>>
>>
>
>

--
View this message in context: http://www.nabble.com/Question-about-definitions-tp22471447p22526787.html
Sent from the Scala - User mailing list archive at Nabble.com.


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