I need a map-like mutable data structure in Scala that is covariant in it's value type parameter. This is impossible to implement in Scala because mutable data structures are invariant in their type parameters. I understand the rationale for that decision, however, since that data structure will not be publicly exposed I need some "unsafe" variant of this data structure. How would you implement an alternative for this in Scala?
Related
Does the Scala Option type incur an overhead of two objects per primitive type value? In other words, is the Option type specialized for primitives, or does it always double-box them (I'm counting Some(...) as a box)?
The current collection framework favors the use of to method in order to convert to the target collection type, and with an implicit conversion available from various collection companion objects to the Factory argument, this creates a neat, uniform interface. It unfortunately makes very hard optimisations which were easy in the old framework with CanBuildFrom. Lets say I have a custom collection type Unique[T], which is a combination of Set and Seq in that the order in which elements follows the order of insertion, but any element can occur only once. Because it offers fast indexOf, apply(i :Int) and contains, conversions to both Set and Seq can be O(1) with a simple wrapper. I can override toSet and toSeq, but I see no way of determining inside to (other than extremely questionable reflection) that the target factory builds Seq or Set, because the Factory implementation used by the implicit conversion is generic and not a prototype instance like old ReusableCBF.
In case of Set or List, the choice seems to be easier, but what do I do for Java's Collection, Iterable equivalent? Do I go for Seq? Traversable? GenTraversableOnce?
You need to decide based on your need. For example: According to Scala Documentation the definition of Seq is
Sequences are special cases of iterable collections of class Iterable. Unlike iterables, sequences always have a defined order of elements. Sequences provide a method apply for indexing.
So if you want to benefit ordering or you want to retrieve element by index you can use Seq
Again according to Scala Documentation if you are mainly interested in iteration over your Collection Traversable is sufficient
Just notice that there is a general good practice that for your function signature like function return type, use more general (abstract) data type to prevent unnecessary performance penalty for the function callers.
As often, it will depend on the needs of your caller.
Traversable is pretty high level (you only get foreach) but it might be sufficient. Seq would be used if you need a defined order of elements. GenTraversableOnce would be a bit abstract for me and possibly for your fellow coders.
Introduction
I am working on an API written in Scala. I use data transfer objects (DTOs) as parameters passed to the API's functions. The DTOs will be instanciated by the API's user.
As the API is pretty abstract / generic I want to specify the attributes of a object that the API should operate on. Example:
case class Person(name: String, birthdate: Date)
When an instance of Person "P" is passed to the API, the API needs to know the attributes of "P" it should operate on: either just name or birthdate, or both of them.
So I need to design a DTO that contains the instance of "P" itself, some kind of declaration of the attributes and maybe additional information on the type of "P".
String based approach
One way would be to use Strings to specify the attributes of "P" and maybe its type. This would be relatively simple, as Strings are pretty lightweight and well known. As there is a formal notation of packages, types and members as Strings, the declarations would structured to a certain degree.
On the other side, the String-declarations must be validated, because a user might pass invalid Strings. I could imagine types that represent the attributes with dedicated types instead of String, which may have the benefit of increased structure and maybe even those type are designed so that only valid instances can exist.
Reflection API approach
Of course the reflection API came to my mind and I am experimenting to declare the attributes with types out of the reflection API. Unfortunately the scala 2.10.x reflection API is a bit unintuitive. There are names, symbols, mirrors, types, typetags which can cause a bit of confusion.
Basically I see two alternatives to attribute declaration with Strings:
Attribute declaration with reflection API's "Names"
Attribute declaration with reflection API's "Symbols" (especially TermSymbol)
If I go this way, as far as I can see, the API's user, who constructs the DTOs, will have to deal with the reflection API and its Names / Symbols. Also the API's implementation will have to make use of the reflection API. So there are two places with reflective code and the user must have at least a little bit of knowledge of the reflection API.
Questions
However I don't know how heavyweight these approaches are:
Are Names or Symbols expensive to construct?
Does the reflection API do any caching of expensive operation results or should I take care about that?
Are Names and Symbols transferable to another JVM via network?
Are they serializable?
Main question: Are scala reflection API Names or Symbols adequate for use inside transfer objects?
It seems complicated to do this with the reflection API. Any hints are welcome. And any hints on other alternatives, too.
P.S.: I did not include my own code, yet, because my API is complex and the reflection part is in pretty experimental state. Maye I can deliver something useful later.
1a) Names are easy to construct and are lightweight, as they are just a bit more than strings.
1b) Symbols can't be constructed by the user, but are created internally when one resolves names using APIs like staticClass or member. First calls to such APIs usually involve unpacking type signatures of symbol's owners from ScalaSignature annotations, so they might be costly. Subsequent calls use already loaded signatures, but still pay the cost of a by-name lookup in a sort of a hashtable (1). declaration costs less than member, because declaration doesn't look into base classes.
2) Type signatures (e.g. lists of members of classes, params + return type of methods, etc) are loaded lazily and therefore are cached. Mappings between Java and Scala reflection artifacts are cached as well (2). To the best of my knowledge, the rest (e.g. subtyping checks) is generally uncached with a few minor exceptions.
3-4) Reflection artifacts depend on their universe and at the moment can't be serialized (3).
How can I refer to ArrayBuffer and Vector in a more generic way?
For example - one of my functions takes a Vector as an argument, while another returns an ArrayBuffer.
What is a common "iterface" that I can use?
For example, in Java I could use List or Collection interface to pass them around.
See here for an overview of the inheritance relationship between the collections classes.
You'll see that IndexedSeq is a common trait for both ArrayBuffer and Vector.
EDIT: IndexedSeq vs. Seq:
From the doc: Indexed sequences do not add any new methods wrt Seq, but promise efficient implementations of random access patterns. This means that, in this context, you could just as well use Seq, as the implementations will be provided by ArrayBuffer and Vector in any case.
I would use SeqLike or more generic TraversableOnce which would also apply for Maps.