How to return Unit from a scala function? - scala

I'm trying to make a function return Unit (this is to implement an RxScala observer), but when I add () to the end of it, I get an error "Application does not take parameters". Here's my code:
val client3MessageStreamObserver: Observable[Message] = client3.messageStream()
client3MessageStreamObserver.subscribe(
m => println("Unexpected message received by client3"),
// callback for handling exceptions
t =>
println("Ex client3: " + t)
// want to make this line work (which it doesn't) which is why
// I need to be able to return Unit.
// client3TestPromise.success(true)
() // error after adding Unit literal here.
)
Why do I get this error after adding () and how can I get rid of it? If I leave it out I get an error saying "Type mismatch: Expected (Throwable) => Unit, actual: (Throwable) => Any)".

Try this:
val client3MessageStreamObserver: Observable[Message] = client3.messageStream()
client3MessageStreamObserver.subscribe(
m => println("Unexpected message received by client3"),
t => println("Ex client3: " + t)
() => ()
)
The third function onCompleted is a function Unit => Unit. So, the parameter is () and then in the return we can explicitly return () or any method returning a () such as println.

OK so I worked this out. Because subscribe expects functions as it's arguments, I needed to wrap multiple instructions in braces to make a code block, i.e.:
val client3MessageStreamObserver: Observable[Message] = client3.messageStream()
client3MessageStreamObserver.subscribe(
// single instruction function doesn't require braces
m => client3TestPromise.failure(new RuntimeException("Unexpected " +
"message received by client3")),
// multi-instruction function does require braces
t => {
println("Ex client3: " + t)
client3TestPromise.success(true)
}
)

Related

Understanding what a function is

Background
I tried to answer a question "what is function?" and wonder if I actually know what it is. Please help to understand what a "function" is in Scala. It may sound non-sense debate but please be patient to help.
Questions
1. What is function
A "function" is a "computation/operation" to be "applied" to a single "argument" to generate an "value". If there are multiple argument, then it can be converted into ()()()... which is called currying.
w is a name
b is a binding of a function object to a name
c is computation
a is application
g is argument on which apply an compuation
val w = ( ) => { }
^ ^ ^ ^ ^
| | | | |
(n) (b) (g) (a) (c)
Is it OK to say these?
Also if this is to apply a computation to an argument:
() => { }
Then it actually should be in the opposite direction?
() <= { }
or
{ } => ()
2. Decomposition of definition
Is this correct understanding of what "def f (x:Unit):Unit = {}" is?
//--------------------------------------------------------------------------------
// The function literal says:
// 1. Define a "function" (ignore "method" here).
// 2. Bind the function to a name f.
// 3. It is to be applied to an "argument" of type Unit.
// 4. Bind the argument to a name x.
// 5. E-valuation, or appliation of the function to an argument generates an "value" of type Unit.
// 6. After evaluation, substitute it with the "value".
//--------------------------------------------------------------------------------
def f (x:Unit):Unit = {}
3. Evaluation / Application
Is "evaluation" the same with "application of a function to an argument and yield an value"? When I read lambda calculas, word "application" is used, but I think "evaluation" is also used.
Unit
//--------------------------------------------------------------------------------
// The literal says:
// 1. Apply the function f
// 2. on the "argument" enclosed between '(' and ')', which is Unit.
// 3. and yield Unit as the "value" evaluated.
//--------------------------------------------------------------------------------
def f (x:Unit):Unit = {}
f()
Is it the same with this? If so is "Unit" an object?
f(Unit) // No error in Scala worksheet
What is causing the error "Too many arguments" for Unit as argument below?
// Define a function that applies on an argument x of type Unit to generate Unit
() => {} // res0: () => Unit = <function0>
(() => {}) // res1: () => Unit = <function0>
// Application
(() => {})()
/* Error: Too many arguments */
(() => {})(Unit)
4. Referential transparency
Please advise if this is correct.
Using "def g (x:String): Unit = println(x)" as an example, "referential transparency" means that g(x) can be always substituted with its result and it will not break any.
If
g("foo")
can be always replaced with
Unit
then it is referentially transparent. However, it is not the case here for g. Hence g is not a referentially transparent function, hence it is not "pure" function. Random is also not pure.
{ scala.util.Random.nextInt } // res0: Int = -487407277
In Scala, function can be pure or side-effective. There is no way to tell by just having look at a function. Or is there a way to mark as such, or validate if it is pure or not?
5. Method is not a function
A method cannot be a first class object to be passed around but it can be by converting it to a function.
def g (x:String): Unit = println(x)
g("foo")
val _g = g _
_g("foo")
Why method cannot be a first class object? If a method is an object, what will happen or what will break?
Scala compiler does clever inferences or complehentions, then if it can be converted into an object with _, why Scala does not make it a firt class object?
6. What is { ... }?
Update:
"=> T" is call by name passing expression to be evaluated inside the function, hence has nothing to do with "{...}" specifically. {...} is a block expression. Hence all below is invalid.
It looks "{...}" is the same with "=> T".
def fill[T](n: Int)(elem: => T)
Array.fill[Int](3)({ scala.util.Random.nextInt })
{...} in itself yield an value without taking any argument.
{ scala.util.Random.nextInt } // res0: Int = 951666328
{ 1 } // res1: Int = 1
Does it mean "application" is an independent first class object, or the Scala compiler is clever enough to understand it is an abbreviation of:
() => { scala.util.Random.nextInt }
or
val next = (x:Int) => { scala.util.Random.nextInt(x) }
If so, "=> T" is actually "() => T"?
In Scala function is an implementation of one of traits from Function1 to Function22 depending on input parameters amount. For your particular example w is a shorthand for anonfunW:
val w = () => {}
val anonfunW = new Function1[Unit, Unit] {
def apply(x: Unit): Unit = ()
}

Scala - Passing a function to Future.apply

I'm learning Scala and just getting familiar with syntax. I see that Future.apply takes a function as the work to do.
The following works perfectly:
val future = Future { doWork(1) }
However just for experimentation I tried some other ways to do it, and neither work appropriately.
val future = Future(() => doWork(1))
This results in the lambda becoming the completion value of the future, instead of the return value of doWork(1).
val work: () => Int = () => doWork(index)
val future = Future(work)
The same situation here. Could someone explain why passing the function as the work to be done is instead resulting in the function actually becoming the return value of the work being done. Also how would I go about this. Thanks!
The signature of method called in Future {...} is def apply[T](body: =>T) where => T is a by-name parameter. See this documentation for more info.
By-name parameters are only evaluated when used.
In examples
Future(() => doWork(1))
and
val work: () => Int = () => doWork(index)
val future = Future(work)
You are passing as by-name parameter function of type () => Int or same as Function0[Int]. This function is returned in the Future when by-name parameter is evaluated.
The function is not evaluated as Future does not call apply or ().
It will be more understandable if you add type parameters to the Future in all examples. If doWork returns Int. In this case Future { doWork(1) } is Future[Int] whereas it is Future[Function0[Int]] in the second and third examples.
The correct usage would be
val work: () => Int = () => doWork(index)
val future = Future(work())

scala Functonal abstraction (List) not working

please help me out in this scala throwing an error in below context
def SelectValues(list: List[Int],sel:Int => Boolean) ={
var sum =0
list.foreach{ e =>
if(sel(e)) sum += e
}
sum
println(sum)
}
println(SelectValues(List(1,2){e => true}))
enter image description here'screen shot
The problem is in your println line:
println(SelectValues(List(1,2){e => true}))
You don't have a comma between the List(1,2) and the {e => true} this means that you are sending a single parameter to SelectValues:
List(1,2){e => true}
This is equivalent to:
List(1,2)(f)
where f is the function. i.e. you are trying to call a function (apply in this case) on the resulting object from List(1,2) and not sending the second parameter (sel)).
the compiler analyzes first the SelectValues signature (before figuring out what your object is) and sees only one parameter.
To solve this, simply add the missing comma:
println(SelectValues(List(1,2), {e => true}))

what is the difference between passing parameters () => T and just T

specifically, what is the difference for following two definitions:
def func(f: () => String) = f()
def func1(s: String) = s
I wrote some codes to test them, it seems they produce the same result; are those two definitions just the same in this scenario; or they do have some difference?
var x = 1
def f() = {
x = x + 1
s"$x"
}
println(func1(f))
println(func1(f))
println(func1(f))
println(func(f))
println(func(f))
println(func(f))
They are perhaps the same in THIS scenario, but there are lots of other scenarios when a () => A and a A are much different. () => A is referred to as a thunk and is used to pass a piece of delayed computation to a function. The body of the "thunk" doesn't get evaluated until the function called decides to evaluate it. Otherwitse, the value of the argument being passed in is evaluated by the caller.
Consider this example, where there IS a difference between the version that takes a thunk and the version that just takes a value:
object Thunk {
def withThunk(f: () ⇒ String): Unit = {
println("withThunk before")
println("the thunk's value is: " + f())
println("now the thunk's value is: " + f())
}
def withoutThunk(f: String): Unit = {
println("withoutThunk before")
println("now the value's value is: " + f)
}
def main(argv: Array[String]): Unit = {
withThunk { () ⇒ println("i'm inside a thunk"); "thunk value" }
println("------------")
withoutThunk { println("i'm not inside a thunk"); "just a value" }
}
}
This program will demonstrate some differences. In the thunk version, you see "withThunk before" get printed before the first time "i'm inside a thunk" gets printed, which gets printed twice, since f() is evaluated twice. In the non-thunk version, the "I'm not inside a thunk" gets printed before "withoutThunk before", since this is evaluated before being sent to the function as an argument.
def func(f: () => String) = f()
This one accepts as parameter a function that returns a string.
def func1(s: String) = s
While this one simple requires a String as parameter
Aside from the minor technical difference above, in this scenario they seem to function the same. However, the function parameter is potentially more powerful as it is a function that can derive its return value from several other operations. I think however, the main difference that the function parameter allows you to decide when the value is derived.
def func(f: () => String) = f()
def func1(s: String) = s
println(func1(f)) // in this case f is evaluated first, its value is used in func1.
println(func(f)) // in this case f is NOT evaluated, but passed as it is to func.
// It is upto func to call f whenever needed, or even not call it.
It is this "lazy" evaluation of f, that makes func more useful, for instance f can be passed to some other higher order functions, or it can be called asynchronously.
I want to add an example for the use of () => String.
def printFuncResult(f: () => String) = println(f() + " " + f())
def ran = () => Math.random.toString
printFuncResult(ran)
printFuncResult(Math.random.toString)
When you pass a function like ran then you will most likely have two different values printed (randomness is involved here). When you pass a fixed Random number then it will be printed twice.
As you can see: when you have a function as a parameter it might result in a different value each time it is used in printFuncResult. This is not possible when you just put a String parameter.

Scala, passing a locally defined function into a list?

I have not understood the following code snippet why afterDelay(0) {...}, a locally defined function can be stored into agenda? Can someone help me understand the afterDelay(0) {...} in the run function?
abstract class Simulation {
type Action = () => Unit
case class WorkItem(time: Int, action: Action)
private var curtime = 0
def currentTime: Int = curtime
private var agenda: List[WorkItem] = List()
private def insert(ag: List[WorkItem], item: WorkItem): List[WorkItem] = {
if (ag.isEmpty || item.time < ag.head.time) item :: ag
else ag.head :: insert(ag.tail, item)
}
def afterDelay(delay: Int)(block: => Unit) {
val item = WorkItem(currentTime + delay, () => block)
agenda = insert(agenda, item)
}
private def next() {
(agenda: #unchecked) match {
case item :: rest =>
agenda = rest
curtime = item.time
item.action()
}
}
def run() {
afterDelay(0) {
println("*** simulation started, time = "+
currentTime +" ***")
}
while (!agenda.isEmpty) next()
}
}
afterDelay(0) {
println(...)
}
Is equivalent to the following:
afterDelay(0)({
println(...)
})
The function afterDelay is invoked a new WorkItem (item) is added to the list, not the function itself. The parameter block: => Unit is a "By-Name Parameter" (see the Scala Language Specification section 4.6.1): the expression used as the argument is implicitly converted into a "parameterless method" (without being evaluated first) that will be invoked whenever the variable inside the method is accessed (no () required).
In this case that is when the function resulting from () => block is invoked: it is invoked at item.action() which occurs at some point after the new WorkItem is added to the list (and afterDelay returns).
If it was written as (taking in a function paramater, not a by-name/thunk):
def afterDelay(delay: Int)(block: () => Unit) { // take a function
// new function will invoke function named by "block" when invoked ...
val item = WorkItem(..., () => block())
// or skip wrapping the function in a function ...
// val item = WorkItem(..., block)
...
}
Then it would need to be invoked passing in a function:
afterDelay(0)(() => { // need a function
println(...)
})
Or, alternative syntax, still a function of () => Unit, but the outside parenthesis can be avoided:
afterDelay(0) { () => // need a function
println(...)
}
Extract from the SLS, 4.6.1 By-Name Parameters:
The type of a value parameter may be prefixed by =>, e.g. x: => T. The type of such a parameter is then the parameterless method type => T. This indicates that the corresponding argument is not evaluated at the point of function application, but instead is evaluated at each use within the function. That is, the argument is evaluated using call-by-name.
You defined afterDelay as a curried function. This means it has two parameter lists. In scala you can replace the brackets surounding the parameterlist (...) with {...}. In the second parameterlist you are using a "call-by-name" parameter. Those parameters are evaluated everytime again you use them in your function. A good Example is here.
"Call-by-name" parameters are often used to define your own controlling structure.
def do(until: Int)(body: => Unit) {
body
if (until > 1) do(until - 1)(body)
}
do(0)(println("test"))
do(5)(println("test2"))
This is an example for a do until. It will print once test and five times test2.