1

Im relatively new to scala functions and I'm getting confused on how this syntax sugar actually works and when to use a particular type.

I have written 3 functions all which should do the same thing, but I'm having problems understanding why Function0 is behaving differently

version 1

val fn1 : (String) => String = System.getProperty(_)

println(fn1("os.name"));

version 2

  val fn2 : () => String = System.getProperty("os.name")

  println(fn2());

Version 2 gives type mismatch; found : String required: () ⇒ String

version 3

val fn3 = () => System.getProperty("os.name")

println(fn3());

I understand that for version 2 scala already knows the return type of System.getProperty but why does it produce that particular error, why does it prevent me form explicitly stating the return type. I personally prefer explicit return types so I don't have to dive into a method to see what it is returning.

2 Answers 2

4

In val fn2 : () => String = System.getProperty("os.name"), the System.getProperty("os.name") will be executed and return a string value. But you are saying fn2 is a value, which is a function that takes no arguments and returns a string.

When you do System.getProperty(_), it is like doing x => System.getProperty(x), which is a function that takes a string and returns a string. That is why first version works.

Sign up to request clarification or add additional context in comments.

1 Comment

Sorry for the late response on this if the second functions is interpreted as "a value, which is a function that takes no argument and returns a string. Wouldn't the first function be read in a similar way i.e. returns a function that takes a string and returns a string. Instead the compiler figures out that you ant to return a string not a function.
1

This version will typecheck:

val fn2 : () => String = () => System.getProperty("os.name")

Calling fn2() here is just like calling:

def fn2(): String = System.getProperty("os.name")
fn2()

In your fn1 example, the underscore is providing this implicit syntax, which looks a lot more like what you need for the empty-args case:

val fn1 : (String) => (String) = (s) => System.getProperty(s) 

2 Comments

defs are methods, which are not first class objects, contrary to FunctionN. So val fn2: () => String is definitely not the same thing as def fn2(): String.
Edited my answer for clarity. In the OP's example, the two models I've written are equivalent. defs cannot be passed as objects, but I think this comparison is still helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.