1
votes
scala> def nextOption = if (util.Random.nextInt > 0) Some(1) else None
nextOption: Option[Int]

scala> nextOption
res1: Option[Int] = Some(1)

scala> nextOption
res3: Option[Int] = None

Trying to learn scala, few questions following the code executed above:
1. Is the right part of nextOption definition consideret a function literal?
2. Would that change if it was defined using 'val' keyword instead of 'def'.
3. Why is nextOption type an Option[Int] and not a function? ( ()=>Option[Int] )
4. Would adding parantesses or brackets to this code change its type/value?
5. What would be the difference between nextOption and something like '() => if (......) some(1) Else None'

4

4 Answers

5
votes
  1. Is the right part of nextOption definition considered a function literal?

No, that is just the method body.
A function literal is something like: (i: Int) => i + 1

  1. Would that change if it was defined using 'val' keyword instead of 'def'.

If you just change the def with a val the code would be executed just one time and you would get a value, not a method nor a function.

  1. Why is nextOption type an Option[Int] and not a function? ( ()=>Option[Int] )

That is not the type of nextOption, but the type of the returned value after executing the method.

  1. Would adding parentheses or brackets to this code change its type/value?

Not sure what exactly do you mean with this one, please edit the question and I will edit the answer.

  1. What would be the difference between nextOption and something like '() => if (......) some(1) Else None'

If you do this:

val foo = () => if (util.Random.nextInt > 0) Some(1) else None

Then you effectively created a function, that you can use like this:

foo()
// res: Option[Int] = None

This may be of help: Difference between method and function in Scala

1
votes
  1. No, it is not a function literal, it is a method. A function literal would look like

    val nextOptionF = () => if (util.Random.nextInt > 0) Some(1) else None

You can convert your method into a function by doing

val nextOptionF = nextOption _ 
  1. If you just change from def to val nextOption would become an Option[Int]
  2. When you execute nextOption the method is executed because you didn't add parameters to the definition of your method. If you had added parameter:
    def nextOption() = if (util.Random.nextInt > 0) Some(1) else None


    nextOption
    res1: Option[Int] = Some(1)
  1. Replied already
  2. That would return a function literal
1
votes

Going in order:

1) No. Function literals are anonymous functions. Here you clearly assign your expression a name. As you mention later () => if (......) some(1) Else None would be a function literal. If you do this in the REPL, you will see it literally returns a function :) Function literals don't have a name, tho you can assign them to a value/variable. You can read about it more here:

What is a function literal in Scala?

2) There wouldn't be any difference in this case. If you were to do an anonymous function, under the hood, the compiler would interpret this as an instance of Function0. It is called the ETA Expansion This however I believe takes away your ability to specify generic types. More on the difference here

3) Scala allows to call methods with zero parameters just by name, aka you can omit the parenthesis. Thus, when you just call nextOption, it evaluates the function and returns the result.

4) No, it wouldn't.

5) As mentioned in the first case, this indeed would be an anonymous function and you would see the function in the REPL

1
votes
  1. Why is nextOption type an Option[Int] and not a function () => Option[Int]?

I think confusion stems from the way REPL prints method types of parameterless methods. Consider what happens if we add empty parameter list ()

scala> def nextOption() = if (util.Random.nextInt > 0) Some(1) else None
nextOption: ()Option[Int]

Note how now method type is printed as ()Option[Int], instead of familiar () => Option[Int]. IMHO, it might be less confusing if REPL would print method type of parameterless methods like so

=> Option[Int]

as they are described in SLS

A special case are types of methods without any parameters. They are written here => T. Parameterless methods name expressions that are re-evaluated each time the parameterless method name is referenced.

Note methods are not values and method type is just something internal to the compiler:

Method types do not exist as types of values. If a method name is used as a value, its type is implicitly converted to a corresponding function type.

We can convert method type to a function type explicitly via eta expansion

scala> nextOption _
res12: () => Option[Int] = $$Lambda$1218/528012220@37e5111b