How do I implement a JavaScript-style callback? - callback

I'm trying to implement a JavaScript-style callback. I have an application that uses a library (both are mine) and I need the application to be able to pass a closure or function to a method in the library, which then spawns a thread and inside the thread when a condition is met it will call the callback.
main.rs
fn main(){
welcome_message();
mylib::connect(|| println!("Connected to service! Please enter a command. (hint: help)\n\n"));
loop {
match prompt_input() {
true => {},
false => break,
}
}
}
lib.rs
pub fn connect<F>(resolve: F) -> (mpsc::Sender<Message>, mpsc::Receiver<Message>)
where F: Fn()
{
...
let receive_loop = Thread::scoped(move || {
for response in receiver.incoming_messages::<Message>(){
let json_string = match response.unwrap() {
Message::Text(txt) => txt,
_ => "".to_string(),
};
let message = json::Json::from_str(json_string.as_slice());
let message_json = message.unwrap();
if message_json.is_object() {
let ref something = receiver_tx;
let obj = message_json.as_object().unwrap();
let something_json = obj.get("lsri").unwrap();
let something = something_json.to_string().replace("\"", "");
match something.as_slice() {
"service#connected" => resolve(),
_ => println!("{}", type),
}
} else {
println!("Invalid service response");
}
}
});
...
}
Error
src/lib.rs:54:24: 54:38 error: the trait `core::marker::Send` is not implemented for the type `F` [E0277]
src/lib.rs:54 let receive_loop = Thread::scoped(move || {
^~~~~~~~~~~~~~
src/lib.rs:54:24: 54:38 note: `F` cannot be sent between threads safely
src/lib.rs:54 let receive_loop = Thread::scoped(move || {
^~~~~~~~~~~~~~
It doesn't need to be a closure that I pass, I could pass a function too. It doesn't need any arguments or return types, but I could add some dummy ones if that helps. I am VERY open to suggestions of other methods or ways to accomplish the same goal.
I have tried using:
Thread::spawn
FnMut()
Arc::new(resolve) (with implementation of .clone())
Arc::new(Mutex::new(resolve)) (with implementation of .lock())
Searching Google for examples
Reading the Rust book in it's entirety
Searching the error message for examples
All of the above in various configurations
Is this possible with Rust? Is there a better way?
Thank you for your time in advance.
Solution:
For anyone finding this in the future, per the instructions of the answer below I changed the signature of connect to the following, which allowed the callback to be passed into the thread.
pub fn connect<'a, T, F>(resolve: F) -> (mpsc::Sender<Message>, mpsc::Receiver<Message>)
where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a

Try marking your F with the same restrictions as Thread::scoped:
fn scoped<'a, T, F>(f: F) -> JoinGuard<'a, T>
where T: Send + 'a, F: FnOnce() -> T, F: Send + 'a
specifically, bounding the type with the Send trait should clear the immediate error of
the trait core::marker::Send is not implemented for the type F

Related

Can a function operating upon mutable data structure be referentially transparent?

I'm working on an network application and designed the following trait to read files from remote machines:
trait ReadFileAlg[F[_], Dataset[_], Context]{
def read(path: String, ctx: Context): F[Dataset[String]]
}
final class NetworkContext{
private var fileDescriptor: Int = _
private var inputStream: InputStream = _
//etc
}
final class ReadFromRemoteHost[F[_]: Sync] extends ReadFileAlg[F, List, NetworkContext]{
override def read(path: String, ctx: NetworkContext): F[List[String]] = Sync[F].delay(
//read data from the remote host
)
}
The problem I see here is that the implementation accepts NetworkContext as a paramenter which is mutable and contains fields like fileDescriptor which is related to a network connection.
Is this function read referentially transparent?
I think yes, because the function itself does not provide direct access to a mutable state (it is under Sync[F].delay) even though it accepts mutable data structure as an argument.
IMO, the semantics of read are
"When you apply me I am pure, however when you run me I have a
side-effect."
Some say this is a kind of sleight of hand:
...we simply declare that a function returning an IO type may have
arbitrary effects without going into detail in how these come about.
The scheme has two consequences: First, the type of a function tells
you whether it is referentially transparent or has side-effects when
run.
For example, consider the following object with mutable state
object Foo {
var x = 42
}
def f(foo: Foo.type): Int = foo.x
We can confirm f is not referentially transparent because
assert(f(Foo) == 42) // OK
assert(f(Foo) == 42) // OK
...
Foo.x = -11
...
assert(f(Foo) == 42) // boom! Expression f(Foo) suddenly means something else
However re-implementing f to "suspend" the effect
def f(foo: Foo.type): IO[Int] = IO(foo.x)
which is similar to
def f(foo: Foo.type): Unit => Int = _ => foo.x
then
magicalAssert(f(Foo) == (_ => foo.x)) // OK
magicalAssert(f(Foo) == (_ => foo.x)) // OK
...
Foo.x = -11
...
magicalAssert(f(Foo) == (_ => foo.x)) // Still OK! Expression f(Foo) did not change meaning
Here magical assert is like human brain and does not suffer from halting problem so is able to deduce equality of function behaviour, that is, applying f evaluates to value (_ => foo.x) which is indeed always equal to value (_ => foo.x) even though at some point Foo.x was mutated to -11.
However, running f's effect we have
assert(f(Foo)() == 42) // OK
assert(f(Foo)() == 42) // OK
...
Foo.x = -11
...
assert(f(Foo)() == 42) // boom! expression f(Foo)() suddenly means something else
(Note how we are simulating IO.run via extra parentheses in f(Foo)())
Hence expression f(Foo) is referentially transparent, however expression f(Foo)() is not.

Scala accessing variable outside function

I was reading an article at https://medium.com/#aarshkshah1992/scala-functional-memoization-and-lazy-loading-caches-de116f24828
and this part is really interesting
def memoizedIsPrime: Int => Boolean = {
def checkIfPrime(i: Int): Boolean = {
2 to (i - 1) forall (x => i % x != 0)
}
var cache = Map.empty[Int, Boolean]
i => {
if (!cache.contains(i)) {
print(s"Calling isPrime since input ${i} has not been seen before and caching the output")
cache = cache updated(i, checkIfPrime(i))
}
else print(s"Input ${i} has been seen before , returning cached output")
cache(i)
}
}
val isPrime = memoizedIsPrime
Can anyone explain how i is being accessed and the how the code part after => is really working?
Thanks in advance :)
The result of memoizedIsPrime is Int => Boolean, in other words a function that takes an Int and returns a Boolean.
So in the body of the code, after we get some preliminary def and val definitions out of the way, we need a way to reference the incoming Int:
i => ...
OK, so it is decided, we'll refer to the received Int as i. Now we need to produce a Boolean value. And that, of course, is the { } delimited block of code that comes after the => which gets executed every time a new Int arrives.

Producing a partially applied function from method of type in an Option

Suppose I'm writing a GUI
class Kitteh (val age: Int) {
require (age < 5)
def saveMeow(file: File) = { /* implementation */ }
def savePurr(file: File) = { /* implementation */ }
}
The frame has a field for the current Kitteh, which is an Option because it might not have been defined yet, or the user may have attempted to create an invalid one:
var currentKitteh: Option[Kitteh] = None
Now I want to create a Kitteh safely when the user hits Create
val a = ... // parse age from text box
currentKitteh = try { Some(new Kitteh(a)) } catch { case _ => None }
My GUI has two buttons which do similar things. In psedocode, they should both
if (currentKitteh.isDefined) {
if (file on the disk already exists) {
bring up a dialog box asking for confirmation
if (user confirms)
<< execute method on currentKitteh >>
}
}
else bring up warning dialog
Don't worry about the detail: the point is that because there is code duplication, I want to create a common method that I can call from both buttons. The only difference is the method on the Kitteh that needs to be executed.
Now if currentKitteh were not an Option, the common method could have a signature like
def save(filename: String, f:(File => Unit)) {
which I could call with, for example
save("meow.txt", currentKitteh.saveMeow _)
but since it is actually an Option, how could I implement this?
I could just check whether currentKitteh is defined, and do a .get before calling the save method for each button, but is there another way, leaving this check in the save method? In other words, given an Option[A], is it possible to specify a partial function from a method on the (possibly non-existent) A object?
(hope this question makes sense, convoluted example notwithstanding)
edit: Bonus question: what if, instead of Option[Kitteh], I used Either[Throwable, Kitteh]?
update: Additional line added to pseudocode to bring up warning dialog: ideally, the save method should always be called so that the user is warned if there is no valid Kitteh to save.
This looks like the best option to me:
currentKitteh foreach { c => save("meow.txt", c.saveMeow _) }
If you're repeatedly doing this, you can abstract it,
def currentSaveMeow(file: String) = currentKitteh foreach { c =>
save(file, c.saveMeow _)
}
currentSaveMeow("meow.txt")
I suppose to answer your original question, you could also push the logic into the function argument,
save("meow.txt", file => currentKitten.foreach(_.saveMeow(file)))
The semantics are a little different with this version.
Update. If k: Option[Kitteh] is replaced by k: Either[Throwable, Kitteh], then what about k.right foreach { c => ... }? You could also use k.right map ... if you want to preserve error information.
In response to the modified question, here's another abstraction possibility,
def save(filename: String, f: (Kitteh, File) => Unit)
Now save has the responsibility of unpacking currentKitteh. Call save like this,
save("meow.txt", (k, f) => k.saveMeow(f))
or like this,
save("meow.txt", _ saveMeow _)
You can map a function to it and getOrElse your fail function:
def save =
o map {s => () => "saved a kitteh! " + s} getOrElse {() => "oh noes, no kittehs!"}
then you just:
save()
You could define a class BadKitteh and have that produce error messages. Then simply use currentKitty.getOrElse(badKitty) if you need one.

How do I create a partial function with generics in scala?

I'm trying to write a performance measurements library for Scala. My idea is to transparently 'mark' sections so that the execution time can be collected. Unfortunately I wasn't able to bend the compiler to my will.
An admittedly contrived example of what I have in mind:
// generate a timing function
val myTimer = mkTimer('myTimer)
// see how the timing function returns the right type depending on the
// type of the function it is passed to it
val act = actor {
loop {
receive {
case 'Int =>
val calc = myTimer { (1 to 100000).sum }
val result = calc + 10 // calc must be Int
self reply (result)
case 'String =>
val calc = myTimer { (1 to 100000).mkString }
val result = calc + " String" // calc must be String
self reply (result)
}
Now, this is the farthest I got:
trait Timing {
def time[T <: Any](name: Symbol)(op: => T) :T = {
val start = System.nanoTime
val result = op
val elapsed = System.nanoTime - start
println(name + ": " + elapsed)
result
}
def mkTimer[T <: Any](name: Symbol) : (() => T) => () => T = {
type c = () => T
time(name)(_ : c)
}
}
Using the time function directly works and the compiler correctly uses the return type of the anonymous function to type the 'time' function:
val bigString = time('timerBigString) {
(1 to 100000).mkString("-")
}
println (bigString)
Great as it seems, this pattern has a number of shortcomings:
forces the user to reuse the same symbol at each invocation
makes it more difficult to do more advanced stuff like predefined project-level timers
does not allow the library to initialize once a data structure for 'timerBigString
So here it comes mkTimer, that would allow me to partially apply the time function and reuse it. I use mkTimer like this:
val myTimer = mkTimer('aTimer)
val myString= myTimer {
(1 to 100000).mkString("-")
}
println (myString)
But I get a compiler error:
error: type mismatch;
found : String
required: () => Nothing
(1 to 100000).mkString("-")
I get the same error if I inline the currying:
val timerBigString = time('timerBigString) _
val bigString = timerBigString {
(1 to 100000).mkString("-")
}
println (bigString)
This works if I do val timerBigString = time('timerBigString) (_: String), but this is not what I want. I'd like to defer typing of the partially applied function until application.
I conclude that the compiler is deciding the return type of the partial function when I first create it, chosing "Nothing" because it can't make a better informed choice.
So I guess what I'm looking for is a sort of late-binding of the partially applied function. Is there any way to do this? Or maybe is there a completely different path I could follow?
Well, thanks for reading this far
-teo
The usual pattern when you want "lazy" generics is to use a class with an apply method
class Timer(name: Symbol) {
def apply[T](op: => T) = time(name)(op)
}
def mkTimer(name: Symbol) = new Timer(name)

Can you return an unevaluated function in scala?

Given this code:
def getFunc(funcName:String, param:Int) = match funcName {
case "FooFunc" => FooFunc(param)
[...]
}
def FooFunc(param:Int) = param + SomeObject.SomeVariable
How could I return FooFunc with param applied, without evaluating it? The reason I'd want to do this is because FooFunc, as you can see, relies on an external variable so I'd like to be able to call it with param already applied. What would the return type of getFunc need to be?
Easy:
def getFunc(funcName: String, param: Int) = funcName match {
case "FooFunc" => () => FooFunc(param)
[...]
}
Your method has a good name: getFunc is supposed to return a function, so it will.
The lazyness must be defined at the call site, in Scala. You can do:
lazy val x = getFunc(...) // getFunc only gets evaluated when needed
Or you can change the signature:
def FooFunc(param:Int) = () => param + SomeObject.SomeVariable
...
val x = getFunc(...) // x contains a function from Unit into something
x() // Use x here, causing the evaluation
You could add another void parameter, so the function is only evaluated when it is applied to this parameter.
Though I'd rather use a proper object instead of a function in this case.
I'm sure there's many options, but you can use:
return { Unit => FooFun(param) }