This question already has an answer here:
Difference between function with parentheses and without [duplicate]
(1 answer)
Closed 6 years ago.
I was learning about scala methods and I created two code examples which are somewhat similar in nature, but confused on calling them.
Method #1
def someTestMethod = {
println("Inside a test method")
}
This resorts to a Unit type since it does not return anything.
Method #2
def anotherTestMethod() = {
println("Inside a test method")
}
This resorts to Unit as well, but with a curly brace () added.
What is the difference between the two methods, notice that if I call the first method like someTestMethod(), the scala shell/compiler says
error: Unit does not take parameters, but works well if I call like someTestMethod without the braces.
Also, the second method seems fool proof, in the sense that it can be called either way anotherTestMethod or anotherTestMethod(), why is it so?
When you don't want to pass any parameter to the method, use the first one.
If you want to pass some pass parameters, use the second one with brackets and pass some parameters and use it inside method.
For example:
def someTestMethod1(count : Int) = {
println("Inside a test method"+count)
}
someTestMethod1(10)
Related
In scala, how can I call a single parameter method using space in the body of the anonymous class?
add "Answer3" below is not working
trait Question {
def add(answer:String):Unit = {
println("Received the answer=" + answer)
}
}
object Test {
val question:Question = new Question {
this add "Answer1" // working
add("Answer2") // working
add "Answer3" // NOT working, why? -> error: ';' expected but string literal found.
}
}
You're trying to mix two different, and conflicting, convenience syntax options.
instance.method(argument)
... can be expressed as ...
instance method argument
... and, if the method() takes no argument then that can also be expressed with spaces, but the parser needs a little help.
instance method;
On a separate track, if the instance is this then that can be dropped.
method(argument)
But you can't drop the parentheses because the parser tries to interpret that as instance method and fails.
This question already has answers here:
What is the eta expansion in Scala?
(2 answers)
Closed 4 years ago.
New to Scala, have searched far and wide for clarification on some ScalaMock syntax. As per this guide, I keep seeing the following general testing pattern:
(myClass.myMethod _).expects()
What exactly is happening here? What function does the class/method/space/underscore serve? How does the compiler treat this?
The appended _ forces the conversion of a method into a function.
To understand why this is necessary, let's try to re-build a tiny piece of Scalamock, namely the expects method. The expects method seems to be invoked on methods of mocked objects. But methods / functions do not have an expects method to begin with. Therefore, we have to use the "pimp my library"-pattern to attach the method expects to functions. We could do something like this:
implicit class ExpectsOp[A, B](f: A => B) {
def expects(a: A): Unit = println("it compiles, ship it...")
}
Now let's define a class Bar with method baz:
class Bar {
def baz(i: Int): Int = i * i
}
and also an instance of Bar:
val bar = new Bar
Let's see what happens if you try to invoke expects on bar.baz:
(bar.baz).expects(42)
error: missing argument list for method baz in class Bar
Unapplied methods are only converted to functions when a function type is expected. You can make this conversion explicit by writing baz _ or baz(_) instead of baz.
So, it doesn't work without explicit conversion into a function, and we have to enforce this conversion by appending an _:
(bar.baz _).expects(42) // prints: "it compiles, ship it..."
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I am newbie to Scala. I have a method just as below :
def process(func: Context => T) = {
val context = getContext() // This method provides me the context
func(context)
}
Now if I want to call this method. I have two helper methods
def runContext1(context: Context): String = {
"hello world"
}
def runContext2(): (Context) => String = {
context => "hello world"
}
def test1() = {
process(context => {
"hello world"
})
}
def test2() = {
process(runContext1)
}
def test3() = {
process(runContext2())
}
test2() does not work and throws a NullPointerException whereas test3() works.
Differences between test1(), test2() and test3() // As per my understanding test1() uses closure with anonymous functions. test2() and test3() are closures with named functions. Correct me if I am wrong and tell me if there are other differences
I want to know why test3() works and test2() does not.
What is the contract of runContext2()? I do not understand runContext2(): (Context) => String.
Your problem is somewhere in the implementation of test2 method. All of the code you posted should work (except for the fact that test1() is missing a closing parenthesis, but that's a typo).
Regarding your first question, yes, you are right in sense that those are closures because they "close over" definitions of process, runContext1 and runContext2. Whenever a method uses something defined outside of its scope, that's a closure. If that value changes on the outside, method will see that change. Further reading: link. And yes, test1 uses an anonymous function, while test2 and test3 use named ones.
Now, about your third question. The thing is, runContext2() is a method taking nothing and returning a function. Returned function takes a context and returns a string. It could have been a val too (in that case you would of course need to omit the empty parenthesis since vals don't take arguments):
val runContextVal: (Context) => String = {
context => "hello world"
}
Note that your method process() takes a function, so in fact our runContextVal would be the only one actually obeying the contract when passed to process method:
process(runContextVal)
All other invocations of process() have a method passed to it (defined using keyword def) instead of a function. This is not something compiler would allow per se. However, it's smart enough to perform something called eta expansion which is basically a simple transformation of a parameterless method into a function. Key idea is fairly simple - every value, e.g. 42 or "foo", can be thought of as a function which takes nothing and returns that value, e.g. () => 42. Furthermore, a function that takes a parameter (such as val f = (x: Int) => Int) can be thought of as a function that takes a parameter and returns your function applied to that parameter (e.g. (x: Int) => f(x)). Function for squaring numbers (let's call it sqr()) is the same as a function n => sqr(n), isn't it? Check out some other online materials for extra details (e.g. here, here or here).
Note however that if you wanted to create a function value from your runContext1 method, you would run into trouble:
val fun2 = runContext2 // works
val fun1 = runContext1 // ERROR!
If a method is parameterless or has an empty parameter (not the same thing), then eta-expansion is performed automatically. However, if it has one or more actual parameters (like runContext1 has Context) then we need to give the compiler a hand. We either need to explicitly state the value type:
val fun1: Context => String = runContext1
or make a partially applied function:
val fun1 = runContext1 _
If this is all new to you, don't be overwhelmed. Just write methods like you normally would (e.g. how runContext1 is written) and use eta expansion only when (if?) you need it.
This question already has answers here:
How to write to a file in Scala?
(19 answers)
Closed 6 years ago.
I am trying to write a given string into a new file in SCALA.
I have imported
java.io._
java.nio._
This is my code:
implicit class PathImplicits(p: Path) {
def write(str:String, file:String):Path = Paths.get(file)
p.write(str,file)
}
However, the compile says it does not recognize the 'file' variable.
First of all, you are missing a pair of braces around your function. I think, you intended it to look like this:
def write(str:String, file:String):Path = {
Paths.get(file)
p.write(str,file)
}
It looks like it, because str and file are parameters to the function, and you are trying to use them outside of it (a function body without braces is just one statement).
Now, the way I "fixed" it for you, still doesn't make very much sense.
First, Paths.get(file) doesn't do anything, it just returns the Path object, which you do not assign to anything, so, this call does not have any effect. Second, Path does not have a method, called write, so the second line isn't going to work. Perhaps, you intended it to implicitly end up calling PathImplicits.write, but that won't work (you'd have to be outside of that class), and that's a good thing, because you are actually inside that function, and, if that line called it again, you'd get into infinite recursion.
Let's break your problem into two parts. First, let's forget about implicits and other fancy stuff, and just figure out how to write a string into a file. There is a whole lot of different ways to do it. Here is one for instance:
def writeToFile(file: File, str: String): Unit = {
val writer = new FileWriter(file)
try { writer.append(str).append("\n") }
finally { writer.close }
}
Now, if you want to make it work with Path implicitly, you'd need something like this:
object PathImplicits {
implicit class RichPath(p: Path) extends AnyVal {
def write(str: String) = writeToFile(p.toFile, str)
}
}
That's it. Now, you should be able to write something like this:
import PathImplicits._
Paths.get("/some/path/to/file.txt").write("Foo!")
I am new to Scala, and am learning it by going over some Play code. I have had a good read of the major concepts of Scala and am comfortable with functional programming having done some Haskell and ML.
I am really struggling to read this code, at the level of the syntax and the programming paradigms alone. I understand what the code is supposed to do, but not how it does it because I can't figure out the syntax.
// -- Home page
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref) { implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
(Prismic is an API separate to Play and is not really that relevant). How would I describe this function (or is it a method??) to another developer over the phone: in other words, using English. For example in this code:
def add(a: Int, b: Int): Int = a + b
I would say "add is a function which takes two integers, adds them together and returns the result as another integer".
In the Play code above I don't even know how to describe it after getting to "index is a function which takes an Option of a String and returns an Action of type AnyContent by ....."
The bit after the '=' and then the curly braces and the '=>' scare me! How do I read them? And is the functional or OO?
Thanks for your assistance
Let's reduce it to this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(function)
That's better, isn't it? index is a function from Option of String to Action of AnyContent (one word), which calls the action method of the object Prismic passing two curried parameters: ref, the parameter that index received, and a function (to be described).
So let's break down the anonymous function:
{ implicit request =>
for {
someDocuments <- ctx.api.forms("everything").ref(ctx.ref).submit()
} yield {
Ok(views.html.index(someDocuments))
}
}
First, it uses {} instead of () because Scala allows one to drop () as parameter delimiter if it's a single parameter (there are two parameter lists, but each has a single parameter), and that parameter is enclosed in {}.
So, what about {}? Well, it's an expression that contains declarations and statements, with semi-colon inference on new lines, whose value is that of the last statement. That is, the value of these two expressions is the same, 3:
{ 1; 2; 3 }
{
1
2
3
}
It's a syntactic convention to use {} when passing a function that extends for more than one line, even if, as in this case, that function could have been passed with just parenthesis.
The next thing confusing is the implicit request =>, Let's pick something simpler:
x => x * 2
That's pretty easy, right? It takes one parameter, x, and returns x * 2. In our case, it is the same thing: the function takes one parameter, request, and returns this:
for (someDocuments <- somethingSomething())
yield Ok(views.html.index(someDocuments))
That is, it calls some methods, iterate over the result, and map those results into a new value. This is a close equivalent to Haskell's do notation. You can rewrite it like below (I'm breaking it down into multiple lines for readability):
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
So, back to our method definition, we have this:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)(
implicit request =>
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
)
The only remaining question here is what that implicit is about. Basically, it makes that parameter implicitly available through the scope of the function. Presumably, at least one of these method calls require an implicit parameter which is properly fielded by request. I could drop the implicit there an pass request explicitly, if I knew which of these methods require it, but since I don't, I'm skipping that.
An alternate way of writing it would be:
def index(ref: Option[String]): Action[AnyContent] = Prismic.action(ref)({
request =>
implicit val req = request
ctx
.api
.forms("everything")
.ref(ctx.ref)
.submit()
.map(someDocuments => Ok(views.html.index(someDocuments)))
})
Here I added {} back because I added a declaration to the body of the function, though I decided not to drop the parenthesis, which I could have.
Something like this:
index is a function which takes an Option of a String and returns an Action of type AnyContent. It calls the method action that takes as a first argument an Option and as a second argument a method that assumes an implicit value request of type Request is in scope. This method uses a For-comprehension that calls the submit method which returns an Option or a Future and then in case its execution is successful, it yields the result Ok(...) that will be wrapped in the Action returned by the action method of Prismic.
Prismic.action is a method that takes 2 groups of arguments (a.k.a. currying).
The first is ref
The second is { implicit request => ...}, a function defined in a block of a code
more information on Action