Twitter util library provides a nice utility for how to evaluate Scala code at runtime, for example:
val eval = new com.twitter.util.Eval()
val example = eval.apply("""
case class E() {
def one(): Int = 1
}
(new E).one()
""").asInstanceOf[Int]
// example: Int = 1
But is it possible to evaluate code that doesn't return anything (returns status true/false - complied/failed) and then start using classes defined within evaluated part, for example:
val eval = new com.twitter.util.Eval()
eval.{_MAGIC_METHOD_}("""
case class E() {
def one(): Int = 1
}
""")
val one = (new E).one(); // and this one will be -> one: Int = 1
So I'm curious about {_MAGIC_METHOD_} part, is it possible to do this with some library? Is it possible with Twitter utils? Some other util library? Scala compiler (Scala Compiler - http://mvnrepository.com/artifact/org.scala-lang/scala-compiler)?
Thanks in advance for your help and any suggestions.
Related
I come from a Java background and am taking over a Gatling project where I noticed what seems to me a bit of inconsistency when using what is a val or a def method. The picture below exemplifies that and I was wondering if there's any guidance on what is the best usage for these within the Gatling context please.
These are other examples where I'm not sure what should be used. I'm assuming a Switch makes sense being inside a method but not sure about the others?
private def teacherViewResources: ChainBuilder =
exec(viewResourcesFlow)
.randomSwitch(
70.0 -> pause(1,2).exec(teacherLaunchResource),
10.0 -> pause(1,2).exec(teacherAssignResource),
20.0 -> pause(1,2).exec(teacherResourcesNext)
)
private def teacherLaunchResource: ChainBuilder =
exec(launchResourcesFlow)
val rootTeacherScenario = scenario("Root Teacher Scenario " + currentScenario.toString)
.doIfOrElse(currentScenario == PossibleScenarios.BRANCH)(
feed(userFeederTeacher).during(EXECUTION_TIME_SEC) {
exec(teacherBranching)
}
//For use with atOnceUsers for debugging
//feed(userFeederTeacher).exec(simulationTeacherBranching)
)(
exec {
session =>
logger.debug("Invalid teacher scenario chosen")
session
}
)
val loginFlowWithExit = exec(loginFlow).exitHereIfFailed
val teacherBranching = group("teacherBranching") {
exec(loginFlow)
.exec(session => sessionSetSessionVariable(session))
.exec(execFlaggedScenario(teacherDashboard)) // First method to run for a teacher
.exec(logout())
}
Many thanks.
val is evaluated once while def is evaluated on every call.
Remember that Gatling DSL components are just builders, not what is executed when your test is running.
Everything that doesn't take a parameter could be a val, you just have to make sure you don't end up with using forward references, eg:
broken:
val foo = exec(???).exec(bar) // here, bar is still null because it's populated later in the code
val bar = exec(???)
correct:
val bar = exec(???)
val foo = exec(???).exec(bar) // fine because bar is already populated
This question isn't programming language specific (the more general the better), but I'm working in Scala (not necessarily on the JVM). Is there a means to reference count by call location, not the number of total calls? In particular, it would be great to be able to detect if a given method is called from more than one call location.
I think I can fake it to some extent by doing a reference equality check with a function, but this could be abused easily by having a global-ish token, or even calling the function multiple times in the same scope:
sealed case class Token();
class MyClass[A] {
var tokenOpt: Option[Token] = None
def callMeFromOnePlace(x: A)(implicit tk: Token) = {
tokenOpt match {
case Some(priorTk) => if (priorTk ne tk) throw new IllegalStateException("")
case None => tokenOpt = Some(tk)
}
// Do some work ...
}
}
Then this should work fine:
val myObj = new MyClass[Int]
val myIntList = List(1,2,3)
implicit val token = Token()
myIntList.map(ii => myObj.callMeFromOnePlace(ii))
But unfortunately, so would this:
val myObj = new MyClass[Int]
implicit val token = Token()
myObj.callMeFromOnePlace(1)
myObj.callMeFromOnePlace(1) //oops, want this to fail
When you are talking about call location, it can be represented by a call stack trace. Here is a simple example:
// keep track of calls here (you can use immutable style if you want)
var callCounts = Map.empty[Int, Int]
def f(): Unit = {
// calculate call stack trace hashCode for more efficient storage
// .toSeq makes WrappedArray, that knows how to properly calculate .hashCode()
val hashCode = new RuntimeException().getStackTrace.toSeq.hashCode()
val callLocation = hashCode
callCounts += (callLocation -> (callCounts.getOrElse(callLocation, 0) + 1))
}
List(1,2,3).foreach(_ =>
f()
)
f()
f()
println(callCounts) // Map(75070239 -> 3, 900408638 -> 1, -1658734417 -> 1)
I am not completely clear what you want to do but for your //oops.. example to fail you need just check the PriorTk is not None. (do note that it is not a thread safe solution )
For completeness, enforcing these kind of constraints from a type system perspective requires linear types.
I'm confused about anonymous function definitions as following:
var plusOne = (x:Int)=>x+1
// or val plusOne=(x:Int)=>x+1
println(plusOne(2))
Or
def plusOne = (x:Int)=>x+1
println(plusOne(2))
What's the difference please in var/val and def for a function name.
val declares an "immutable variable or rather symbol" that doesn't allow reassignment, right hand side of the assignment is evaluated immediately
var declares a "mutable variable" that allows reassignments later to the symbol, right hand side of the assignment is evaluated immediately just like val
def declares an "immutable symbol" that doesn't allow reassignment, right hand side is evaluated lazily, i.e. whenever that symbol is referenced later in the code
Example -
var plusOneVar = (x:Int)=>x+1
val plusOneVal = (x:Int)=>x+1
def plusOneDef = (x:Int)=>x+1
plusOneVar = (x:Int)=>x+2 // Reassignment to var is valid
plusOneVal = (x:Int)=>x+2 // Compile time error, reassignment to val
plusOneDef = (x:Int)=>x+2 // Compile time error, reassignment to val
Because you are looking at an example with functions, it is hard to understand. Let's try to understand it with simple variables.
var symbolVar = 100 // line 1
val symbolVal = symbolVar // line 2
def symbolDef = symbolVar // line 3
println(symbolVar) // prints 100
println(symbolVal) // prints 100
println(symbolDef) // prints 100 - no surprise yet
symbolVar = symbolVar + 1
println(symbolVal) // still prints 100 which was evaluated and assigned on line 2
println(symbolDef) // prints 101 as symbolDef is a def and it depends on symbolVar, line 3 is evaluated again
var plusOne can be reassigned. val plusOne cannot be reassigned. Both are evaluated once. def plusOne is evaluated each time it is called
Note also with val (or var) one instance of the function is created and is used for any number of invocations to that function, whereas with def a new instance of the function is created for each invocation. Yet, for
def f (i:Int) = i+1
f: (i: Int)Int
note
val g = f _
g: Int => Int = <function1>
It might be clear from the Class File Disassembler results using javap. Save the following code as Test.scala
class Test {
val fVal: Int => Int = x => x + 1
var fVar: Int => Int = x => x + 1
def fDef(x: Int): Int = { x + 1 }
}
and do scalac Test.scala; javap Test will show
Compiled from "Test.scala"
public class Test {
public scala.Function1<java.lang.Object, java.lang.Object> fVal();
public scala.Function1<java.lang.Object, java.lang.Object> fVar();
public void fVar_$eq(scala.Function1<java.lang.Object, java.lang.Object>);
public int fDef(int);
public Test();
}
As is shown in the results above, val and fVar are represented as methods that return a Function1 object. The difference is fVar has an additional "setter". While fDef is like normal Java method.
I'm still learning Scala, but one thing I thought was interesting is that Scala blurs the line between methods and fields. For instance, I can build a class like this...
class MutableNumber(var value: Int)
The key here is that the var in the constructor-argument automatically allows me to use the 'value' field like a getter/setter in java.
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
If I want to add constraints, I can do so by switching to using methods in place of the instance-fields:
// require all mutable numbers to be >= 0
class MutableNumber(private var _value: Int) {
require(_value >= 0)
def value: Int = _value
def value_=(other: Int) {
require(other >=0)
_value = other
}
}
The client side code doesn't break since the API doesn't change:
// use number...
val num = new MutableNumber(5)
num.value = 6
println(num.value)
My hang-up is with the named-parameter feature that was added to Scala-2.8. If I use named-parameters, my API does change and it does break the api.
val num = new MutableNumber(value=5) // old API
val num = new MutableNumber(_value=5) // new API
num.value = 6
println(num.value)
Is there any elegant solution to this? How should I design my MutableNumber class so that I can add constraints later on without breaking the API?
Thanks!
You can use the same trick that case classes do: use a companion object.
object Example {
class MutableNumber private (private var _value: Int) {
require (_value >= 0)
def value: Int = _value
def value_=(i: Int) { require (i>=0); _value = i }
override def toString = "mutable " + _value
}
object MutableNumber {
def apply(value: Int = 0) = new MutableNumber(value)
}
}
And here it is working (and demonstrating that, as constructed, you must use the object for creations, since the constructor is marked private):
scala> new Example.MutableNumber(5)
<console>:10: error: constructor MutableNumber cannot be accessed in object $iw
new Example.MutableNumber(5)
^
scala> Example.MutableNumber(value = 2)
res0: Example.MutableNumber = mutable 2
scala> Example.MutableNumber()
res1: Example.MutableNumber = mutable 0
Thanks for the answer! As an aside, I think the Scala-guys might be aware that there's an issue:
What's New in Scala 2.8: Named and Default Parameters
...
Until now, the names of arguments were a somewhat arbitrary choice for library developers, and weren't considered an important part of the API. This has suddenly changed, so that a method call to mkString(sep = " ") will fail to compile if the argument sep were renamed to separator in a later version.
Scala 2.9 implements a neat solution to this problem, but while we're waiting for that, be cautious about referring to arguments by name if their names may change in the future.
http://www.artima.com/scalazine/articles/named_and_default_parameters_in_scala.html
class MutableNumber {
private var _value = 0 //needs to be initialized
def value: Int = _value
def value_=(other: Int) {
require(other >=0) //this requirement was two times there
_value = other
}
}
you can modify all members of any class within curly braces
val n = new MutableNumber{value = 17}
Is there any reason for Scala not support the ++ operator to increment primitive types by default?
For example, you can not write:
var i=0
i++
Thanks
My guess is this was omitted because it would only work for mutable variables, and it would not make sense for immutable values. Perhaps it was decided that the ++ operator doesn't scream assignment, so including it may lead to mistakes with regard to whether or not you are mutating the variable.
I feel that something like this is safe to do (on one line):
i++
but this would be a bad practice (in any language):
var x = i++
You don't want to mix assignment statements and side effects/mutation.
I like Craig's answer, but I think the point has to be more strongly made.
There are no "primitives" -- if Int can do it, then so can a user-made Complex (for example).
Basic usage of ++ would be like this:
var x = 1 // or Complex(1, 0)
x++
How do you implement ++ in class Complex? Assuming that, like Int, the object is immutable, then the ++ method needs to return a new object, but that new object has to be assigned.
It would require a new language feature. For instance, let's say we create an assign keyword. The type signature would need to be changed as well, to indicate that ++ is not returning a Complex, but assigning it to whatever field is holding the present object. In Scala spirit of not intruding in the programmers namespace, let's say we do that by prefixing the type with #.
Then it could be like this:
case class Complex(real: Double = 0, imaginary: Double = 0) {
def ++: #Complex = {
assign copy(real = real + 1)
// instead of return copy(real = real + 1)
}
The next problem is that postfix operators suck with Scala rules. For instance:
def inc(x: Int) = {
x++
x
}
Because of Scala rules, that is the same thing as:
def inc(x: Int) = { x ++ x }
Which wasn't the intent. Now, Scala privileges a flowing style: obj method param method param method param .... That mixes well C++/Java traditional syntax of object method parameter with functional programming concept of pipelining an input through multiple functions to get the end result. This style has been recently called "fluent interfaces" as well.
The problem is that, by privileging that style, it cripples postfix operators (and prefix ones, but Scala barely has them anyway). So, in the end, Scala would have to make big changes, and it would be able to measure up to the elegance of C/Java's increment and decrement operators anyway -- unless it really departed from the kind of thing it does support.
In Scala, ++ is a valid method, and no method implies assignment. Only = can do that.
A longer answer is that languages like C++ and Java treat ++ specially, and Scala treats = specially, and in an inconsistent way.
In Scala when you write i += 1 the compiler first looks for a method called += on the Int. It's not there so next it does it's magic on = and tries to compile the line as if it read i = i + 1. If you write i++ then Scala will call the method ++ on i and assign the result to... nothing. Because only = means assignment. You could write i ++= 1 but that kind of defeats the purpose.
The fact that Scala supports method names like += is already controversial and some people think it's operator overloading. They could have added special behavior for ++ but then it would no longer be a valid method name (like =) and it would be one more thing to remember.
I think the reasoning in part is that +=1 is only one more character, and ++ is used pretty heavily in the collections code for concatenation. So it keeps the code cleaner.
Also, Scala encourages immutable variables, and ++ is intrinsically a mutating operation. If you require +=, at least you can force all your mutations to go through a common assignment procedure (e.g. def a_=).
The primary reason is that there is not the need in Scala, as in C. In C you are constantly:
for(i = 0, i < 10; i++)
{
//Do stuff
}
C++ has added higher level methods for avoiding for explicit loops, but Scala has much gone further providing foreach, map, flatMap foldLeft etc. Even if you actually want to operate on a sequence of Integers rather than just cycling though a collection of non integer objects, you can use Scala range.
(1 to 5) map (_ * 3) //Vector(3, 6, 9, 12, 15)
(1 to 10 by 3) map (_ + 5)//Vector(6, 9, 12, 15)
Because the ++ operator is used by the collection library, I feel its better to avoid its use in non collection classes. I used to use ++ as a value returning method in my Util package package object as so:
implicit class RichInt2(n: Int)
{
def isOdd: Boolean = if (n % 2 == 1) true else false
def isEven: Boolean = if (n % 2 == 0) true else false
def ++ : Int = n + 1
def -- : Int = n - 1
}
But I removed it. Most of the times when I have used ++ or + 1 on an integer, I have later found a better way, which doesn't require it.
It is possible if you define you own class which can simulate the desired output however it may be a pain if you want to use normal "Int" methods as well since you would have to always use *()
import scala.language.postfixOps //otherwise it will throw warning when trying to do num++
/*
* my custom int class which can do ++ and --
*/
class int(value: Int) {
var mValue = value
//Post-increment
def ++(): int = {
val toReturn = new int(mValue)
mValue += 1
return toReturn
}
//Post-decrement
def --(): int = {
val toReturn = new int(mValue)
mValue -= 1
return toReturn
}
//a readable toString
override def toString(): String = {
return mValue.toString
}
}
//Pre-increment
def ++(n: int): int = {
n.mValue += 1
return n;
}
//Pre-decrement
def --(n: int): int = {
n.mValue -= 1
return n;
}
//Something to get normal Int
def *(n: int): Int = {
return n.mValue
}
Some possible test cases
scala>var num = new int(4)
num: int = 4
scala>num++
res0: int = 4
scala>num
res1: int = 5 // it works although scala always makes new resources
scala>++(num) //parentheses are required
res2: int = 6
scala>num
res3: int = 6
scala>++(num)++ //complex function
res4: int = 7
scala>num
res5: int = 8
scala>*(num) + *(num) //testing operator_*
res6: Int = 16
Of course you can have that in Scala, if you really want:
import scalaz._
import Scalaz._
case class IncLens[S,N](lens: Lens[S,N], num : Numeric[N]) {
def ++ = lens.mods(num.plus(_, num.one))
}
implicit def incLens[S,N:Numeric](lens: Lens[S,N]) =
IncLens[S,N](lens, implicitly[Numeric[N]])
val i = Lens[Int,Int](identity, (x, y) => y)
val imperativeProgram = for {
_ <- i := 0;
_ <- i++;
_ <- i++;
x <- i++
} yield x
def runProgram = imperativeProgram ! 0
And here you go:
scala> runProgram
runProgram: Int = 3
It isn't included because Scala developers thought it make the specification more complex while achieving only negligible benefits and because Scala doesn't have operators at all.
You could write your own one like this:
class PlusPlusInt(i: Int){
def ++ = i+1
}
implicit def int2PlusPlusInt(i: Int) = new PlusPlusInt(i)
val a = 5++
// a is 6
But I'm sure you will get into some trouble with precedence not working as you expect. Additionally if i++ would be added, people would ask for ++i too, which doesn't really fit into Scala's syntax.
Lets define a var:
var i = 0
++i is already short enough:
{i+=1;i}
Now i++ can look like this:
i(i+=1)
To use above syntax, define somewhere inside a package object, and then import:
class IntPostOp(val i: Int) { def apply(op: Unit) = { op; i } }
implicit def int2IntPostOp(i: Int): IntPostOp = new IntPostOp(i)
Operators chaining is also possible:
i(i+=1)(i%=array.size)(i&=3)
The above example is similar to this Java (C++?) code:
i=(i=i++ %array.length)&3;
The style could depend, of course.