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

question about "function type inheritance" in scala

5 replies
John Fries
Joined: 2010-07-18,
User offline. Last seen 42 years 45 weeks ago.

Scala folk,

I'm a newbie reading "Programming in Scala", and I'm trying to make
sense of a statement made on pg 9 (Section 1.2: What makes Scala
scalable?).
The statement is:
"Function types are classes that can be inherited from subclasses."

I know that I can create new classes, and I know that functions are
objects and hence have a type.
I don't yet know how/if scala distinguishes between a type and a
class, but for now I'm not assuming that there is a distinction.
A function type might be something like "(Int,Int)String" (possibly
I'm confused on this point, perhaps its type is Function or something
like that).

The statement conjures up an image of me declaring a function type the
way I would declare a class:
class (X,Y)Z

and then subclassing that function type somehow (not sure what there
would be to inherit, since the entire implementation of the function
would be overridden).

Any advice would be greatly appreciated!

-John

David Flemström
Joined: 2009-08-10,
User offline. Last seen 42 years 45 weeks ago.
Re: question about "function type inheritance" in scala
On Sun, Jul 18, 2010 at 7:20 PM, John Fries <john.a.fries@gmail.com> wrote:
Any advice would be greatly appreciated!

All that I'm going to cover below is actually mentioned in the book you're reading, but I guess I'll give you a little preview of what's ahead.
A function type in Scala is written like this:
() => Z        //Takes 0 params and returns something of type Z
 A => Z        //Takes one param of type A and returns something of type Z
(A, B) => Z    //Takes two params of type A and B and returns something of type Z
(A, B, C) => Z //...
But the above types are actually just convenient aliases for the following classes (Functions are actual objects and thus have to have classes):
Function0[Z]
Function1[A, Z]
Function2[A, B, Z]
Function3[A, B, C, Z]
//...
(the number after the function specifies how many parameters that function takes)So to make a class that extends a function, one would write:
class IntToStringConverter extends Int => String {
  def apply(i: Int): String = i.toString
}

//or, more explicitly:
class IntToStringConverter extends Function1[Int, String] {
  def apply(i: Int): String = i.toString
}
The method "apply" is abstract and needs to be implemented by the subclass. The apply method is what gets called when the function is invoked:
val c = new IntToStringConverter

val str = c(3) //is the same as c.apply(3)
println(str)
Some great examples of things that extend functions are Array[Foo] (conceptually) which extends Int => Foo (Takes an array index and returns the thing at that index), List[Foo] which also extends Int => Foo, Set[Foo] which extends Foo => Boolean (to check whether something is an element of the set) et cetera.
Hope this helped.
John Fries
Joined: 2010-07-18,
User offline. Last seen 42 years 45 weeks ago.
Re: question about "function type inheritance" in scala

wow, that is a really remarkable unification of concepts. I thought I
had searched the book thoroughly, but hadn't found references to
FunctionN, etc. Thanks for your help, David, that completely answered
my question!

On Sun, Jul 18, 2010 at 10:47 AM, David Flemström
wrote:
> On Sun, Jul 18, 2010 at 7:20 PM, John Fries wrote:
>>
>> Any advice would be greatly appreciated!
>
> All that I'm going to cover below is actually mentioned in the book you're
> reading, but I guess I'll give you a little preview of what's ahead.
> A function type in Scala is written like this:
>
> () => Z //Takes 0 params and returns something of type Z
> A => Z //Takes one param of type A and returns something of type Z
> (A, B) => Z //Takes two params of type A and B and returns something of
> type Z
> (A, B, C) => Z //...
>
> But the above types are actually just convenient aliases for the following
> classes (Functions are actual objects and thus have to have classes):
>
> Function0[Z]
> Function1[A, Z]
> Function2[A, B, Z]
> Function3[A, B, C, Z]
> //...
>
> (the number after the function specifies how many parameters that function
> takes)
> So to make a class that extends a function, one would write:
>
> class IntToStringConverter extends Int => String {
> def apply(i: Int): String = i.toString
> }
>
> //or, more explicitly:
> class IntToStringConverter extends Function1[Int, String] {
> def apply(i: Int): String = i.toString
> }
>
> The method "apply" is abstract and needs to be implemented by the subclass.
> The apply method is what gets called when the function is invoked:
>
> val c = new IntToStringConverter
>
> val str = c(3) //is the same as c.apply(3)
> println(str)
>
> Some great examples of things that extend functions are Array[Foo]
> (conceptually) which extends Int => Foo (Takes an array index and returns
> the thing at that index), List[Foo] which also extends Int => Foo, Set[Foo]
> which extends Foo => Boolean (to check whether something is an element of
> the set) et cetera.
> Hope this helped.

Luc Duponcheel
Joined: 2008-12-19,
User offline. Last seen 34 weeks 3 days ago.
Re: question about "function type inheritance" in scala
Here is some scala REPL session
showing the relationship between functions and function values

$ scala
Welcome to Scala version 2.8.0.final (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def plusFunction(i: Int, j: Int) = i+j
plusFunction: (i: Int,j: Int)Int

scala> var plusFunctionValue = (i: Int, j: Int) => i+j
plusFunctionValue: (Int, Int) => Int = <function2>

scala> plusFunction(1, 1)
res0: Int = 2

scala> plusFunctionValue.apply(1, 1)
res1: Int = 2

scala> plusFunctionValue(1, 1)     
res2: Int = 2

scala> plusFunctionValue = plusFunction
plusFunctionValue: (Int, Int) => Int = <function2>

Here is some scala REPL session
showing how to use function types and inheritance

scala> trait PartialFunction[X, Y] extends Function[X, Option[Y]] {
     |  def isDefinedAt(x: X): Boolean
     | }
defined trait PartialFunction

scala> object InverseOfInt extends PartialFunction[Int, Double] {
     |  def apply(i: Int) = if (!isDefinedAt(i)) { None } else { Some(1.0/i) }
     |  def isDefinedAt(i: Int) = i != 0                 
     | }
defined module InverseOfInt

scala> InverseOfInt(2)
res0: Option[Double] = Some(0.5)

scala> InverseOfInt(0)
res1: Option[Double] = None

hope this helps



--
   __~O
  -\ <,
(*)/ (*)

reality goes far beyond imagination

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: question about "function type inheritance" in scala

On Sunday July 18 2010, John Fries wrote:
> Scala folk,
>
> I'm a newbie reading "Programming in Scala", and I'm trying to make
> sense of a statement made on pg 9 (Section 1.2: What makes Scala
> scalable?). The statement is:
> "Function types are classes that can be inherited from subclasses."
>
> I know that I can create new classes, and I know that functions are
> objects and hence have a type.
> I don't yet know how/if scala distinguishes between a type and a
> class, but for now I'm not assuming that there is a distinction.

Types and classes exist in Scala. Classes exist at runtime and any given
class may represent

> A function type might be something like "(Int,Int)String" (possibly
> I'm confused on this point, perhaps its type is Function or something
> like that).

That notation is how Scala presents methods. The corresponding function
would have the signature (Int, Int) => String.

> The statement conjures up an image of me declaring a function type
> the way I would declare a class:
> class (X,Y)Z

That's not Scala.

There are many ways one can end up defining or creating an actual
function.

Among them are explicitly sub-class FunctionN[T1, ... Tn, R] (where N is
the function arity, T1 ... Tn are the argument types and R is the
result type) and then implement the apply(T1, ... Tn): R = { ... }
method. But that's probably the least common way to write a Function.

Another way is to use partial application on a method:

class C {
def m(i: Int, j: Int): String = (i + j).toString
val f = m _
}

C#m is a (Int, Int)String while C#f is an (Int, Int) => String, but both
compute the same (conceptual) function.

But there are many others. E.g., blocks of case clauses produce
FunctionN or PartialFunction instance. There's a variety of notations
that yield anonymous functions in settings where they're usually
referred to as "closures."

> and then subclassing that function type somehow (not sure what there
> would be to inherit, since the entire implementation of the function
> would be overridden).
>
> Any advice would be greatly appreciated!

Keep reading Programming in Scala and write lots of Scala code. Ask
questions on #scala on Freenode or on Stack Overflow with a "scala"
tag.

> -John

Randall Schulz

Randall R Schulz
Joined: 2008-12-16,
User offline. Last seen 1 year 29 weeks ago.
Re: question about "function type inheritance" in scala

On Sunday July 18 2010, Randall R Schulz wrote:
> On Sunday July 18 2010, John Fries wrote:
> > Scala folk,
> >
> > I'm a newbie reading "Programming in Scala", and I'm trying to make
> > sense of a statement made on pg 9 (Section 1.2: What makes Scala
> > scalable?). The statement is:
> > "Function types are classes that can be inherited from subclasses."
> >
> > I know that I can create new classes, and I know that functions are
> > objects and hence have a type.
> > I don't yet know how/if scala distinguishes between a type and a
> > class, but for now I'm not assuming that there is a distinction.
>
> Types and classes exist in Scala. Classes exist at runtime and any
> given class may represent

Oops. I never came back and finished my thought there...

A class, in particular a generic class, may represent many types. Also
the existence of structural typing in Scala means that any class with
the set of members (vals, vars and defs) M conforms to all the types
corresponding to the power set of M.

Randall Schulz

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