I want to write a simple Scala script that runs some methods that are defined in another file.
Each line that runs this method requires information that won't be available until runtime. For simplicity sakes, I want to abstract that portion out.
Thus, I want to use Currying to get the result of each line in the script, then run the result again with the extra data.
object TestUtil {
// "control" is not known until runtime
def someTestMethod(x: Int, y: Int)(control: Boolean): Boolean = {
if (control) {
assert(x == y)
x == y
} else {
assert(x > y)
x > y
}
}
}
someTestMethod is defined in my primary codebase.
// testScript.sc
import <whateverpath>.TestUtil
TestUtil.someTestMethod(2,1)
TestUtil.someTestMethod(5,5)
Each line should return a function, that I need to rerun with a Boolean.
val control: Boolean = true
List[(Boolean) -> Boolean) testFuncs = runFile("testScript.sc")
testFuncs.foreach(_(control)) // Run all the functions that testScripts defined
(Sorry if this is a weird example, it's the simplest thing I can think of)
So far I have figured out how to parse the script, and get the Tree. However at that point I can't figure out how to execute each individual tree object and get the result. This is basically where I'm stuck!
val settings = new scala.tools.nsc.GenericRunnerSettings(println)
settings.usejavacp.value = true
settings.nc.value = true
val interpreter: IMain = new IMain(settings)
val treeResult: Option[List[Tree]] = interpreter.parse(
"""true
| 5+14""".stripMargin)
treeResult.get.foreach((tree: Tree) => println(tree))
the result of which is
true
5.$plus(14)
where 5 + 14 has not been evaluated, and I can't figure out how, or if this is even a worthwhile route to pursure
In the worst case you could toString your modified tree and then call interpreter.interpret:
val results = treeResult.get.map { tree: Tree => interpreter.interpret(tree.toString) }
It seems like it would be better to have the other file evaluate to something that can then be interpreted passing control (e.g. using the scalaz Reader Monad and for/yield syntax). But I assume you have good reasons for wanting to do this via an extra scala interpreter.
Related
I'm looking to call the ATR function from this scala wrapper for ta-lib. But I can't figure out how to use wrapper correctly.
package io.github.patceev.talib
import com.tictactec.ta.lib.{Core, MInteger, RetCode}
import scala.concurrent.Future
object Volatility {
def ATR(
highs: Vector[Double],
lows: Vector[Double],
closes: Vector[Double],
period: Int = 14
)(implicit core: Core): Future[Vector[Double]] = {
val arrSize = highs.length - period + 1
if (arrSize < 0) {
Future.successful(Vector.empty[Double])
} else {
val begin = new MInteger()
val length = new MInteger()
val result = Array.ofDim[Double](arrSize)
core.atr(
0, highs.length - 1, highs.toArray, lows.toArray, closes.toArray,
period, begin, length, result
) match {
case RetCode.Success =>
Future.successful(result.toVector)
case error =>
Future.failed(new Exception(error.toString))
}
}
}
}
Would someone be able to explain how to use function and print out the result to the console.
Many thanks in advance.
Regarding syntax, Scala is one of many languages where you call functions and methods passing arguments in parentheses (mostly, but let's keep it simple for now):
def myFunction(a: Int): Int = a + 1
myFunction(1) // myFunction is called and returns 2
On top of this, Scala allows to specify multiple parameters lists, as in the following example:
def myCurriedFunction(a: Int)(b: Int): Int = a + b
myCurriedFunction(2)(3) // myCurriedFunction returns 5
You can also partially apply myCurriedFunction, but again, let's keep it simple for the time being. The main idea is that you can have multiple lists of arguments passed to a function.
Built on top of this, Scala allows to define a list of implicit parameters, which the compiler will automatically retrieve for you based on some scoping rules. Implicit parameters are used, for example, by Futures:
// this defines how and where callbacks are run
// the compiler will automatically "inject" them for you where needed
implicit val ec: ExecutionContext = concurrent.ExecutionContext.global
Future(4).map(_ + 1) // this will eventually result in a Future(5)
Note that both Future and map have a second parameter list that allows to specify an implicit execution context. By having one in scope, the compiler will "inject" it for you at the call site, without having to write it explicitly. You could have still done it and the result would have been
Future(4)(ec).map(_ + 1)(ec)
That said, I don't know the specifics of the library you are using, but the idea is that you have to instantiate a value of type Core and either bind it to an implicit val or pass it explicitly.
The resulting code will be something like the following
val highs: Vector[Double] = ???
val lows: Vector[Double] = ???
val closes: Vector[Double] = ???
implicit val core: Core = ??? // instantiate core
val resultsFuture = Volatility.ATR(highs, lows, closes) // core is passed implicitly
for (results <- resultsFuture; result <- results) {
println(result)
}
Note that depending on your situation you may have to also use an implicit ExecutionContext to run this code (because you are extracting the Vector[Double] from a Future). Choosing the right execution context is another kind of issue but to play around you may want to use the global execution context.
Extra
Regarding some of the points I've left open, here are some pointers that hopefully will turn out to be useful:
Operators
Multiple Parameter Lists (Currying)
Implicit Parameters
Scala Futures
Following code does not work if I don't uncomment the commented line.It says
type mismatch; found : Unit required: Option[String]
import java.io._
import org.apache.pdfbox.pdmodel.PDDocument
import org.apache.pdfbox.text.PDFTextStripper
object PdfToText {
def main(args: Array[String]) {
val filename = "D:\\Scala\\DATA\\HelloWorld.pdf"
getTextFromPdf(filename)
}
def getTextFromPdf(filename: String): Option[String] = {
val pdf = PDDocument.load(new File(filename))
println(new PDFTextStripper().getText(pdf))
// Some(new PDFTextStripper().getText(pdf))
}
}
Code executes fine if I keep the line -
Some(new PDFTextStripper().getText(pdf))
Output:
Welcome
to
The World of Scala
Could anyone please explain the behaviour of the line
" Some(new PDFTextStripper().getText(pdf)"
The result of a method is the result of the final line of code. println returns Unit. If that's the last line then that's what the method returns, which conflicts with the stated Option[String] return type.
The code new PDFTextStripper().getText(pdf) returns a String and wrapping it in Some() makes it an Option[String] which does match the stated method return type.
explanation
Here is a method that compiles.
def six(): Int = { // takes no arguments and returns an Int
println("top") // string sent to stdout
6 // this is the Int it returns
}
Here is a method that does not compile.
def six(): Int = { // takes no arguments and returns an Int
6 // this is the Int it should return
println("end") // Error: type mismatch
}
This method is supposed to return an Int (that's what the : Int means) but the last line is a println() statement and println returns a Unit, not an Int, so that causes the error. This method is trying to return Unit when it is supposed to return Int.
This is a very basic concept in the Scala language.
Option is a Scala type that represents the presence or absence of a value. Instead of runtime constructs like null and exceptions which have significant downsides, Option (and equivalent constructs in other languages) allows for compile-time checking that you are handling both possibilities.
A common use of Option is a database lookup by id. It is quite possible there is no entity with that id. The return type of the function in Scala would be Option[Employee]. If you find one, it would return Some(employee); otherwise simply None. Both subclass Option. Note that you can think of Option like a container of zero or one element.
In your case, you have defined your function to return Option[String], which is why returning Some(String) containing the text of the file makes the compiler happy. I hope that answers your question.
Please note though that your function isn't really designed in a way that uses Option effectively since there is no issue of presence/absence--just always present. In other words, returning an Option isn't useful here. However, it would be perfectly appropriate to use Option to represent the cases where the file is or isn't available on the file system to be read.
For example:
object PdfToText {
def main(args: Array[String]) {
val filename = "D:\\Scala\\DATA\\HelloWorld.pdf"
val text = getTextFromPdf(filename)
val result = text.map(t => s"File contents: ${t}").getOrElse("Empty file")
println(result)
}
def getTextFromPdf(filename: String): Option[String] = {
val file = new File(filename)
if (file.exists() && !file.isDirectory) {
val pdf = PDDocument.load(new File(filename))
Some(new PDFTextStripper().getText(pdf))
} else {
None
}
}
}
Here presence is defined by the existence of a readable file, which allows me to return its contents in a Some, and absence is defined by the nonexistence of the file or the file being a directory, which manifests as a None
I then account for both possibilities in main. If there's text to be read because the function gave me back a Some, I call map (which only fires on Somes) to transform the text into a different string. If I get None, we skip over to the getOrElse and produce a default string.
Either way, we print out whatever we got, which is guaranteed to be a String no matter what happened with the original File.
As a shameless plug, you can learn more about Option in our tutorial Nine Reasons to Try Scala. Just fast forward to 8:36.
Scalastyle (intellij 2016.1 defaults) says this boolean expression can be simplified
val t = Option(true)
val f = Option(false)
if(t.contains(true) && f.contains(false)) {
println("booop")
}
I can get rid of this by changing the if to:
if(t.contains(true).&&(f.contains(false)))
Or by changing && to &
But not really seeing how this is simplifying it, could anyone explain what's going on?
Update
It doesn't appear to be related to if the vals are known at compile time, or them being locally defined. The following code also get's the warning that the expression can be simplfied:
object TestFoo {
def bar(t: Option[Boolean]) = {
val f = Option(scala.util.Random.nextBoolean)
if (t.contains(true) && f.contains(false)) println("booop")
}
def main(args: Array[String]) = bar(t = Option(scala.util.Random.nextBoolean))
}
I just don't get how I'm supposed to make that any simpler, is there some strange Option[Boolean] comparing I'm missing out on?
It seems to suggest you being consistent with the method call usage. Either everything in infix form:
(t contains true) && (f contains false)
Or everything in regular method call form:
t.contains(true).&&(f.contains(false))
With your values, t.contains(true).&&(f.contains(false)) always returns true. So you could simplify it by simply writing true, i.e by just executing the print without an if condition.
Is it possible to configure a Scala interpreter (tools.nsc.IMain) so that it "forgets" the previously executed code, whenever I run the next interpret() call?
Normally when it compiles the sources, it wraps them in nested objects, so all the previously defined variables, functions and bindings are available.
It would suffice to not generate the nested objects (or to throw them away), although I would prefer a solution which would even remove the previously compiled classes from the class loader again.
Is there a setting, or a method, or something I can overwrite, or an alternative to IMain that would accomplish this? I need to be able to still access the resulting objects / classes from the host VM.
Basically I want to isolate subsequent interpret() calls without something as heavy weight as creating a new IMain for each iteration.
Here is one possible answer. Basically there is method reset() which calls the following things (mostly private, so either you buy the whole package or not):
clearExecutionWrapper()
resetClassLoader()
resetAllCreators()
prevRequests.clear()
referencedNameMap.clear()
definedNameMap.clear()
virtualDirectory.clear()
In my case, I am using a custom execution wrapper, so that needs to be set up again, and also imports are handled through a regular interpret cycle, so either add them again, or—better—just prepend them with the execution wrapper.
I would like to keep my bindings, they are also gone:
import tools.nsc._
import interpreter.IMain
object Test {
private final class Intp(cset: nsc.Settings)
extends IMain(cset, new NewLinePrintWriter(new ConsoleWriter, autoFlush = true)) {
override protected def parentClassLoader = Test.getClass.getClassLoader
}
object Foo {
def bar() { println("BAR" )}
}
def run() {
val cset = new nsc.Settings()
cset.classpath.value += java.io.File.pathSeparator + sys.props("java.class.path")
val i = new Intp(cset)
i.initializeSynchronous()
i.bind[Foo.type]("foo", Foo)
val res0 = i.interpret("foo.bar(); val x = 33")
println(s"res0: $res0")
i.reset()
val res1 = i.interpret("println(x)")
println(s"res1: $res1")
i.reset()
val res2 = i.interpret("foo.bar()")
println(s"res2: $res2")
}
}
This will find Foo in the first iteration, correctly forget x in the second iteration, but then in the third iteration, it can be seen that the foo binding is also lost:
foo: Test.Foo.type = Test$Foo$#8bf223
BAR
x: Int = 33
res0: Success
<console>:8: error: not found: value x
println(x)
^
res1: Error
<console>:8: error: not found: value foo
foo.bar()
^
res2: Error
The following seems to be fine:
for(j <- 0 until 3) {
val user = "foo.bar()"
val synth = """import Test.{Foo => foo}
""".stripMargin + user
val res = i.interpret(synth)
println(s"res$j: $res")
i.reset()
}
Perhaps this is just my background in more imperative programming, but I like having return statements in my code.
I understand that in Scala, returns are not necessary in many methods, because whatever the last computed value is is returned by default. I understand that this makes perfect sense for a "one-liner", e.g.
def square(x) = x * x
I also understand the definitive case for using explicit returns (when you have several branches your code could take, and you want to break out of the method for different branches, e.g. if an error occurs). But what about multiline functions? Wouldn't it be more readable and make more sense if there was an explicit return, e.g.
def average(x: List[Int]) : Float = {
var sum = 0
x.foreach(sum += _)
return sum / x.length.toFloat
}
def average(x: List[Int]) : Float =
x.foldLeft(0)(_ + _) / x.length.toFloat
UPDATE: While I was aiming to show how an iterative code can be made into a functional expression, #soc rightly commented that an even shorter version is x.sum / x.length.toFloat
I usually find that in Scala I have less need to "return in the middle". Furthermore, a large function is broken into smaller expressions that are clearer to reason. So instead of
var x = ...
if (some condition) x = ...
else x = ...
I would write
if (some condition) ...
else ....
Similar thing happens using match expressions. And you can always have helper nested classes.
Once you are comfortable with many forms of expressions that evaluate to a result (e.g., 'if') without a return statement, then having one in your methods looks out of place.
At one place of work we had a rule of not having 'return' in the middle of a method since it is easy for a reader of your code to miss it. If 'return' is only at the last line, what's the point of having it at all?
The return doesn't tell you anything extra, so I find it actually clutters my understanding of what goes on. Of course it returns; there are no other statements!
And it's also a good idea to get away from the habit of using return because it's really unclear where you are returning to when you're using heavily functional code:
def manyFutures = xs.map(x => Futures.future { if (x<5) return Nil else x :: Nil })
Where should the return leave execution? Outside of manyFutures? Just the inner block?
So although you can use explicit returns (at least if you annotate the return type explicitly), I suggest that you try to get used to the last-statement-is-the-return-value custom instead.
Your sense that the version with the return is more readable is probably a sign that you are still thinking imperatively rather than declaratively. Try to think of your function from the perspective of what it is (i.e. how it is defined), rather than what it does (i.e. how it is computed).
Let's look at your average example, and pretend that the standard library doesn't have the features that make an elegant one-liner possible. Now in English, we would say that the average of a list of numbers is the sum of the numbers in the list divided by its length.
def average(xs: List[Int]): Float = {
var sum = 0
xs.foreach(sum += _)
sum / xs.length.toFloat
}
This description is fairly close to the English version, ignoring the first two lines of the function. We can factor out the sum function to get a more declarative description:
def average(xs: List[Int]): Float = {
def sum(xs: List[Int]): Int = // ...
sum(xs) / xs.length.toFloat
}
In the declarative definition, a return statement reads quite unnaturally because it explicitly puts the focus on doing something.
I don't miss the return-statement at the end of a method because it is unnecessary. Furthermore, in Scala each method does return a value - even methods which should not return something. Instead of void there is the type Unit which is returned:
def x { println("hello") }
can be written as:
def x { println("hello"); return Unit }
But println returns already the type Unit - thus when you explicitly want to use a return-statement you have to use it in methods which return Unit, too. Otherwise you do not have continuous identical build-on code.
But in Scala there is the possibility to break your code in a lot of small methods:
def x(...): ReturnType = {
def func1 = ... // use funcX
def func2 = ... // use funcX
def func3 = ... // use funcX
funcX
}
An explicitly used return-statement does not help to understand the code better.
Also Scala has a powerful core library which allows you to solve many problems with less code:
def average(x: List[Int]): Float = x.sum.toFloat / x.length
I believe you should not use return, I think it somehow goes against the elegant concept that in Scala everything is an expression that evaluates to something.
Like your average method: it's just an expression that evaluates to Float, no need to return anything to make that work.