Programmatic Structural Types - More Details

Syntax

SimpleType    ::= ... | Refinement
Refinement    ::= ‘{’ RefineStatSeq ‘}’
RefineStatSeq ::=  RefineStat {semi RefineStat}
RefineStat    ::= ‘val’ VarDcl | ‘def’ DefDcl | ‘type’ {nl} TypeDcl

Implementation of structural types

The standard library defines a trait Selectable in the package scala, defined as follows:

trait Selectable extends Any {
  def selectDynamic(name: String): Any
  def applyDynamic(name: String, paramClasses: ClassTag[_]*)(args: Any*): Any =
    new UnsupportedOperationException("applyDynamic")
}

An implementation of Selectable that relies on Java reflection is available in the standard library: scala.reflect.Selectable. Other implementations can be envisioned for platforms where Java reflection is not available.

selectDynamic takes a field name and returns the value associated with that name in the Selectable. Similarly, applyDynamic takes a method name, ClassTags representing its parameters types and the arguments to pass to the function. It will return the result of calling this function with the given arguments.

Given a value v of type C { Rs }, where C is a class reference and Rs are refinement declarations, and given v.a of type U, we consider three distinct cases:

We make sure that r conforms to type Selectable, potentially by introducing an implicit conversion, and then call either selectDynamic or applyDynamic, passing the name of the member to access, along with the class tags of the formal parameters and the arguments in the case of a method call. These parameters could be used to disambiguate one of several overload variants in the future, but overloads are not supported in structural types at the moment.

Limitations of structural types

Differences with Scala 2 structural types

Migration

Receivers of structural calls need to be instances of Selectable. A conversion from Any to Selectable is available in the standard library, in scala.reflect.Selectable.reflectiveSelectable. This is similar to the implementation of structural types in Scala 2.

Reference

For more info, see Rethink Structural Types.