CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-scala-lang--scala3-library-sjs1-3

Scala.js-specific runtime library components for Scala 3, providing JavaScript-specific functionality and bridge components between Scala 3 and the Scala.js runtime environment

Pending
Overview
Eval results
Files

derivation.mddocs/

Derivation System

Mirror-based generic programming for automatic derivation of type class instances, supporting both sum types (enums) and product types (case classes).

Capabilities

Mirror Types

Core mirror types for compile-time reflection and generic programming.

/**
 * Base trait for compile-time reflection of types
 * Provides type-level access to the structure of enums, case classes, and objects
 */
sealed trait Mirror:
  /** The type being mirrored */
  type MirroredMonoType
  /** String name of the mirrored type */
  type MirroredLabel <: String  
  /** Tuple of element names (field names for products, case names for sums) */
  type MirroredElemLabels <: Tuple

/**
 * Mirror for sum types (sealed traits, enums)
 * Provides ordinal access to sum type variants
 */
trait Mirror.Sum extends Mirror:
  /** Get ordinal (index) of sum type instance */
  def ordinal(x: MirroredMonoType): Int

/**
 * Mirror for product types (case classes, tuples)
 * Provides construction from generic product representation
 */
trait Mirror.Product extends Mirror:  
  /** Element types of the product */
  type MirroredElemTypes <: Tuple
  /** Create instance from product representation */
  def fromProduct(p: scala.Product): MirroredMonoType

/**
 * Mirror for singleton types (objects, case objects)
 */
trait Mirror.Singleton extends Mirror.Product:
  type MirroredElemTypes = EmptyTuple
  def fromProduct(p: scala.Product): MirroredMonoType

/**
 * Mirror proxy for Scala 2 compatibility
 */
trait Mirror.SingletonProxy extends Mirror.Singleton

Type Aliases:

object Mirror:
  /** Mirror of any kind for type T */
  type Of[T] = Mirror { type MirroredMonoType = T }
  /** Product mirror for type T */
  type ProductOf[T] = Mirror.Product { type MirroredMonoType = T }
  /** Sum mirror for type T */
  type SumOf[T] = Mirror.Sum { type MirroredMonoType = T }

Usage Examples:

import scala.deriving.Mirror

// Example types
enum Color:
  case Red, Green, Blue

case class Person(name: String, age: Int)

case object Singleton

// Using mirrors
def showStructure[T](value: T)(using mirror: Mirror.Of[T]): String =
  val typeName = constValue[mirror.MirroredLabel]
  s"Type: $typeName"

// Sum type mirror
def getOrdinal[T](value: T)(using mirror: Mirror.SumOf[T]): Int =
  mirror.ordinal(value)

val red = Color.Red
println(getOrdinal(red))  // 0

// Product type mirror  
def fromTuple[T](tuple: Tuple)(using mirror: Mirror.ProductOf[T]): T =
  mirror.fromProduct(tuple.asInstanceOf[Product])

val personTuple = ("Alice", 30)
val person = fromTuple[Person](personTuple.asInstanceOf[Tuple])

Generic Programming Patterns

Common patterns for writing generic code using mirrors.

// Type class derivation pattern
trait Show[T]:
  def show(value: T): String

object Show:
  /** Derive Show for product types */
  inline def derived[T](using mirror: Mirror.ProductOf[T]): Show[T] = 
    new Show[T]:
      def show(value: T): String = 
        val typeName = constValue[mirror.MirroredLabel]
        val elemLabels = constValueTuple[mirror.MirroredElemLabels]
        // Implementation details...
        s"$typeName(...)"

  /** Derive Show for sum types */
  inline def derived[T](using mirror: Mirror.SumOf[T]): Show[T] =
    new Show[T]:
      def show(value: T): String =
        val typeName = constValue[mirror.MirroredLabel]
        val ordinal = mirror.ordinal(value)
        s"$typeName#$ordinal"

Usage Examples:

// Automatic derivation
case class Point(x: Double, y: Double) derives Show

enum Status derives Show:
  case Active, Inactive, Pending

// Using derived instances
val point = Point(1.0, 2.0)
println(summon[Show[Point]].show(point))  // "Point(...)"

val status = Status.Active  
println(summon[Show[Status]].show(status))  // "Status#0"

// Manual derivation
given Show[Person] = Show.derived

val alice = Person("Alice", 30)
println(summon[Show[Person]].show(alice))

Advanced Derivation Techniques

Advanced patterns for complex generic programming scenarios.

// Recursive derivation for nested structures
trait Eq[T]:
  def eqv(x: T, y: T): Boolean

object Eq:
  given Eq[String] = _ == _
  given Eq[Int] = _ == _
  given Eq[Boolean] = _ == _
  
  given [T](using eq: Eq[T]): Eq[Option[T]] = 
    (x, y) => (x, y) match
      case (Some(a), Some(b)) => eq.eqv(a, b)
      case (None, None) => true
      case _ => false
      
  given [T](using eq: Eq[T]): Eq[List[T]] =
    (xs, ys) => xs.length == ys.length && xs.zip(ys).forall(eq.eqv)

  inline def derived[T](using mirror: Mirror.Of[T]): Eq[T] = 
    inline mirror match
      case m: Mirror.SumOf[T] => derivedSum(using m)
      case m: Mirror.ProductOf[T] => derivedProduct(using m)
      
  private inline def derivedSum[T](using mirror: Mirror.SumOf[T]): Eq[T] =
    (x, y) => mirror.ordinal(x) == mirror.ordinal(y) && x == y
    
  private inline def derivedProduct[T](using mirror: Mirror.ProductOf[T]): Eq[T] =
    (x, y) => 
      val xProduct = Tuple.fromProductTyped(x)
      val yProduct = Tuple.fromProductTyped(y) 
      compareProducts(xProduct, yProduct)
      
  private def compareProducts[T <: Tuple](x: T, y: T): Boolean =
    // Implementation for comparing tuple elements recursively
    x == y  // Simplified

Usage Examples:

// Derive equality for complex nested types
case class Address(street: String, city: String)
case class Person(name: String, age: Int, address: Address) derives Eq

val alice1 = Person("Alice", 30, Address("Main St", "NYC"))
val alice2 = Person("Alice", 30, Address("Main St", "NYC"))
val bob = Person("Bob", 25, Address("Oak Ave", "LA"))

println(summon[Eq[Person]].eqv(alice1, alice2))  // true
println(summon[Eq[Person]].eqv(alice1, bob))     // false

Tuple Derivation Support

Utilities for working with tuples in generic programming.

object Tuple:
  /** Convert any Product to a tuple with proper typing */
  def fromProductTyped[P <: Product](p: P): Tuple = 
    fromProduct(p).asInstanceOf[Tuple]
    
  /** Convert Product to untyped tuple */
  def fromProduct(p: Product): Tuple =
    // Convert product to tuple representation
    ???

  /** Get size of tuple type at compile time */
  inline def size[T <: Tuple]: Int = constValue[Size[T]]
  
  /** Map over tuple with type-level function */
  inline def map[T <: Tuple, F[_]](tuple: T)(f: [X] => X => F[X]): Map[T, F] = ???

Usage Examples:

// Working with products as tuples
case class Point3D(x: Double, y: Double, z: Double)

val point = Point3D(1.0, 2.0, 3.0)
val tuple = Tuple.fromProductTyped(point)  // (1.0, 2.0, 3.0)

// Type-level size computation
type Coords = (Double, Double, Double)
val size = Tuple.size[Coords]  // 3

// Type-level mapping
val optionalCoords = Tuple.map((1.0, 2.0, 3.0))(
  [X] => (x: X) => Option(x)
)  // (Some(1.0), Some(2.0), Some(3.0))

Label Utilities

Working with compile-time labels and names.

/**
 * Extract field names from a mirror as a tuple of strings
 */
inline def labelValues[T](using mirror: Mirror.Of[T]): Tuple =
  constValueTuple[mirror.MirroredElemLabels]

/**
 * Get type name as string
 */
inline def typeName[T](using mirror: Mirror.Of[T]): String =
  constValue[mirror.MirroredLabel]

Usage Examples:

case class User(id: Int, name: String, email: String)

// Get field names at compile time
val fieldNames = labelValues[User]  // ("id", "name", "email")
val className = typeName[User]      // "User"

// Use in generic serialization
def toMap[T](value: T)(using mirror: Mirror.ProductOf[T]): Map[String, Any] =
  val labels = labelValues[T].toArray.map(_.toString)
  val values = Tuple.fromProductTyped(value).toArray
  labels.zip(values).toMap

val user = User(1, "Alice", "alice@example.com")  
val userMap = toMap(user)
// Map("id" -> 1, "name" -> "Alice", "email" -> "alice@example.com")

Integration with Type Classes

Seamless integration with common type class patterns.

// Common derivable type classes work automatically
trait Ordering[T]:
  def compare(x: T, y: T): Int

trait Encoder[T]:
  def encode(value: T): String
  
trait Decoder[T]:
  def decode(input: String): Either[String, T]

// Standard derives syntax works
case class Product(name: String, price: Double) 
  derives Eq, Show, Ordering, Encoder, Decoder

enum Priority derives Eq, Show, Ordering:
  case Low, Medium, High

Types

// Core mirror types
sealed trait Mirror:
  type MirroredMonoType
  type MirroredLabel <: String
  type MirroredElemLabels <: Tuple

trait Mirror.Sum extends Mirror:
  def ordinal(x: MirroredMonoType): Int

trait Mirror.Product extends Mirror:
  type MirroredElemTypes <: Tuple  
  def fromProduct(p: scala.Product): MirroredMonoType

trait Mirror.Singleton extends Mirror.Product:
  type MirroredElemTypes = EmptyTuple

trait Mirror.SingletonProxy extends Mirror.Singleton

// Type aliases
object Mirror:
  type Of[T] = Mirror { type MirroredMonoType = T }
  type ProductOf[T] = Mirror.Product { type MirroredMonoType = T }  
  type SumOf[T] = Mirror.Sum { type MirroredMonoType = T }

Install with Tessl CLI

npx tessl i tessl/maven-org-scala-lang--scala3-library-sjs1-3

docs

annotations.md

capabilities.md

collections.md

core-types.md

derivation.md

index.md

metaprogramming.md

runtime.md

utilities.md

tile.json