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

=> in def vs. val

3 replies
Raoul Duke
Joined: 2009-01-05,
User offline. Last seen 42 years 45 weeks ago.

hi,

am i the only one who finds it hard to learn and grok the ways to
specify functions (val) with or without types vs. methods (def)? i'm
totally just cargo-cult pattern-match programming when it comes to
this. any pointers to cheat-sheets / exhaustive yet clear and concise
summaries would be appreciated. (yes, i've been trying to grok the
language spec about this as well as googling around.)

thanks.

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: => in def vs. val
Perhaps you could be a little more specific about what you want to do.

In general, in Java you write

ReturnType myMethodName(ParameterType1 p1, ParameterType2 p2, ...)

whereas in Scala you write

def myMethodName(p1: ParameterType1, p2: ParameterType2, ...): ReturnType

So far so good.  The type of the *equivalent function* is

(ParameterType1, ParameterType2, ...) => ReturnType

and if you want to specify a particular function of that type, then you specify the parameter names and give a code block:

(p1: ParameterType1, p2: ParameterType2, ...) => {
  /* code */
  myReturnValue  // Should have type ReturnType
}

Now, you can easily convert a method into a function:

  myObject.myMethodName _

So, putting this all together

object UntestedExample {
  def isPositive(i: Int): Boolean = (i > 0)

  val posTestA: (Int) => Boolean = (i: Int) => { (i > 0) }
  val posTestB = (i: Int) => (i>0)
  val posTestC = isPositive _

  def thresholdFunctionGenerator(i:Int): (Int) => Boolean = {
    (j: Int) => (i > j)
  }

  val posTestD = thresholdFunctionGenerator(0)

  val threshFuncFuncA = (i:Int) => { (j: Int) => (j>i) }
  val threshFuncFuncB = thresholdFunctionGenerator _

  val posTestE = threshFuncFuncA(0)
  val posTestF = threshFuncFuncB(0)
}

Here I've defined a method isPositive and six equivalent functions (stored in vals).  Hopefully you can follow how each one is being created.  (Note that I haven't always used either the most pedantically long or the most concise version possible.)

Now, in addition to the story I've already told, there are three wrinkles.

(1) Methods with multiple parameter lists.

You can write these in Scala:

def multiMethodThreshold(i: Int)(j: Int): Boolean = (j>i)

When you call them, you call them with multiple parameters.  However, you can break in at any point and convert the remainder to a function:

val posTestG = multiMethodThreshold(0) _

Or, you can convert the whole thing to a function that returns a function that returns the result:

val threshFuncFuncC: (Int) => ( (Int) => Boolean) = multiMethodThreshold _

(2) Methods and functions with no parameters vs. by-name parameters.

You can write a method that takes a function without any parameters at all:

def check(value: => Int) = (value > 0)

This is called a "by-name parameter", and basically says that instead of passing the actual value, if you pass a variable, it will be passed by reference and looked at every time you call the method (functions of the type () => stuff work too, typically).  This construct can be used in very many places, but not everywhere.

Or, you can write a method that takes a function with an empty parameter list:

def check(value: () => Int) = (value() > 0)

Here, you *must* pass a function, and you call it by using ().  But otherwise it works a lot like the by-name parameter version, and it can be used everywhere.

(3) Partial functions.

These are most often used where you need a case statement.  This is a little beyond the scope of what I want to get into right now, but for now just keep in mind that you can write your very own methods that you use like so:

myObject.myMethod {
  case this:ThatType => stuff
  case _ => differentStuff
}

by using a PartialFunction[TypeToPassIntoCase,TypeReturnedFromCase].  (The code block above is actually the definition of such a partial function.)

I hope this helps somewhat.

  --Rex

On Tue, Jan 26, 2010 at 9:03 PM, Raoul Duke <raould [at] gmail [dot] com> wrote:
hi,

am i the only one who finds it hard to learn and grok the ways to
specify functions (val) with or without types vs. methods (def)? i'm
totally just cargo-cult pattern-match programming when it comes to
this. any pointers to cheat-sheets / exhaustive yet clear and concise
summaries would be appreciated. (yes, i've been trying to grok the
language spec about this as well as googling around.)

thanks.

Raoul Duke
Joined: 2009-01-05,
User offline. Last seen 42 years 45 weeks ago.
Re: => in def vs. val

On Tue, Jan 26, 2010 at 7:59 PM, Rex Kerr wrote:
> I hope this helps somewhat.

i bet it will be, thank you for the detailed response! i am parsing!

Raoul Duke
Joined: 2009-01-05,
User offline. Last seen 42 years 45 weeks ago.
Re: => in def vs. val

cf. Rex's long answer, some of which works for me, and malheursement
some of which didn't, at least as far as i understood it, but it all
helped me start to get more of a clue. here's another way i'd answer
what i was wondering about. pretty please offer corrections to my
cluelessness here below.

A. Things To Be Aware Of wrt Your Previous Mental Models.

0) Methods and functions are similar, but of course not exactly the
same beasts in Scala (or, well, most places). You can make one "point
to" an implementation of the other, so you can sorta convert them back
and forth if need be, tho I'm not sure how scopes might come in to
play.

1) Scala's type inference only works for the return type at best. You
must specify argument types.

a) So the type spec might appear to oddly be only "half" vs. if you
are thinking Java or Haskell (since the former has no type inference,
and the latter since it lacks OO has "complete" type inference).

b) One way of specifying functions requires that you also specify the
return type.

2) When defining a method vs. a function, the delimiters used to
separate Name, Arguments, Result, and Body are kinda different. This
might have something to do with needing the syntax to support
anonymous functions (lambdas)? In particular, be aware of how ":"
changes the syntax for a function.

B. Examples, Trying To Work Our Way Up From Simple To More Complex.

def F() = 4
val F = () => 4
val F:()=>Int = () => 4

def F(x:Int) = x
val F = (x:Int) => x
val F:(Int)=>Int = (x) => x

def F(x:Int, y:Int) = x+y
val F = (x:Int, y:Int) => x+y
val F:(Int,Int)=>Int = (x,y) => x+y

val Ff = (x:Int) => x
def Df(x:Int) = Ff(x)

def Df(x:Int) = x
val Ff = (x:Int) => Df(x)

sincerely.

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