简体   繁体   中英

working around type erasure — recommended way?

After Scala-2.10 the situation has changed, since there is now a dedicated reflection system .
What is the recommended , best-practice , standard way the community has settled down on in order to amend the deficiencies created by type erasure?

The situation

We all know that the underlying runtime system (JVM / bytecode) is lacking the ability to fully represent parametrised types in a persistent way. This means that the Scala type system can express elaborate type relationships, which lack an unambiguous representation in plain JVM byte code.

Thus, when creating a concrete data instance, the context of the creation contains specific knowledge about the fine points of the embedded data. As long as the creation context is connected to the usage context in a statical fashion , ie as long as both are connected directly within a single compilation process, everything is fine, since we stay in "scala realm" where any specific type knowledge can be passed within the compiler.

But as soon as our data instance (object instance) passes a zone where only JVM bytecode properties are guaranteed, this link is lost. This might happen eg when

  • sending the data element as message to another Actor
  • passing it through subsystems written in other JVM languages (eg an OR-Mapper and RDBMS storage)
  • feeding the data through JVM Serialisation and any marshalling techniques built on top
  • and even just within Scala, passing through any function signature which discards specific type parameter information and retains only some type bound (eg Seq[AnyRef] ) or an existential type ( Seq[_] )

Thus we need a way to marshal the additional specific type information.

An Example

Let's assume we use a type Document[Format] . Documents are sent and retrieved through a family of external service APIs, which mostly talk in JSON format (and are typically not confined to usage from Java alone). Obviously, for some specific kinds of Format , we can write type classes to hold the knowledge how to parse that JSON and convert it into explicit Scala types. But clearly there is no hope for one coherent type hierarchy to cover any kind of Document[Format] (beyond the mere fact that it is a formatted document and can be converted). It figures that we can handle all the generic concerns elegantly (distributing load, handling timeouts and availability of some API / service, keeping a persistent record of data). But for any actual "business" functionality, we need to switch over to specific types eventually.

The Quest

Since the JVM bytecode can not represent the type information we need, without any doubt we need to allocate some additional metadata field within our Document[Format] to represent the information "this document has Format XYZ". So, by looking at that piece of metadata, we can re-gain the fully typed context later on.

My question is about the preferred, most adequate, most elegant, most idiomatic way of solving this problem. That is, in current Scala (>= Scala-2.10).

  • how to represent the additional type information (ie the Format in the example above)? Storing Format.class in the document object? or using a type tag? or would you rather recommend a symbolic representation, eg 'Format or "my.package.Format"
  • or would you rather recommend to store the full type information, eg Document[Format] , and which representation is recommended?
  • what is the most concise, most clear, most clean, most readable and self-explanatory solution in code to re-establish the full type context? Using some kind of pattern match? Using some implicit? Using a type class or view bound?

What have people found out to work well in this situation?

Scala documentation: http://docs.scala-lang.org/overviews/reflection/typetags-manifests.html

From the article:

Like scala.reflect.Manifest, TypeTags can be thought of as objects which carry along all type information available at compile time, to runtime. For example, TypeTag[T] encapsulates the runtime type representation of some compile-time type T. Note however, that TypeTags should be considered to be a richer replacement of the pre-2.10 notion of a Manifest, that are additionally fully integrated with Scala reflection.

You should also look at Manifests.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM