I'm trying to learn Scala and the Play Framework at the same time. Scala looks to me like it has a lot of really cool ideas, but one of my frustrations is trying to understand all of the different syntaxes for methods/functions/lambdas/anonymous functions/etc.
So I have my main application controller like so:
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
This tells me I have a singleton Application that has one method, index, that returns what type?? I was expecting index to have a definition more like:
def index(req: Request) : Result = { ... }
Looking at Play Framework's documentation, it looks as though Action is a trait, that transforms a request to a result, by I'm having a hard time understanding what this line is saying:
def index = Action { ... }
I come from a Java background, so I don't know what this is saying? (this statement feels like it's saying "method index = [some interface Action]", which doesn't make sense to me; it seems something beautiful is happening, but it is magic to me, and I feel uneasy with magic in my code ;))
When you invoke an object as if it were a function, that's translated into a call to apply. I.e.:
foo(bar)
is translated into
foo.apply(bar)
So, inside index you are calling the Action object as if it were a function, which means you are actually calling Action.apply.
The return type of index is omitted because the compiler can infer it to be the return type of Action.apply (which I guess from the name is Unit).
So the short answer to this question is that there's some stuff going on behind the scenes that makes the above work: namely that the compiler is inferring types, and in Scala, objects with an apply method can get called as if they were functions.
So what's going on here is that this code:
def index = Action {
Ok("Hello World!")
}
...is equivalent to (or rather shorthand for) this code:
def index : Action[AnyContent] = Action.apply(
(req: Request[AnyContent]) => {
Ok(views.html.index("Hello World!"))
} : Result
)
The magic is happening here: ... = Action {...}. Action {...} says "call Action with this anonymous function {...}".
Because Action.apply is defined as apply(block: => Result): Action[AnyContent], all of the argument-/return- types can be inferred.
Related
The following trivial Kotlin code snippet
fun main() {}
compiles just fine, but the following
val main : () -> Unit = {}
makes the compiler complain that "No main method found in project.", while I was expecting them to be equivalent (I expect a programming language to be as conceptually uniform as possible).
Why does this happen? Is it related only to main, or does this behaviour concern a larger class of functions? Is there some subtle difference between declaring functions with "fun" and declaring them as lambdas?
Conceptually, they are different things. To see that, let's take a look at roughly what the equivalent Java would be. I'll use JVM for examples in this answer, but the same principles apply to all of the other Kotlin backends.
object Foo {
fun main() { ... }
}
This is roughly
class Foo {
public static void main() { ... }
}
Again, roughly. Technically, you'll get a singleton object and a method on it unless you use #JvmStatic (I assume there's some special handling for main that produces a static function on JVM, but I don't know that for a fact)
On the other hand,
object Foo {
val main: () -> Unit = { ... }
}
Here, we're declaring a property, which in Java is going to get implemented as a getter-setter pair
class Foo {
// Singleton instance
public static Foo instance = new Foo();
public Supplier<Void> main;
Foo() {
main = new Supplier<Void>() {
Void get() {
...
}
}
}
}
That is, there isn't actually a main method. There's a main field which, deep down somewhere, has a function inside of it. In my example above, that function is called get. In Kotlin, it's called invoke.
The way I like to think of it is this. Methods in Kotlin (i.e. the things you define on objects that designate their behavior) are not themselves first-class objects. They're second-class citizens which exist on an object. You can convert them to first-class objects by making them into functions. Functions are ordinary objects, like any other. If you take an ordinary object, which may or may not be a function, and call it with (), then you're actually invoking the method .invoke(...) on it. That is, () is an operator on objects which really ends up calling a method. So in Kotlin, functions are really just objects with a custom invoke and a lot of syntax sugar.
Your val defines a field which is a function. Your fun defines a method. Both of these can be called with (), but only one is a genuine method call; the other is secretly calling .invoke on another object. The fact that they look syntactically the same is irrelevant.
As the old adage goes, functions are a poor man's objects, and objects are a poor man's functions.
There is a subtle (or more than subtle) difference. Declaring it with val means that main is a property containing a reference to an anonymous function (which you defined with the lambda). If you define it with val, then when you call main(), you are actually calling the getter of the main property, and then using the invoke() operator to call invoke() on the return value of the property (the anonymous function).
In ES6, I want to do something like
class Foo extends Bar {
#Map('toCall')
someFunction() {
...
}
}
and later
foo = new Foo();
Foo.MAGIC_LOOKUP_TABLE['toCall'](foo);
in order to effectively call foo.someFunction();.
The intended use case is to let the programmer in charge of Foo dictate which function should be called only with a decorator change.
However, when writing:
export function Map(str) {
return function(target, name, descriptor) {
// ???
};
}
I can not for the life of me figure out how to get anything like Foo where you see ??? above. target seems to be a prototype value shared by all subclasses of Bar that attempt to use #Map.
How can I best achieve this? I do not want the author of Foo's javascript file to have to know about MAGIC_LOOKUP_TABLE, but instead to merely annotate the method to be called.
I'm working on a scala object in order to perform some testing
My start object is as follows
object obj1 {
def readvalue : IO[Float] = IO{
scala.io.StdIn.readFloat()
}
}
The testing should be
1- value of type FLOAT
2- should be less than 3
As we can not mock singleton objects I've used mocking functions here is what I've done.
class FileUtilitiesSpec
extends FlatSpec
with Matchers
with MockFactory
{
"value" should "be of Type Float" in {
val alpha = mockFunction[() => IO[Float]]
alpha.expects shouldBe a[IO[Float]]
}
"it" should "be less than 3" in {
val alpha = mockFunction[() => IO[Float]]
alpha.expects shouldBe <(3)
}
}
Im getting an error saying that :
MockFunction0-1() once (never called - UNSATISFIED) was not an instance of cats.effect.IO, but an instance of org.scalamock.handlers.CallHandler0
ScalaTestFailureLocation: util.FileUtilitiesSpec at (FileUtilitiesSpec.scala:16)
Expected :cats.effect.IO
Actual :org.scalamock.handlers.CallHandler0 ```
I would recommend reading the examples here as a starting point: https://scalamock.org/quick-start/
Using mock objects only makes sense if you are planning to use them in some other code, e.g. dependencies you do not want to make part of your module under test, or are beyond your control.
An example might be a database connection where you would depend on an actual system, making the code hard to test without simulating it.
The example you provided only has mocks, but no code using it, hence the error you are getting is absolutely correct. The mock expects to be used, but was not called.
The desired behaviour for a mocking library in this case is to make the test fail as the developer intended for this interaction with a mock to happen, but it was not recorded - so something is wrong.
I want to send slick table as part of the akka actor message . So that the remote actor at the other end can connect to the database and can do CRUD operations on the mysql database. Am unable to get my head over the slick types and i find compiler/eclipse complaining. How can i get this done. Is it a good idea to pass slick queries as part of actor messages.
object RemoteActorMessages {
case class Create(table: Table[A])
case class RunQuery(query: Query[_, _, _])
case Result(code: Int, message: String)
}
class DBActor extends Actor {
def recieve = {
case Create(table) => createTable(table)
case RunQuery(query) => runQuery(query)
case ... //so on
}
}
def createTable(table: Table[M]): Future[A] = Future {
db.withSession(implicit session => tableQuery[table].ddl.create)
}
def runQuery(query: Query[_, _, _]): Future[A] = Future {
db.withSession { implicit session => {
query.run
}
}
}
warning: code might have some type errors.Discretion is appreciated from the viewers
I am confused about how to send results back to the sender of the messages. for example: query.list.run gives back list of model objects. So, how should i frame by Result message
I think this is a case of 'when you have a hammer everything becomes nails'. I believe this is not the right use case for the actors. A reason (not the only one) would be that DB operations are 'slow' and they would block the actor threads for a long time.
Arguably you want a service that manages the table operations, using Futures and a custom Execution Context to isolate the impact (for example, in Play is done like this). Something like:
object DBService {
def createTable() : Future[Boolean] = ???
...
}
Actors should only receive commands like CreateTable that then call the corresponding method in the service.
Incidentally, this would simplify your use case as the service could know more about the table and other Slick specifics, whilst the actor would be oblivious to them.
Not the only way, but arguably simpler.
I would like to create a smart recursion prevention mechanism. I would like to be able to annotate a piece of code somehow, to mark that it should not be executed in recursion, and if it is indeed executed in recursion, then I want to throw a custom error (which can be caught to allow executing custom code when this happens)
Here is my attempt until here:
import scala.collection.mutable.{Set => MutableSet, HashSet => MutableHashSet }
case class RecursionException(uniqueID:Any) extends Exception("Double recursion on " + uniqueID)
object Locking {
var locks:MutableSet[Any] = new MutableHashSet[Any]
def acquireLock (uniqueID:Any) : Unit = {
if (! (locks add uniqueID))
throw new RecursionException(uniqueID)
}
def releaseLock (uniqueID:Any) : Unit = {
locks remove uniqueID
}
def lock1 (uniqueID:Any, f:() => Unit) : Unit = {
acquireLock (uniqueID)
try {
f()
} finally {
releaseLock (uniqueID)
}
}
def lock2[T] (uniqueID:Any, f:() => T) : T = {
acquireLock (uniqueID)
try {
return f()
} finally {
releaseLock (uniqueID)
}
}
}
and now to lock a code segment I do:
import Locking._
lock1 ("someID", () => {
// Custom code here
})
My questions are:
Is there any obvious way to get rid of the need for hard coding a unique identifier? I need a unique identifier which will actually be shared between all invocations of the function containing the locked section (so I can't have something like a counter for generating unique values, unless somehow scala has static function variables). I thought on somehow
Is there any way to prettify the syntax of the anonymouse function? Specifically, something that will make my code look like lock1 ("id") { /* code goes here */ } or any other prettier look.
A bit silly to ask in this stage, but I'll ask anyway - Am I re-inventing the wheel? (i.e. does something like this exist?)
Wild final thought: I know that abusing the synchronized keyword (at least in java) can gaurantee that there would be only one execution of the code (in the sense that no multiple threads can enter that part of the code at the same time). I don't think it prevents from the same thread to execute the code twice (although I may be wrong here). Anyway, if it does prevent it, I still don't want it (even thoug my program is single threaded) since I'm pretty sure it will lead to a deadlock and won't report an exception.
Edit: Just to make it clearer, this project is for error debugging purposes and for learning scala. It has no real useage other than easily finding code errors at runtime (for detecting recursion where it shouldn't happen). See the comments to this post.
Not quite sure what you're aiming at, but a few remarks:
First, you do not need to do lock1 and lock2 to distinguish Unit and the other type. Unit is a proper value type, the generic method will work for it too. Also, you should probably use a call by name argument => T, rather than a function () => T, and use two argument lists:
def lock[T] (uniqueID:Any)(f: => T) : T = {
acquireLock (uniqueID)
try {
f
} finally {
releaseLock (uniqueID)
}
}
Then you can call with lock(id){block} and it looks like common instructions such as if or synchronized.
Second, why do you need a uniqueId, why make Lock a singleton? Instead, make Lock a class, an have as many instances as you would have had ids.
class Lock {
def lock[T](f: => T): T = {acquireLock() ...}
}
(You may even name your lock method apply, so you can just do myLock{....} rather than myLock.lock{...})
Multithreading aside, you now just need a Boolean var for acquire/releaseLock
Finally, if you need to support multithreading, you have to decide whether several thread can enter the lock (that would not be recursion). If they can, the boolean should be replaced with a DynamicVariable[Boolean] (or maybe a java ThreadLocal, as DynamicVariable is an InheritableThreadLocal, which you may or may not want). If they cannot, you just need to synchronize access in acquire/releaseLock.
Is there any obvious way to get rid of the need for hard coding a unique identifier?
Since for what you said on the comments this is not prod code, I guess you could use the functions hashCode property like this:
def lock1 (f:() => Unit) : Unit = {
acquireLock (f.hashCode)
try {
f()
} finally {
releaseLock (f.hashCode)
}
Is there any way to prettify the syntax of the anonymouse function?
With the before-mentioned change the syntax should be prettier:
lock1 {
If you're planning on keeping the identifier (if hashcode doesn't cut it for you) you can define your method like this:
def lock1 (uniqueID:Any)(f:() => Unit) : Unit = {
That will let you call the lock1 method with:
lock("foo") {
}
Cheers!