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
—
Experimental capture checking system for capability-safe programming, providing fine-grained control over side effects and resource access.
Foundation types for the capability system.
/**
* Base trait for all capability classes
* Capabilities represent permissions or resources that can be captured
*/
trait Capability extends Any
/**
* Universal capture reference representing all capabilities
* Used in function signatures to indicate capture of all capabilities
*/
object cap extends Capability
/**
* Carrier trait for capture set type parameters
* Used internally for representing sets of captured capabilities
*/
trait CapSet extends Any
/**
* Constraint that capture set C contains capability R
* Used in type signatures to express capture requirements
*/
sealed trait Contains[+C, R]
/**
* Existential capability types for abstraction over unknown capabilities
*/
sealed trait Exists extends CapabilityUsage Examples:
import scala.caps.*
// Function that requires no capabilities
def pureFunction(x: Int): Int = x * 2
// Function that captures the universal capability
def impureFunction(): Unit = {
println("Side effect!") // Requires cap capability
}
// Function with explicit capability parameter
def withCapability[C <: Capability](f: C => Unit)(using c: C): Unit = f(c)
// Using capability constraints
def constrainedFunction[C](using Contains[C, java.io.FileSystem]): Unit = {
// Can perform file operations
}Capability system for exception handling.
/**
* Capability for throwing exceptions of type E
* Erased at runtime - only provides compile-time tracking
*/
erased class CanThrow[-E <: Exception] extends Capability
object CanThrow:
/** Unsafe capability that can throw any exception */
object unsafeExceptions:
given canThrowAny: CanThrow[Exception] = ???Usage Examples:
import scala.caps.CanThrow
// Function that can throw IOException
def readFile(path: String)(using CanThrow[java.io.IOException]): String = {
// File reading implementation that might throw IOException
scala.io.Source.fromFile(path).mkString
}
// Function that handles the capability
def safeReadFile(path: String): Either[Exception, String] = {
try {
given CanThrow[java.io.IOException] = CanThrow.unsafeExceptions.canThrowAny
Right(readFile(path))
} catch {
case e: Exception => Left(e)
}
}
// Multiple exception types
def riskyOperation()(using CanThrow[IllegalArgumentException], CanThrow[java.io.IOException]): Unit = {
if (scala.util.Random.nextBoolean())
throw new IllegalArgumentException("Random failure")
else
throw new java.io.IOException("IO failure")
}Annotations for expressing reachability of capabilities.
/**
* Annotation for marking reach capabilities
* Used to express that a capability can be reached through method calls
*/
final class use extends annotation.StaticAnnotationUsage Examples:
import scala.caps.use
// Method that reaches a capability through its parameter
def processWithReach(@use resource: FileReader): String = {
resource.read() // The capability is "reached" through the parameter
}
// Class with reach capability annotation
class Service(@use connection: DatabaseConnection) {
def query(sql: String): ResultSet = connection.execute(sql)
}Escape hatches for capability system constraints.
/**
* Mark constructor parameters as untracked by the capture checker
*/
object untrackedCaptures
/**
* Remove all capture sets from a value's type
* Use with extreme caution - bypasses capability safety
*/
def unsafeAssumePure[T](x: T): T = x
/**
* Suppress separation checks for the given operation
* Allows potentially unsafe capability mixing
*/
def unsafeAssumeSeparate(op: Any): op.type = opUsage Examples:
import scala.caps.unsafe.*
// Remove capture tracking (unsafe)
def makePure[T](impureValue: T): T = {
unsafeAssumePure(impureValue) // Now treated as pure
}
// Bypass separation checks
def mixCapabilities(cap1: SomeCapability, cap2: AnotherCapability): Unit = {
unsafeAssumeSeparate {
// Operations that would normally violate separation
cap1.operation()
cap2.operation()
}
}
// Constructor with untracked parameters
class UnsafeService(connection: DatabaseConnection) extends untrackedCapabilities:
// connection is not tracked by capture checker
def query(sql: String) = connection.execute(sql)Internal utilities for capability system implementation.
/**
* Wrapper for capture argument lists
* Used internally by the compiler for capability inference
*/
def capsOf[CS]: Any = ???
extension (x: Any)
/**
* Reach capability encoding for internal use
* Expresses that x reaches some capability
*/
def reachCapability: x.type = xUsage Examples:
import scala.caps.internal.*
// Internal use - typically handled by compiler
def internalCapabilityProcessing[CS](): Unit = {
val caps = capsOf[CS]
// Internal capability manipulation
}
// Reach capability extension (compiler-generated)
def someMethod(resource: FileHandle): Unit = {
val reachable = resource.reachCapability
// Express that resource's capabilities are reachable
}Common patterns for using capabilities in real applications.
// Resource management pattern
trait Resource extends Capability:
def close(): Unit
class FileResource(path: String) extends Resource:
def read(): String = ???
def close(): Unit = ???
def withResource[T, R <: Resource](resource: R)(f: R => T): T = {
try f(resource)
finally resource.close()
}
// IO capability pattern
trait IO extends Capability
object IO:
given globalIO: IO = new IO {}
def println(s: String)(using IO): Unit = {
scala.Predef.println(s) // Requires IO capability
}
// Network capability pattern
trait Network extends Capability
class HttpClient(using Network):
def get(url: String): String = ???
def post(url: String, data: String): String = ???
// Database capability pattern
trait Database extends Capability:
def query(sql: String): List[Map[String, Any]]
def execute(sql: String): Int
class Repository(using db: Database):
def findUser(id: Int): Option[User] = {
val results = db.query(s"SELECT * FROM users WHERE id = $id")
results.headOption.map(User.fromMap)
}Usage Examples:
// Resource management
val result = withResource(FileResource("data.txt")) { file =>
file.read()
}
// IO operations
given IO = IO.globalIO
println("Hello, capabilities!") // Requires IO capability
// Network operations
given Network = new Network {}
val client = HttpClient()
val response = client.get("https://api.example.com/data")
// Database operations
given Database = new Database {
def query(sql: String) = List(Map("id" -> 1, "name" -> "Alice"))
def execute(sql: String) = 1
}
val repo = Repository()
val user = repo.findUser(1)// Core capability types
trait Capability extends Any
object cap extends Capability
trait CapSet extends Any
sealed trait Contains[+C, R]
sealed trait Exists extends Capability
// Exception capabilities
erased class CanThrow[-E <: Exception] extends Capability
// Annotations
final class use extends annotation.StaticAnnotation
// Unsafe operations
object untrackedCaptures
def unsafeAssumePure[T](x: T): T
def unsafeAssumeSeparate(op: Any): op.type
// Internal support
def capsOf[CS]: Any
extension (x: Any) def reachCapability: x.typeInstall with Tessl CLI
npx tessl i tessl/maven-org-scala-lang--scala3-library-sjs1-3