why scala value class#toString contains case class info? - scala

value classes can be used to achieve type safety without the overhead of unboxing.
I had the impression that in runtime such types/classes would "not exist", being seen as simple types (for instance, a value class case class X(i: Int) extends AnyVal would be a simple Int on runtime).
But if you do call a .toString method on a value class instance it would print something like:
scala> val myValueClass = X(3)
myValueClass: X = 3
scala> myValueClass.toString
res5: String = X(3)
so I guess the compiler includes some information after all?

Not really. The compiler creates a static method (in Scala this corresponds to the class's companion object) which is called with your int value as a parameter in order to simulate calling a method on your value class-typed object.
Your value class itself only exists in the source code. In compiled bytecode an actual primitive int is used and static methods are called rather than new object instances with real method calls. You can read more about this mechanism here.

Value classes are designed so that adding or removing extends AnyVal (if legal) shouldn't change the results of calculations (except even non-case value classes have equals and hashCode defined automatically like case classes). This requires that in some circumstances they survive, e.g.
def toString(x: Any) = x.toString
toString(myValueClass)
but the situation in your question isn't one of them.
http://docs.scala-lang.org/sips/completed/value-classes.html#expansion-of-value-classes explains more precisely how value classes are implemented and is useful to see in what cases they survive, though some details may have changed since.

Related

Quick Documentation For Scala Apply Constructor Pattern in IntelliJ IDE

I am wondering if there is a way to get the quick documentation in IntelliJ to work for the class construction pattern many scala developers use below.
SomeClass(Param1,Parma2)
instead of
new SomeClass(param1,Param2)
The direct constructor call made with new obviously works but many scala devs use apply to construct objects. When that pattern is used the Intelij documentation look up fails to find any information on the class.
I don't know if there are documents in IntelliJ per se. However, the pattern is fairly easy to explain.
There's a pattern in Java code for having static factory methods (this is a specialization of the Gang of Four Factory Method Pattern), often along the lines of (translated to Scala-ish):
object Foo {
def barInstance(args...): Bar = ???
}
The main benefit of doing this is that the factory controls object instantiation, in particular:
the particular runtime class to instantiate, possibly based on the arguments to the factory. For example, the generic immutable collections in Scala have factory methods which may create optimized small collections if they're created with a sufficiently small amount of contents. An example of this is a sequence of length 1 can be implemented with basically no overhead with a single field referring to the object and a lookup that checks if the offset is 0 and either throws or returns its sole field.
whether an instance is created. One can cache arguments to the factory and memoize or "hashcons" the created objects, or precreate the most common instances and hand them out repeatedly.
A further benefit is that the factory is a function, while new is an operator, which allows the factory to be passed around:
class Foo(x: Int)
object Foo {
def instance(x: Int) = new Foo(x)
}
Seq(1, 2, 3).map(x => Foo(x)) // results in Seq(Foo(1), Foo(2), Foo(3))
In Scala, this is combined with the fact that the language allows any object which defines an apply method to be used syntactically as a function (even if it doesn't extend Function, which would allow the object to be passed around as if it's a function) and with the "companion object" to a class (which incorporates the things that in Java would be static in the class) to get something like:
class Foo(constructor_args...)
object Foo {
def apply(args...): Foo = ???
}
Which can be used like:
Foo(...)
For a case class, the Scala compiler automatically generates a companion object with certain behaviors, one of which is an apply with the same arguments as the constructor (other behaviors include contract-obeying hashCode and equals as well as an unapply method to allow for pattern matching).

Scala Case Classes - Are they just structs?

So I just learned about scala case classes, and I'm told they are used to provide a simple wrapper around a bunch of properties so that it's easier to test for equality. But now I have two questions:
Is this just the same thing as a struct in C++/C#?
Are case classes a value type or a reference type?
First note that a struct in C++ and a struct in C# are very different things.
Structures in C++ are just like regular classes but by default, their members
are public. See this post for more on this topic.
Structures in C# are value types. When passed as a parameter, they are
copied instead of passed via a pointer. This behaviour is similar to a
primitive type in Java. This behaviour is the default in C++, with any
class or struct.
Your second question has been answered in Eric's answer but the important point is that C# structures are passed completely by value (all their fields are copied) while Java/C# classes are passed via a pointer (that is passed by value). See this famous post if you want the full explanation.
Unfortunately, it is not currently possible to have a true value type in JVM bytecode. You cannot make your own type that will be fully copied everytime you pass it. And the answer is no, case classes aren't value types like C# structures. A JVM language may try to replicate the behaviour of a value type but it will be managed by the GC and passed via a pointer (that is passed by value).
To give a more direct answer, no:
Case classes are like regular classes with a few key differences.
Learn more about them on this page.
Not really. What scala case classes are most like is ... scala classes.
They actually are regular scala classes with a few additional methods, that get added to them automatically - namely, .copy on the class itself and .apply and .unapply on the companion object. They also get a nice .toString method, listing all the fields, and .equals, that compares instance members rather than the object ref.
In most other respects, they are just regular scala classes.
Scala classes are just like Java classes. Their reference is passed by value.
Scala case classes are just like scala classes, but some things are automatically generated for you:
The fields of the constructor are publicly accessible (albeit a case class is immutable by default, thus you can regard them as public final values in Java, unless you declare the fields of the case class as var)
An equals and hashCode method based on the fields of the constructor
An apply and unapply method in the companion object
A toString method showing all the values of the constructor
A copy method
Here's an example:
case class MasterOfTheUniverse(name: String, power: Int)
scala> MasterOfTheUniverse("He-Man", 100).name
res1: String = He-Man
scala> MasterOfTheUniverse("He-Man", 100).power
res2: Int = 100
scala> MasterOfTheUniverse("He-Man", 100).toString
res3: String = MasterOfTheUniverse(He-Man,100)
scala> MasterOfTheUniverse("He-Man", 100) == MasterOfTheUniverse("She-Ra", 90)
res4: Boolean = false
scala> MasterOfTheUniverse("She-Ra", 90) == MasterOfTheUniverse("She-Ra", 90)
res6: Boolean = true
scala> MasterOfTheUniverse("He-Man", 100).copy(name = "He-Manatee")
res7: MasterOfTheUniverse = MasterOfTheUniverse(He-Manatee,100)

Why can't I override a method that takes a value-class as parameter in Scala?

I'm playing around with value classes (class that extends AnyVal) in Scala 2.10.3 but are running into a strange compiler error when using them as parameter to abstract methods.
As the following example demonstrates:
class ValueClass(val x: Int) extends AnyVal
trait Test {
def foo(v: ValueClass): Int
}
new Test {
override def foo(v: ValueClass): Int = 1
}
The compiler spits out the following error:
error: bridge generated for member method foo: (v: ValueClass)Int in anonymous class $anon
which overrides method foo: (v: ValueClass)Int in trait Test
clashes with definition of the member itself;
both have erased type (v: Int)Int
override def foo(v: ValueClass): Int = 1
Why doesn't this work? And is there a way to pass a value class into an abstract method?
So as others noted, this issue has been fixed in later versions. If you are curious at all as to what was changed, I suggest you take a look into this pull request.
SI-6260 Avoid double-def error with lambdas over value classes Post-erasure of value classs in method signatures to the underlying
type wreaks havoc when the erased signature overlaps with the generic
signature from an overriden method. There just isn't room for both.
But we really need both; callers to the interface method will be
passing boxed values that the bridge needs to unbox and pass to the
specific method that accepts unboxed values.
This most commonly turns up with value classes that erase to Object
that are used as the parameter or the return type of an anonymous
function.
This was thought to have been intractable, unless we chose a different
name for the unboxed, specific method in the subclass. But that sounds
like a big task that would require call-site rewriting, ala
specialization.
But there is an important special case in which we don't need to
rewrite call sites. If the class defining the method is anonymous,
there is actually no need for the unboxed method; it will only ever
be called via the generic method.
I came to this realisation when looking at how Java 8 lambdas are
handled. I was expecting bridge methods, but found none. The lambda
body is placed directly in a method exactly matching the generic
signature.
This commit detects the clash between bridge and target, and recovers
for anonymous classes by mangling the name of the target method's
symbol. This is used as the bytecode name. The generic bridge forward
to that, as before, with the requisite box/unbox operations.

Using private constructor in a macro

I want to use a private constructor in a macro. This example is a positive integer, but the basic pattern could not only be used for other numeric types like even numbers, but also string derived types like email addresses or a directory name. By making the constructor private the user is denied the opportunity to make an illegal type. I have the following code:
object PosInt
{
import language.experimental.macros
import reflect.runtime.universe._
import reflect.macros.Context
def op(inp: Int): Option[PosInt] = if (inp > 0) Some(new PosInt(inp)) else None
def apply(param: Int): PosInt = macro apply_impl
def apply_impl(c: Context)(param: c.Expr[Int]): c.Expr[PosInt] =
{
import c.universe._
param match {
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] > 0) =>
case Expr(Literal(i)) if (i.value.asInstanceOf[Int] == 0) => c.abort(c.enclosingPosition, "0 is not a positive integer")
case Expr(Literal(i)) => c.abort(c.enclosingPosition, "is not a positive integer")
case _ => c.abort(c.enclosingPosition, "Not a Literal")
}
reify{new PosInt(param.splice)}
}
}
class PosInt (val value: Int) extends AnyVal
However if I make the PosInt Constructor private, although the Macro compiles as expected I get an error if try to use the macro. I can't work out how to build the expression tree manually, but I'm not sure if that would help anyway. Is there anyway I can do this?
You still can't use a private constructor even if PosInt is not a value class. I'll accept an answer that doesn't use a value class. The disadvantage of value classes is that they get type erasure. Plus classes that I'm interested in like subsets of 2d co-ordinates can't be implement as value classes anyway. I'm not actually interested in Positive Integers, I'm just using them as a simple test bed. I'm using Scala 2.11M5. Scala 2.11 will have the addition of the quasiquotes feature. I haven't worked out how to use, quasiquotes yet, as all the material at the moment on them seems to assume a familiarity with Macro Paradise, which I don't have.
Unfortunately for what you are trying to achieve, macros do not work this way. They just manipulate the AST at compile time. Whatever the final result is, it is always something you could have written literally in Scala (without the macro).
Thus, in order to constrain the possible values of PosInt, you will need a runtime check somewhere, either in a public constructor or in a factory method on the companion object.
If runtime exceptions are not palatable to you, then one possible approach would be:
Make the constructor private on the class.
Provide (for example) a create method on the companion object that returns Option[PosInt] (or Try[PosInt], or some other type of your choice that allows you to express a "failure" when the argument is out of range).
Provide an apply method on the companion object similar to your example, which verifies at compile time that the argument is in range and then returns an expression tree that simply calls create(x).get.
Calling .get on the Option is acceptable in this case because you are sure that it will never be None.
The downside is that you have to repeat the check twice: once at compile time, and once at runtime.
I'm not an expert, but I figured I'll give it a shot...
In Java, the scope of a private constructor is limited to the same class... so the PosInt object would need to be moved into the scope of the same class from which it's being called.
With that said, I found an article that shows two ways you can keep the object from being inherited # http://www.developer.com/java/other/article.php/3109251/Stopping-Your-Class-from-Being-Inherited-in-Java-the-Official-Way-and-the-Unofficial-Way.htm
It describes using the "final" keyword in the class declaration to prevent it from being inherited. That's the "official" way. The "unofficial" way is to make the constructor private, but add a public static method that returns an object of the class...
Yes, I know, it is an old question... but it was left unanswered. You never know when an old question will be the top hit in someone's search results...

Trait, FunctionN, or trait-inheriting-FunctionN in Scala?

I have a trait in Scala that has a single method. Call it Computable and the single method is compute(input: Int): Int. I can't figure out whether I should
Leave it as a standalone trait with a single method.
Inherit from (Int => Int) and rename "compute" to "apply."
Just get rid of Computable and use (Int => Int).
A factor in favor of it being a trait is that I could usefully add some additional methods. But of course if they were all implemented in terms of the compute method then I could just break them out into a separate object.
A factor in favor of just using the function type is simplicity and the fact that the syntax for an anonymous function is more concise than that for an anonymous Computable instance. But then I've no way to distinguish objects that are actually Computable instances from other functions that map Int to Int but aren't meant to be used in the same context as Computable.
How do other people approach this type of problem? No right or wrong answers here; I'm just looking for advice.
If you make it a Trait and still want to be able to use the lightweight function syntax, you could also additionally add an implicit conversion in the places where you want them:
scala> trait Computable extends (Int => Int)
defined trait Computable
scala> def computes(c: Computable) = c(5)
computes: (c: Computable)Int
scala> implicit def toComputable(f: Int => Int) = new Computable { def apply(i: Int) = f(i) }
toComputable: (f: (Int) => Int)java.lang.Object with Computable
scala> computes( (i: Int) => i * 2 )
res0: Int = 10
Creating a trait that extends from a function type can be useful for a couple of reasons.
Your function object does something special and non-obvious (and difficult to type), and you can parameterize slight variations in a constructor. For example, suppose you were writing a trait to perform an XPath query on an XML tree. The apply function would hide several kinds of work in constructing the XPath query mechanism, but it's still worthwhile to implement the Function1 interface so that you can query starting from a whole bunch of different nodes using map or flatMap.
As an extension of #1, you want to do some processing at construction time (e.g. parsing the XPath expression and compiling it to run fast), you can do once, ahead of time, in the object's constructor (whereas if you just curried Functions without subclassing, the compilation could only happen at runtime, so it would be repeated for every query.)
You want to pass an encryption function (a type of Function1[String,String]) as an implicit, but not all Function1[String,String]s perform encryption. By deriving from Function1[String,String] and naming the subclass/trait EncryptionFunction, you can ensure that only functions of the right subclass will be passed implicitly. (This isn't true when declaring Type EncryptionFunction = String => String.)
I hope that was clear.
It sounds like you might want to use a structural type. They're also called implicit interfaces.
You could then refactor the methods that currently accept a Computable to accept anything that has a compute(input: Int) method.
One option is to define a type (you can still call it Computable), which is at the moment is Int=>Int. Use it whenever you need the computable stuff. You will get all the benefits of inheriting from Function1. Then if you realize you need some more methods you can change the type to another trait.
At first:
type Computable = Int => Int
Later on:
type Computable = ComputableTrait // with its own methods.
One disadvantage of it is that the type you defined is not really a new type, more a kind of alias. So until you change it to a trait the compiler will still accept other Int => Int functions. At least, you (the developer) can differentiate. When you change to a trait (and the difference becomes important) the compiler will find out when you need a Computable but has an Int => Int.
If you want the compiler to reject other Int => Int -s from day one, then I'd recommend to use a trait, but extend Int => Int. When you need to call it you would still have the more convenient syntax.
Another option might be to have a trait and a companion object with an apply method that accepts an Int => Int and creates a Computable out of that.
Then creating new Computables would be almost as simple as writing plain anonymous functions, but you would still have the type checking (which you would loose with implicit conversion). Additionally you could mix in the trait without problems (but then the companion object's apply can't be used as it is).