Storing an anonymous function passed as a parameter in a Map - scala

I'm trying to implement a simple web application server as a personal project to improve my Scala, but I've hit upon a problem.
I'd like to be able to set up routes using code like the following:
def routes()
{
get("/wobble")
{
...many lines of code here...
}
get("/wibble")
{
...many lines of code here...
}
post("/wibble")
{
...many lines of code here...
}
post("/wobble")
{
...many lines of code here...
}
}
routes is called by the server when it starts and get and post are functions defined by me like this:
get(url:String)(func:()=>String)=addroute("GET",url,func)
post(url:String(func:()=>String)=addroute("POST",url,func)
addroute(method:String,url:String,f:()=>String)
{
routesmap+=(method->Map[String,()=>String](url,func))
}
Unfortunately, I've had nothing but problems with this. Could anyone tell me the correct way in Scala to add an anonymous function (as passed in as a parameter in the defined routes function above) to a Map (or any other Scala collection for that matter)?

Here is a working example:
scala> var funcs = Map[String,(Int)=>Int]()
funcs: scala.collection.immutable.Map[String,Int => Int] = Map()
scala> funcs += ("time10", i => i * 10 )
scala> funcs += ("add2", i => i + 2 )
scala> funcs("add2")(3)
res3: Int = 5
scala> funcs("time10")(10)
res4: Int = 100
You can also add a declared function:
val minus5 = (i:Int) => i - 5
funcs += ( "minus5", minus5)
Or a method:
def square(i: Int) = i*i
funcs += ("square", square)
In your case, you can have two maps, one for GET and one for POST. It should simplify the design (and at most, you will end with four maps if you include DEL and PUT).

May be, this one ? :
type Fonc = ( (=> String) => Unit)
var routesmap = Map[String,Map[String,()=>String]]()
def addRoute(method:String,url:String,f:()=>String) = {
routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))
}
def get(url:String):Fonc = (x => addRoute("GET",url,() => x))
def post(url:String):Fonc = (x => addRoute("POST",url,() => x))
def routes()
{
post("/wobble")
{
"toto"
}
get("/wibble")
{
"titi"
}
}

you can try this code :
def addRoute(method:String,url:String,f:()=>String) = {
routesmap+=(method-> (routesmap.getOrElse(method,Map[String,()=>String]()) + (url->f)))
}
def get(url:String,func:()=>String)= addRoute("GET",url,func)
def post(url:String,func:()=>String)= addRoute("POST",url,func)
def routes()
{
get("/wobble",()=>{"toto"})
get("/wibble",()=>{println("test")
"titi"})
}
and execute these commands
scala> routes
scala> routesmap.get("GET").get("/wibble")()

Related

Is there a way to use map-like syntax for setting variables in non-map code blocks in Scala? [duplicate]

This question already has answers here:
Chaining operations on values without naming intermediate values
(2 answers)
Closed 2 years ago.
I am often writing code where I want to evaluate an expression and then pass the result of that expression down to the next block of code as a variable using syntax similar to that used with a map or fold expression.
The sort of code that I want to write would look something like we do with an Option or Future:
Some("foo") map { upper => s"works with $upper"}
but without objects that support map.
A good example (but not the only one) is doing replacement of Json elements in with the spray libraries. Something like:
JsObject(upper.fields +
("obj" -> JsObject(
upper.fields("obj").asJsObject { lower: JsObject => lower.fields +
("data" -> JsObject(lower.fields("data")))
}
))
)
Is there a way to accomplish this without resorting to nesting matches?
Answer 1: Here is an example using the mouse library with Scala 2.12:
def withMouse(upper: JsObject): JsObject = {
upper
.|> { upper => println(upper.compactPrint); upper.fields; }
.|> { upper => upper + ("obj" ->
upper("obj").asJsObject.fields
.|> { lower => JsObject(lower + ("data" ->
lower("data")
))}
)}
.|> { newmsg => JsObject(newmsg) }
}
Answer 2: Here is the same example using the ChainingOps library's .pipe method with Scala 2.13
def withPipe(upper: JsObject): JsObject = {
upper
.pipe { upper => println(upper.compactPrint); upper.fields; }
.pipe { upper => upper + ("obj" ->
upper("obj").asJsObject.fields
.pipe { lower => JsObject(lower + ("data" ->
lower("data")
))}
)}
.pipe { newmsg => JsObject(newmsg) }
}
It sounds like you want pipe().
From the ScalaDocs page:
import scala.util.chaining._
val times6 = (_: Int) * 6
//times6: Int => Int = $$Lambda$2023/975629453#17143b3b
val i = (1 - 2 - 3).pipe(times6).pipe(scala.math.abs)
//i: Int = 24
If not on Scala 2.13, there exists mouse which provides similar chaining operators, for example,
input
.<| { println }
.<| { preconditions }
.thrush { program }
.<| { postconditions }
.<| { println }
where
import mouse.all._
import scala.io.StdIn
case class User(name: String, age: Int, previous: Option[User] = None) {
def changeName(newName: String): User =
this.copy(name = newName, previous = Some(this))
}
def preconditions(user: User): Unit = {
assert(user.name.nonEmpty, "User should have a name")
assert(user.age >= 0, "User's age should not be negative")
}
def postconditions(`new`: User): Unit = {
assert(
`new`.previous.exists(_.name != `new`.name),
"User should have changed their name details"
)
}
def program(user: User): User = {
println(s"Please enter new name for $user")
val newName = StdIn.readLine()
user.changeName(newName)
}
val input = User("Picard", 75)
Note how <| just executes side-effect, whilst thrush may transform.

How to save output of repeat loop in parquet file?

I have a word "hi" written in loop.
implicit class Rep(n: Int) {
def times[A](f: => A) { 1 to n foreach(_ => f) }
}
// use it with
130.times { println("hi") }
How to save output?
There are some bugs in your code, here is a correct one:
implicit class Rep(n: Int) {
def times[A](f: => A): Seq[A] = { 1 to n map(_ => f) }
}
// use it with
val myHis = 130.times { "hi" } // returns Vector(hi, hi, hi, hi, hi, ...)
add = otherwise the functions return type is Unit- always add the return type explicit in such cases (: Seq[A]) and the compiler would have helped you.
use map instead of foreach as foreach returns again Unit
println("hi") returns again Unit. The last statement is returned, so it must be the value you want.
To write a file of this:
new java.io.PrintWriter("filename") { write(myHis.mkString(", ")); close }
Be aware this simple example does not handle exception properly - but I think myHis.mkString(", ") is what you are looking for.

Avoiding the variable in "val x = foo; bar(x); x" [duplicate]

This question already has answers here:
Equivalent to Ruby's #tap method in Scala [duplicate]
(1 answer)
how to keep return value when logging in scala
(6 answers)
Closed 9 years ago.
Often I have functions like this:
{
val x = foo;
bar(x);
x
}
For example, bar is often something like Log.debug.
Is there a shorter, idiomatic way how to run it? For example, a built-in function like
def act[A](value: A, f: A => Any): A = { f(value); value }
so that I could write just act(foo, bar _).
I'm not sure if i understood the question correctly, but if i do, then i often use this method taken from the Spray toolkit:
def make[A, B](obj: A)(f: A => B): A = { f(obj); obj }
then you can write the following things:
utils.make(new JobDataMap()) { map =>
map.put("phone", m.phone)
map.put("medicine", m.medicine.name)
map.put("code", utils.genCode)
}
Using your act function as written seems perfectly idiomatic to me. I don't know of a built-in way to do it, but I'd just throw this kind of thing in a "commons" or "utils" project that I use everywhere.
If the bar function is usually the same (e.g. Log.debug) then you could also make a specific wrapper function for that. For instance:
def withDebug[A](prefix: String)(value: A)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
which you can then use as follows:
implicit val loggerI = logger
def actExample() {
// original method
val c = act(2 + 2, logger.debug)
// a little cleaner?
val d = withDebug("The sum is: ") {
2 + 2
}
}
Or for even more syntactic sugar:
object Tap {
implicit def toTap[A](value: A): Tap[A] = new Tap(value)
}
class Tap[A](value: A) {
def tap(f: A => Any): A = {
f(value)
value
}
def report(prefix: String)(implicit logger: Logger): A = {
logger.debug(prefix + value)
value
}
}
object TapExample extends Logging {
import Tap._
implicit val loggerI = logger
val c = 2 + 2 tap { x => logger.debug("The sum is: " + x) }
val d = 2 + 2 report "The sum is: "
assert(d == 4)
}
Where tap takes an arbitrary function, and report just wraps a logger. Of course you could add whatever other commonly used taps you like to the Tap class.
Note that Scala already includes a syntactically heavyweight version:
foo match { case x => bar(x); x }
but creating the shorter version (tap in Ruby--I'd suggest using the same name) can have advantages.

declare variable in custom control structure in scala

I am wondering if there is a way to create a temp variable in the parameter list of a custom control structure.
Essentially, I would like create a control structure that looks something like the
for loop where I can create a variable, i, and have access to i in the loop body only:
for(i<- 1 to 100) {
//loop body can access i here
}
//i is not visible outside
I would like to do something similar in my code. For example,
customControl ( myVar <- "Task1") {
computation(myVar)
}
customControl ( myVar <- "Task2") {
computation(myVar)
}
def customControl (taskId:String) ( body: => Any) = {
Futures.future {
val result = body
result match {
case Some(x) =>
logger.info("Executed successfully")
x
case _ =>
logger.error(taskId + " failed")
None
}
}
}
Right now, I get around the problem by declaring a variable outside of the custom control structure, which doesn't look very elegant.
val myVar = "Task1"
customControl {
computation(myVar)
}
val myVar2 = "Task2"
customControl {
computation(myVar2 )
}
You could do something like this:
import scala.actors.Futures
def custom(t: String)(f: String => Any) = {
Futures.future {
val result = f(t)
result match {
case Some(x) =>
println("Executed successfully")
x
case _ =>
println(t + " failed")
None
}
}
}
And then you can get syntax like this, which isn't exactly what you asked for, but spares you declaring the variable on a separate line:
scala> custom("ss") { myvar => println("in custom " + myvar); myvar + "x" }
res7: scala.actors.Future[Any] = <function0>
in custom ss
ss failed
scala> custom("ss") { myvar => println("in custom " + myvar); Some(myvar + "x") }
in custom ss
Executed successfully
res8: scala.actors.Future[Any] = <function0>
scala>
Note that the built-in for (x <- expr) body is just syntactic sugar for
expr foreach (x => body)
Thus it might be possible to achieve what you want (using the existing for syntax) by defining a custom foreach method.
Also note that there is already a foreach method that applies to strings. You could do something like this:
case class T(t: String) {
def foreach(f: String => Unit): Unit = f(t)
}
Note: You can also change the result type of f above from Unit to Any and it will still work.
Which would enable you to do something like
for (x <- T("test"))
print(x)
This is just a trivial (and useless) example, since now for (x <- T(y)) f(x) just abbreviates (or rather "enlongishes") f(y). But of course by changing the argument of f in the above definition of foreach from String to something else and doing a corresponding translation from the string t to this type, you could achieve more useful effects.

Scala extending while loops to do-until expressions

I'm trying to do some experiment with Scala. I'd like to repeat this experiment (randomized) until the expected result comes out and get that result. If I do this with either while or do-while loop, then I need to write (suppose 'body' represents the experiment and 'cond' indicates if it's expected):
do {
val result = body
} while(!cond(result))
It does not work, however, since the last condition cannot refer to local variables from the loop body. We need to modify this control abstraction a little bit like this:
def repeat[A](body: => A)(cond: A => Boolean): A = {
val result = body
if (cond(result)) result else repeat(body)(cond)
}
It works somehow but is not perfect for me since I need to call this method by passing two parameters, e.g.:
val result = repeat(body)(a => ...)
I'm wondering whether there is a more efficient and natural way to do this so that it looks more like a built-in structure:
val result = do { body } until (a => ...)
One excellent solution for body without a return value is found in this post: How Does One Make Scala Control Abstraction in Repeat Until?, the last one-liner answer. Its body part in that answer does not return a value, so the until can be a method of the new AnyRef object, but that trick does not apply here, since we want to return A rather than AnyRef. Is there any way to achieve this? Thanks.
You're mixing programming styles and getting in trouble because of it.
Your loop is only good for heating up your processor unless you do some sort of side effect within it.
do {
val result = bodyThatPrintsOrSomething
} until (!cond(result))
So, if you're going with side-effecting code, just put the condition into a var:
var result: Whatever = _
do {
result = bodyThatPrintsOrSomething
} until (!cond(result))
or the equivalent:
var result = bodyThatPrintsOrSomething
while (!cond(result)) result = bodyThatPrintsOrSomething
Alternatively, if you take a functional approach, you're going to have to return the result of the computation anyway. Then use something like:
Iterator.continually{ bodyThatGivesAResult }.takeWhile(cond)
(there is a known annoyance of Iterator not doing a great job at taking all the good ones plus the first bad one in a list).
Or you can use your repeat method, which is tail-recursive. If you don't trust that it is, check the bytecode (with javap -c), add the #annotation.tailrec annotation so the compiler will throw an error if it is not tail-recursive, or write it as a while loop using the var method:
def repeat[A](body: => A)(cond: A => Boolean): A = {
var a = body
while (cond(a)) { a = body }
a
}
With a minor modification you can turn your current approach in a kind of mini fluent API, which results in a syntax that is close to what you want:
class run[A](body: => A) {
def until(cond: A => Boolean): A = {
val result = body
if (cond(result)) result else until(cond)
}
}
object run {
def apply[A](body: => A) = new run(body)
}
Since do is a reserved word, we have to go with run. The result would now look like this:
run {
// body with a result type A
} until (a => ...)
Edit:
I just realized that I almost reinvented what was already proposed in the linked question. One possibility to extend that approach to return a type A instead of Unit would be:
def repeat[A](body: => A) = new {
def until(condition: A => Boolean): A = {
var a = body
while (!condition(a)) { a = body }
a
}
}
Just to document a derivative of the suggestions made earlier, I went with a tail-recursive implementation of repeat { ... } until(...) that also included a limit to the number of iterations:
def repeat[A](body: => A) = new {
def until(condition: A => Boolean, attempts: Int = 10): Option[A] = {
if (attempts <= 0) None
else {
val a = body
if (condition(a)) Some(a)
else until(condition, attempts - 1)
}
}
}
This allows the loop to bail out after attempts executions of the body:
scala> import java.util.Random
import java.util.Random
scala> val r = new Random()
r: java.util.Random = java.util.Random#cb51256
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res0: Option[Int] = Some(98)
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res1: Option[Int] = Some(98)
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res2: Option[Int] = None
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res3: Option[Int] = None
scala> repeat { r.nextInt(100) } until(_ > 90, 4)
res4: Option[Int] = Some(94)