chen
chen

Reputation: 4490

Using method to create function? The details explanation?

def first[A] :Tuple2[A,_] => A  = ( pair :Tuple2[A,_] ) => pair._1
val name = first( ("Anna", 23) )

"If you take a closer look at line 2, what you see here is a method call which returns a newly created function of type Tuple2[String,Any] => String (since the compiler kicks in and infers the needed type for applying to person). Although the whole expression looks like an ordinary method call, it’s in fact a method call (to a factory method without any parameter) and a function call which follows afterwards. " -- this is the explanation of the above code.

I am not able to reason about the first step of the above process (the process creating a function object). Can someone write out a "human compiler" procedure explicitly?

EDIT: I think the fully expanded logic for line 2 should be the following two lines

val firstAsFunc= first[String]; 
val name = firstAsFunc(("Anna", 23))

Upvotes: 0

Views: 112

Answers (4)

Daniel C. Sobral
Daniel C. Sobral

Reputation: 297155

I'm not sure to break it down further. Here's what I can think of -- I hope you get it, or that someone else is feeling more clever than I.

scala> val func = first[String] // method call
func: Tuple2[String, _] => String = <function1>

scala> val name = func( ("Anna", 23) )
name: String = Anna

The problem with the above is that func is really a getter -- a method call itself -- so I'm hardly changing anything.

EDIT

I'm not sure what you mean by formal parameter. The method first doesn't have value parameters, just type parameters. Trying to pass a value parameter to it would be a syntactical error.

Upvotes: 3

Dan Burton
Dan Burton

Reputation: 53665

If you take a closer look at line 2, what you see here is a method call which returns a newly created function of type Tuple2[String,Any] => String

This explanation is wrong. Line 2 does not "return a newly created function". The function is created on line 1, as explained by Rex Kerr.

Although the whole expression [on line 2] looks like an ordinary method call, it’s in fact a method call (to a factory method without any parameter) and a function call which follows afterwards.

I don't believe this is true; there is no hidden factory method going on, because the Function1 object has already been created on line 1.

One of the questions I was asking what is the formal parameter for method first.

See Wikipedia > Parameter # Computer Science

Upvotes: 0

Rex Kerr
Rex Kerr

Reputation: 167871

When you say

(pair: Tuple2[A,_]) => pair._1

the compiler decides that you are actually saying

new Function1[Tuple2[A,_], A] {
  def apply(pair: Tuple2[A,_]) = pair._1
}

That is, the first method creates a new object (of type Function1) with a method called apply which then is transparently called when you say first(...). (You would get the same thing if you wrote first.apply(...).)

(Note: Tuple2[A,_] can itself be abbreviated (A,_).)

Upvotes: 3

Paul Butcher
Paul Butcher

Reputation: 10852

I'm not 100% sure that I understand which bit of the process you're asking about - are you asking about what a function object is? I'll answer that question on the assumption that it is :-)

A function object is an object that derives from one of the FunctionN (Function0, Function1 etc.) traits and implements an apply method. So your example could be rewritten:

scala> def first[A]: Tuple2[A, _] => A = new Function1[Tuple2[A, _], A] { def apply(pair: Tuple2[A, _]) = pair._1 }
first: [A]=> Tuple2[A, _] => A

scala> val name = first( ("Anna", 23) )
name: java.lang.String = Anna

You can see that a function is actually an instance of FunctionN like so:

scala> def foo(x: Int, y: Double): String = "x = "+ x.toString +", "+ y.toString
foo: (x: Int, y: Double)String

scala> (foo _).isInstanceOf[Function2[_, _, _]]
res1: Boolean = true

Upvotes: 1

Related Questions