Functional Scala: Functions

Welcome back to the second episode of Functional Scala!

After we’ve checked out some core ideas and extracted Expression based function application as the basic computation method of Functional Programming within the last episode, let’s start with what Dr. Erik Meijer* would call the bread and butter of Functional Programming: and now guess what … it’s surprisingly about … Functions (please imagine a chorus of trumpets in the background while reading this).

In order to call a Function (it is said to apply a Function to its arguments), you firstly have to define one. So let’s get a feeling about how to define Functions in Scala …

Function Literals

Let’s remember the definition of a Function from the last episode:

A Function is a mapping that takes one or more arguments and produces a single result (typically by a function definition that specify how the result can by calculated solely in terms of its arguments).

So all it needs to define a function is to declare the parameters (and its types, since Scala is a statically typed language) on which the function will operate and give a definition on how the result is calculated, typically in terms of the the given parameters. Within Scala you’re able to define a Function in a literal form, by specifying exactly these both essential parts of a Function – a list of parameters followed by the definition of the functions body:

(  x :Int,  y :Int  )  =>  x  +  y

What we have here is a simple function literal, first declaring a list of parameters (both of type Int), followed by the formula for calculating the result – both separated by => (let’s call it the function arrow) which discriminates the parameters (on the left) from the Function body (on the right). It turns out that this literal form is kind of syntactic sugar for constructing an instance of a special Function type (more on that in a later episode).

Wow, that was simple. But what if my Function does a slightly more complex calculation that may be somewhat ‘longer’ than the given example above? Well, of course you’re able to define a multiline Function simply by embracing the Funtion body in curly braces:

(  a :Int,  b :Int,  c :Int  )  =>  {
    val aSquare = a * a
    val bSquare = b * b
    val cSquare = c * c

    aSquare + bSquare == cSquare
}

Look at that admittedly somewhat bloated example of a Function, which tests if the three given integer values form a so called Pythagorean Triple. Wait wait – you may proclaim: Ok, I see those multiple lines within that example, I see those mentioned curly braces, but what i don’t see is any return statement which states what the function may return to its caller. So let’s explore the body of the Function line by line:

In Line 2 to 4, we’re calculating some intermediate values in terms of the given parameters. In order to refer to these intermediate values afterwards, we gave them an alias name, using val. Now in line 6 it gets more interesting. What we see is an expression which is formed in terms of the previous calculated intermediate values. In Scala it turns out, that the result of the whole Function always evaluates to the value of the last expression within the Function body. And since our last expression constitutes a (equality) relation that may hold or not, this last expression and hence the result of the Function evaluates to either true or false.

Function types

Not so fast, mate. We’ve said that Scala is a statically typed language, hence we had to declare the types of a Functions parameters. But what about the type of the Functions result value? And don’t let us stop here – since we’ve also already mentioned that the outcome of a Function literal is an instance of a special Function type – what about the type of the whole function? Well spotted!

As for the type of a Functions result value, we’ve already gathered enough knowledge to answer that. Its simply the type of the value to which the last expression within the Function body evaluates. Let’s recapitulate and think a wee bit what the type of the whole function may be. There are two essential parts of a Function: The parameter list and the Function body, separated by the function arrow =>. Now, every parameter has its own type and as we just discovered, the Function body is essentialy expressed by its result, which also has its own type. So the nature of a Function is reasonable characterized by the nature of its parameter values which can be applied to the Function (that is their types) and the nature of the Functions result (that is the type of the result value). Again, we may separate the parameter types an the result type when expressing a Functions type – didn’t we already possess such an separator? Ahhh, now we should be able to express the types of our Functions …

As for our first example, in goes a first parameter value of type Int and a second parameter value also of type Int. Since the addition of two Int values evaluates to another Int value, the result is also of type Int, for which we can now express the type of the whole Function as follows …

(  Int,  Int  )  =>  Int

As a type can be generally seen as a collection of values that share some common characteristics, the above Function type represents all Functions that map two arguments of type Int to a result which is also of type Int. And while our Function is one specific member of that collection, we can think of a whole bunch of other Functions, also taking two arguments of type Int and resulting to an Int, hence sharing the same Function type (pretty much the same as we can choose from a whole bunch of Integer values that all share the same type Int).

As for our second example, we can repeat that game. All three parameters are of type Int. As we’ve seen, the last expression of the Functions body evaluates to a boolean value, so the result is of type Boolean. Now guess the type of the Function …

(  Int,  Int,  Int  )  =>  Boolean

Ah, ok – now we’re able to infer and express the type of a Function. It’s pretty nice that we’re now capable to deduce the type by looking at the Function definition, but what about the compiler? Well, he does the same – trying to infer the type of a given Function. And sometimes, if the compiler isn’t able to deliver, we have to give him a swift kick in the pants and declare the type of a Function explicitly …

Functions as first class values

All in all, if you’re coming from an object oriented world, a Function seems nothing more than an ordinary method within an object. First of all, remember the last episode – a Function is only allowed to depend on the given parameters whereas a method may refer to the internal state of the object it’s a member of or – even worse – may alter the internal state of that object which can be seen as an evil side effect (we’ll come back to that aspect in a later episode).

For now, i want to show you the difference between a method and a Function from another angle: what is the type of a method? Uhm, well …
It turns out, that a method is only a member of a certain object. The object itself is of course an instance of a certain type, but the method itself has no type. Well, if that makes a little snarl in your head (as it did with mine when i thought about it the first time), let’s look at it from another perspective: As we’ve experienced, every Function has a type. And like any other type (like Int or Boolean) they are no special if used as parameter types or the result type within another Function (remember the first episode, where we’ve already mentioned the idea to pass Functions as arguments to other Functions within our fold example – more on that when we explore Higher Order Functions). So while it’s possible to pass a Function to another Function, it’s not possible to pass a method to a Function. It gets more weird if you think of a Functions result value: while its pretty natural to receive a Function as the result to a call of another Function (huh? normal? again – wait for the power of Higher Order Functions), you can’t think of a naked method as the result of a Function call since a method always needs an object it belongs to .

So while a method can’t be seen as a discrete value in its own right, a Function is! You may have heard of some functional civil rights activists, claiming Functions as first class citizens or first class values. Now you know why – because a Function isn’t anything worse or other than all the values of other types you already now. And like you’re allowed to give a value – of say type Int - an alias name (using val) and refer to that value by that alias, you can of course also do so with a function (since its also a value of that above mentioned Function type):

val add  =  (  x :Int,  y :Int  )  =>  x  +  y

Now we have an ‘alias’ name add for our Function.  Whenever we refer to that add, we refer to the Function which is defined by that function literal on the right side of the equals sign.

Remember the above statement, the compiler isn’t sometimes in the position to infer the type of a Function and therefore we have to let’em off the hook by explicitly declaring the type of the Function? It turns out that type inference is generally unsteady when leveraging recursion:

val power  =  (  base: Int,  exp :Int  )  =>  if(  exp <= 1  ) base  else  base * power(  base,  exp - 1  )

If you try to compile that Function, the compiler will complain that he isn’t able to infer the Functions type:

error: recursive value power needs type

Ahh, the compiler recognizes our Function power as a value. Rightfully so! But now he’s asking for some help while he’s trying to solve our little riddle. Let’s give him what he’s longing for …

val power : ( Int, Int ) => Int  =  ( base: Int, exp :Int ) => if( exp <= 1 ) base else base * power( base, exp - 1 )

So what we have here now is a full blown declaration of a Function. Everything on board: An alias name for refering to that Function later on, introduced as a value. An explicit type declaration for that value, so the compiler can settle back and relax. And of course the value itself – our Function literal, consisting of parameter list and Function body – the complete agenda. Graham Hutton** would be pleased while phrasing it like so

A Function is defined by using an equation that gives a name for the function, a name for each of its arguments, and a body that specifies how the result can be calculated in terms of the arguments

By the way. See that if statement? Whoops – you know i shouldn’t say statement as its a term coming from the imperative world. In fact, it’s effectively an if expression in our case (since its the last expression in the Function body, it is treatet as an expression that has to evaluate to a result value). What’s the difference you may ask? Well, an expression always evaluates to a value of a certain type. So while we call it an if expression, it also have to evaluate to a value under all circumstances. And that means, that you can’t omit the else case if leveraging Scalas if as an expression (Note, that Scala as an object-functional language has to serve both worlds, so if you don’t employ Scalas if as an expression, you are allowed to omit the else case)!

Function Application

Now that we’ve defined our first functions, let’s use them! Let’s apply our Functions to some concrete argument values of the appropriate type!
Calling a Function in Scala looks pretty much the same as Function application is defined in mathematical Notation: its usually denoted by enclosing the arguments in parentheses, following the name of the Function.

Lucky we! Since we just saw how to give a Function a name (that is to declare a Function literal as a value of a certain Function type and relate that Function to a name ), we’re now able to call it by simply refering to that name:

val byteStates  =  power(  2,  8  )

Admitted, nothing very exciting really happened.  We’ve just applied our Function power to the base of 2 and an exponent of 8, calculating the number of different states of a single byte. Just note that Function application represents nothing more than another expression which evaluates to a value (that is the result value of that Function) of a certain type (that is the type of the Functions result value). And of course we can relate to that value by declaring another alias name for further reference (in this case byteStates). Ahh, and we already know that we don’t have to declare that values type explicitly, because the Scala compiler is able to infer it: in this case, value byteStates simply features the result type of the Function (while the type of the Function was already advertised to the compiler).

Since we enclose all arguments in parentheses, there’s no uncertainty about associativity: Function application has naturally always highest priority – it’s always clear which expressions are captured and used as arguments. Expressions as arguments? Got you! Since that feature seems so self-evident to us, it’s usually not worth to mention: of course you’re not only allowed to apply Functions to plain values, but also to some more complex expressions. Since expressions always evaluate to a value of a certain type in the end, the compiler is able to resolve that kind of composition:

val isPythTriple_3_4_5   =    add(  power( 3, 2 ),  power( 4, 2 )  )   ==   power( 5, 2 )

This should give us no headache at all. What we have here is a neat expression which we can decompose easily: it’s a simple equality relation between two sub-expressions. On the left side’s a really really complex Function application, where the arguments of Function add (which expects two values of type Int) emerge out of two more sub-expresions which turn out to be some more function calls on power (which surprisingly evaluate both to a value of type Int). All in all no virgin soil here.

Summary

Wow, what a day -we just saw that Scala supports Function types in a very literal way. And the best: there’s nothing mysterious about it at all. You just need to get used to it – a Function is nothing more or less than any other value of your well known type universe. And just what you’re able to do with values of other types (think again of Int, Boolean or List[String]) you can also do with Functions: Relate them to an alias name, pass them around, get them back from Function calls – the whole clickedy clack …

Of course there are also some drawbacks we have to speak about, since Scala is an object-functional langage which therefore has to take some compromises. What about true variables in conjunction with Functions? Can we apply some mutable objects as arguments to Functions? And if so, are we allowed to mutate them within the Function, triggering some kind of side effect? If a Function is already an instance of a certain Function type – what about polymorphic Functions vs. polymorphic methods (read generic, type parameterized methods)?

We’ve just scratched the surface. What we’ve now aquired is a good foundation for our further steps within the functional world. As we said at the beginning – we’re now able to eat the bread and butter of Functional Programming in Scala. But there’s also some marmalade, hazelnut spread, not to speak about the whole dessert. We’ll see different ways for defining Functions, e.g. in terms of other functions, new powerful ways of abstraction by leveraging some special, higher Order Functions (did i mention that already?) or just come up with new concepts of deriving Functions out of existing Functions. But each of them is a separate topic for another episode in the land of ‘Functional Scala’ …


* some would call Dr. Erik Meijer simply a Functional purist, i just call him a really cool guy who was able to spark my interest in Functional Programming

 
** Dr. Graham Hutton is another luminary of Functional Programming, who’s written a wundeful book called Programming Haskell (but be warned: while the book pretends to be an introduction to Haskell, i think in truth it strives for the proliferation of Functional Programming, if not world domination).

About these ads

15 Responses to “Functional Scala: Functions”

  1. Heiko Seeberger Says:

    There are other statically typed languages where the following does not hold true: “… all it needs to define a function is to declare the parameters (and its types, since Scala is a statically typed language) on …”.

    Looking at – for example – Haskell, we don’t have to declare parameter types in most cases, because the Haskell type inferencer is even more powerful than the Scala one.

    • Mario Gleichmann Says:

      Yep, you’re right Heiko!

      All in all, Haskell allows for polymorphic functions, which unfortunately isn’t possible that easy way in Scala (since a Function in Scala is always a concrete instance of a certain Function type, which needs to be already type parameterized for the given arguments and result value).

      Though there are some ‘tricks’ to kind of simulate that feature in Scala, using type parametrizable methods, acting as generators for type parameterized Functions, as we will see in a further episode ;o)

      Greetings

      Mario

  2. Twitted by etorreborre Says:

    [...] This post was Twitted by etorreborre [...]

  3. Lutz Hankewitz Says:

    Nice read.
    Especially the explicit difference between function and method was enlightening.
    I am curious about what’s cooming next.

  4. Developpef Says:

    What a great serie of articles!

    I’m just a brand new beginer in functional programing world through Scala… I have to admit that your writing is a real enlightment since all the other articles/tutorials I recently read are generally basic formal syntax explanation or “mystical” exercices!
    I’m trying to learn this new programing paradigm and as soon as I am ready, I will also write some more articles about Scala on my blog, since I think the french community needs to grow! So your articles are really helpful for my understanding.

    Regards

  5. Functional Scala: Functions as Objects as Functions « brain driven development Says:

    [...] ride to some Scala internals and open the curtain for that arcane Function types i talked about the last episode. That said, this episode is more about some Specialité de Scala rather than about Functional [...]

  6. Functional Scala: Closures « brain driven development Says:

    [...] knowledge about the definition and some of the characteristics of common Functions within the first three episodes, let’s not waste any more time and take a look at another example of a Function, [...]

  7. High, Higher, Higher Order Functions « brain driven development Says:

    [...] filter… Hey, wait a minute! Didn’t we say that functions are first class values? Yep, we did! So they don’t differ from other values? Yep, they differ only in type. Apart from that they [...]

  8. Functional Scala: Lambdas and other shortcuts « brain driven development Says:

    [...] – it’s not gonna fall from heaven! Sure, sure, but you may remember the second episode about functions, where we’ve seen pure function [...]

  9. Functional Scala: Turning Methods into Functions « brain driven development Says:

    [...] comes to mix those into the functional game. Let’s repeat some of the core chracteristics for functions: we’ve said that functions are first class values, coming with its own [...]

  10. kasi Says:

    The best

  11. 関数とメソッドが違わなければならないたった一つの理由 Says:

    [...] Functional Scala: Functions ≪ brain driven development [...]

  12. Mitch Says:

    Hey, this is the best explanation of Scala functions I have seen in several months. Terrific, thanks so much for the information.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

Join 43 other followers

%d bloggers like this: