Reputation: 4490
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
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
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
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
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