Replacing class keyword with actor causes an error - class

Here's my code:
class Eapproximator
var step : F64
new create(step' :F64) =>
step = step'
fun evaluate() :F64 =>
var total = F64(0)
var value = F64(1)
while total < 1 do
total = total + step
value = value + (value * step)
end
value
actor Main
new create(env: Env) =>
var e_approx = Eapproximator(0.00001)
var e_val = e_approx.evaluate()
env.out.print(e_val.string())
It works well and prints (as expected) 2.7183. However, if I replace class with actor in Eapproximator definition I get a bunch of errors:
Error:
/src/main/main.pony:18:34: receiver type is not a subtype of target type
var e_val = e_approx.evaluate()
^
Info:
/src/main/main.pony:18:17: receiver type: Eapproximator tag
var e_val = e_approx.evaluate()
^
/src/main/main.pony:6:3: target type: Eapproximator box
fun evaluate() :F64 =>
^
/src/main/main.pony:3:3: Eapproximator tag is not a subtype of Eapproxim
ator box: tag is not a subcap of box
new create(step' :F64) =>
^
Error:
/src/main/main.pony:19:19: cannot infer type of e_val
env.out.print(e_val.string())
What can I do to fix this?

The actor is the unit of concurrency in Pony. This means that many different actors in the same program can run at the same time, including your Main and Eapproximator actors. Now what would happen if the fields of an actor were modified by multiple actors at the same time? You'd most likely get some garbage value in the end because of the way concurrent programs work on modern hardware. This is called a data race and it is the source of many, many bugs in concurrent programming. One of the goals of Pony is to detect data races at compile time, and this error message is the compiler telling you that what you're trying to do is potentially unsafe.
Let's walk through that error message.
receiver type is not a subtype of target type
The receiver type is the type of the called object, e_approx here. The target type is the type of this inside of the method, Eapproximator.evaluate here. Subtyping means that an object of the subtype can be used as if it was an object of the supertype. So that part is telling you that evaluate cannot be called on e_approx because of a type mismatch.
receiver type: Eapproximator tag
e_approx is an Eapproximator tag. A tag object can neither be read nor written. I'll detail why e_approx is tag in a minute.
target type: Eapproximator box
this inside of evaluate is an Eapproximator box. A box object can be read, but not written. this is box because evaluate is declared as fun evaluate, which implicitly means fun box evaluate (which means that by default, methods cannot modify their receiver.)
Eapproximator tag is not a subtype of Eapproxim
ator box: tag is not a subcap of box
According to this error message, a tag object isn't a subtype of a box object, which means that a tag cannot be used as if it was a box. This is logical if we look at what tag and box allow. box allows more things than tag: it can be read while tag cannot. A type can only be a subtype of another type if it allows less (or as much) things than the supertype.
So why does replacing class with actor make the object tag? This has to do with the data race problems I talked about earlier. An actor has free reign over its own fields. It can read from them and write to them. Since actors can run concurrently, they must be denied access to each other's fields in order to avoid data races with the fields' owner. And there is something in the type system that does exactly that: tag. An actor can only see other actors as tag, because it would be unsafe to read from or write to them. The main useful thing it can do with those tag references is send asynchronous messages (by calling the be methods, or behaviours), because that's neither reading nor writing.
Of course, since you're not doing any mutation of Eapproximatorin your program, your specific case would be safe. But it is much easier to try to forbid every unsafe program than to try to allow every safe program in addition to that.
To sum it up, there isn't really a fix for your program, except keeping Eapproximator as a class. Not anything needs to be an actor in a Pony program. The actor is the unit of concurrency, but that means it is also the unit of sequentiality. Computations that need to be sequential and synchronous must live in a single actor. You can then break down those computations into various classes for good code hygiene.

Related

Unique symbol value on type level

Is it possible to have some kind of unique symbol value on the type level, that could be used to distinct (tag) some record without the need to supply a unique string value?
In JS there is Symbol often used for such things. But I would like to have it without using Effect, in pure context.
Well, it could even like accessing Full qualified module name (which is quite unique for the task), but I'm not sure if this is a really relevant/possible thing in the Purescript context.
Example:
Say There is some module that exposes:
type Worker value state =
{ tag :: String
, work :: value -> state -> Effect state
}
makeWorker :: forall value state. Worker value state
performWork :: forall value state. woker -> Worker value state -> value -> Unit
This module is used to manage the state of workers, it passes them value and current state value, and gets Effect with new state value, and puts in state map where keys are tags.
Users of the module:
In one module:
worker = makeWorker { tag: "WorkerOne", work }
-- Then this tagged `worker` is used to performWork:
-- performWork worker "Some value"
In another module we use worker with another tag:
worker = makeWorker { tag: "WorkerTwo", work }
So it would be nice if there would be no need to supply a unique string ("WorkerOne", "WorkerTwo") as a tag but use some "generated" unique value. But the task is that worker should be created on the top level of the module in pure context.
Semantics of PureScript as such is pure and pretty much incompatible with this sort of thing. Same expression always produces same result. The results can be represented differently at a lower level, but in the language semantics they're the same.
And this is a feature, not a bug. In my experience, more often than not, a requirement like yours is an indication of a flawed design somewhere upstream.
An exception to this rule is FFI: if you have to interact with the underlying platform, there is no choice but to play by that platform's rules. One example I can give is React, which uses the JavaScript's implicit object identity as a way to tell components apart.
So the bottom line is: I urge you to reconsider the requirement. Chances are, you don't really need it. And even if you do, manually specified strings might actually be better than automatically generated ones, because they may help you troubleshoot later.
But if you really insist on doing it this way, good news: you can cheat! :-)
You can generate your IDs effectfully and then wrap them in unsafePerformEffect to make it look pure to the compiler. For example:
import Effect.Unsafe (unsafePerformEffect)
import Data.UUID (toString, genUUID)
workerTag :: String
workerTag = toString $ unsafePerformEffect genUUID

#volatile usage unclear - sending an object with a `var` to another thread

I am not sure I use #volatile correctly here. I have a buffer, like this:
final class BufD(val buf: Array[Double], #volatile var size: Int)
Which is sent between processes, whereby it might cross thread boundaries. The sender may update the size field just before sending it out. Therefore I want to make sure that the receiver under no circumstances can see a stale size value here. First question: Does #volatile ensure this or is it redundant?
Now I am introducing a trait:
trait BufLike {
#volatile var size: Int
}
final class BufD(val buf: Array[Double], #volatile var size: Int) extends BufLike
This gives me a compiler warning:
Warning:(6, 4) no valid targets for annotation on method size - it is discarded unused. You may specify targets with meta-annotations, e.g. #(volatile #getter)
#volatile var size: Int
^
Second question: Should I remove the #volatile here or change it in a different way?
I assume thread-A creates, updates, then passes the object-X to thread-B. If object-X and whatever it refers to directly or transitively (fields) are no further updated by thread-A, then volatile is redundant. The consistency of the object-X state at the receiving thread is guaranteed by JVM.
In other words, if logical ownership for object-X is passed from thread-A to thread-B, then volatile doesn't make sense. Conversely, on modern multicore systems, the performance implications of volatile can be more than that of thread-local garbage left by immutable case classes.
If object-X is supposed to be shared for writing, making a field volatile will help to share its value, but you will face another problem: non-atomic updates on the object-X, if fields' values depend on each other.
As #alf pointed out, to benefit from happens-before guarantees, the objects must be passed safely! This can be achieved using java.util.concurrent.** classes. High level constructs like Akka define their own mechanisms of "passing" objects safely.
References:
https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
As #tair points out, the real solution to your problem is to use an immutable case class:
The sender may update the size field just before sending it out.
It seems that receiver does not update the size; neither does sender update the size after if has already sent the BufD out. So for all practical reasons, recipient is much better off receiving an immutable object.
As for #volatile, it ensures visibility—the writes are indeed hitting the main memory instead of being cached in the thread local cache, and the reads include a memory barrier to ensure that the value read is not stale.
Without #volatile, the recipient thread is free to cache the value (it's not volatile, hence it should not be changed from the other thread, hence it's safe to cache) and re-use it instead of referring to the main memory. (SLS 11.2.1, JLS §8.3.1.4)
#volatile Marks a field which can change its value outside the control of the program; this is equivalent to the volatile modifier in Java.
and
A write to a volatile field (§8.3.1.4) happens-before every subsequent read of that field.
The problem here is that either you don't need all that as the object is effectively immutable (and you're better off with a properly immutable one), or you want to see coordinated changes in buf and size on the recipient size. In the latter case, #volatile may be useful (while fragile), if writer appends (not overwrites!) to buf, and then updates the size. In this case, write to buf happens-before write to size, which in turn happens-before reader can read the updated value from size (by volatility), therefore if reader checks and re-checks the size, and writer only appends, you're probably fine. Having said that, I would not use this design.
As for the warning, it all compiles to Java, i.e. JVM, bytecode, and volatile is a JVM flag for fields. Traits cannot define a field—they only define methods, and it's up to the extending class to decide whether it'll be a proper variable or (a pair of) methods (SLS 4.2).
A variable declaration var x: T is equivalent to the declarations of both a getter function x and a setter function x_=:
def x: T
def x_= (y: T): Unit
A function cannot be #volatile, hence the warning.

Constraint a scala type such that I would never need to check for null?

def myMethod(dog: Dog) = {
require (dog != null) // is it possible to already constraint it in the `Dog` type?
}
Is there a way to construct Dog such that it would be an ADT which would never be able to accept a null thus eliminate any null check? (I don't want an Option here, otherwise all my code would turn to have Option based, I want to already constraint the Dog class such that null is never possible, this is why type system is for to allow me to specify constraints in my program).
There was an attempt to provide such functionality (example I'm running in 2.10.4):
class A extends NotNull
defined class A
val x: A = null
// <console>:8: error: type mismatch;
// found : Null(null)
// required: A
// val x: A = null
^
Though it was never complete and eventually got deprecated. As for the time of writing, I don't think it's possible to construct ones hierarchy in a way that prevent you from nulls, without additional nullity checking analysis.
Check out comments in relevant ticket for an insight
I don't think this is possible, generally, because Java ruins everything. If you have a Java method that returns Dog, that could give you a null no matter what language/type features you add to Scala. That null could then be passed around, even in Scala code, and end up being passed to myMethod.
So you can't have non-null types in Scala without losing the interoperability property that Scala objects are Java objects (at least for the type in question).
Unfortunately inheritance makes it very difficult for the computer to know in the general case whether a method could be passed an object that originated from Java - unless everything is final/sealed, you can always subclass a class that handled the object at some point, and override the Dog-returning method. So it requires hairy full-program analysis to figure out the concrete types of everything (and remember, which concrete types are used can depend on runtime input!) just to establish that a given case could not involve Java code.

akka sending a closure to remote actor

Background
i want to send a closure to a remote actor. remote actor should run the closure on its data and send back the result. May be it is not advisable, but for curiosity's sake that's i want to do now
But i observe that if a closure is created as an anonymous function, it captures the outer object also and tries to marshal it, which fails if the outer object is not serializable, as in this case.
class Client(server: ActorRef) extends Actor {
var every = 2
override def preStart() = {
println("client started. sending message....")
server ! new Message((x) => x % every == 0)
}
}
the above code generates exception while calling the remote actor. i could define a local variable in the method preStart()
val every_ = every
and use it in place of actor member variable. But i feel it is a workaround not a solution. and i will have to be very careful if the closure is any bit more complex.
Alternative is to define a class inheriting from Function1[A,B] and send its instances as closure.
class MyFunc(every : Int) extends Function1[Int,Boolean] with Serializable {
def apply(v1 :Int) : Boolean = {
v1 % every == 0
}
}
server ! new Message(new MyFunc(every))
But this separates the closure definition from the place it is used, and defeats the whole purpose of using a functional language. and also makes defining the closure logic more difficult.
Specific Query
Is there a way i can defer defining the body of the Function1.apply and assign the body of apply when i create the instance of MyFunc from a locally defined closure?
e.g.
server ! new Message(new MyFunc(every){ // not valid scala code
x % every == 0
})
where every is a local variable?
basically i want to combine the two approaches i.e. send an object of Function1 over to remote actor with the body of Function1 defined by an anon function defined in place where Function1 instance is created.
Thanks,
Sure, you could send behaviour to actor, but it considered to be a bad practice, and your questions is a good answer on question: "why".
As BGR pointed out there is special section in documentation on this question, but it has no example.
So, when you sending a closure as message you sending some extra "implicit" state with it. It could be not mutable as said in documentation, but even in this case it can create problems.
The problem with scala here is that it not strictly functional language - it is multiparadigm language. In other words you could have code in functional paradigm side by side with code in imperative style. There is no such problems in, for example haskell, which is purely functional.
In case of your "specific query" I'll suggest you to use set of predefined functions. This is full equivalent of variant with closures but with a bit chatty syntax. Since you do not generate code during runtime all functions you use are defined in limited set and (looks like) parameterized by value. This makes your code not so flexible like with closures, but in the end it will be equivalent cases.
So, as a leitmotif of all my post: if you going to send behaviour to actor it should be rock solid atomic (in meaning have no any dependencies)

Automatic casting in Scala

I have a class that inherits the Actor trait. In my code, I have a method that creates x numbers of this actor using a loop and another method that simply sends the Finish message to all of them to tell them to terminate. I made the kill method just take an array of Actor since I want to be able to use it with an array of any type of Actor. For some reason, however, when I pass a value of type Array[Producer], where Producer extends Actor, to a method that accepts the type Array[Actor], I get a type error. Shouldn't Scala see that Producer is a type of Actor and automatically cast this?
What you are describing is called covariance, and it is a property of most of the collection classes in Scala--a collection of a subtype is a subtype of the collection of the supertype. However, since Array is a Java primitive array, it is not covariant--a collection of a subtype is simply different. (The situation is more complicated in 2.7 where it's almost a Java primitive array; in 2.8 Array is just a plain Java primitive array, since the 2.7 complications turned out to have unfortunate corner cases.)
If you try the same thing with an ArrayBuffer (from collection.mutable <- edit: this part is wrong, see comments) or a List (<- edit: this is true) or a Set (<- edit: no, Set is also invariant), you'll get the behavior you want. You could also create an Array[Actor] to begin with but always feed it Producer values.
If for some reason you really must use Array[Producer], you can still cast it using .asInstanceOf[Array[Actor]]. But I suggest using something other than primitive arrays--anything you could possibly be doing with actors will be far slower than the tiny overhead of using a more full-featured collection class.