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
—
Boundary-based control flow, utility types, and helper functions including structured exception-like control flow and advanced utility classes.
Structured control flow using boundary/break pattern for non-local returns.
/**
* Boundary control flow system providing structured "break" functionality
*/
object boundary:
/**
* Create a boundary with a label, enabling break operations within the block
*/
def apply[T](body: Label[T] ?=> T): T
/**
* Break from the nearest enclosing boundary with a value
*/
def break[T](value: T)(using Label[T]): Nothing
/**
* Break from the nearest enclosing boundary without a value (Unit)
*/
def break()(using Label[Unit]): Nothing
/**
* Label type for boundary operations
* Represents a typed break target within a boundary
*/
sealed abstract class Label[-T]
/**
* Exception type used internally for break operations
*/
final class Break[T](val value: T) extends Throwable with scala.util.control.ControlThrowableUsage Examples:
import scala.util.boundary
import scala.util.boundary.break
// Basic boundary usage
val result = boundary {
for i <- 1 to 100 do
if i > 50 then break(i)
println(i)
-1 // Default value if no break
}
println(result) // 51
// Boundary with Unit return type
boundary {
val items = List(1, 2, 3, 4, 5)
for item <- items do
if item == 3 then break()
println(s"Processing $item")
}
// Nested boundaries with different types
val nested = boundary[String] {
boundary[Int] {
if someCondition then break(42)
if otherCondition then break("early exit") // Breaks outer boundary
100
}.toString
}
// Early return from function
def findFirst[T](items: List[T])(predicate: T => Boolean): Option[T] =
boundary[Option[T]] {
for item <- items do
if predicate(item) then break(Some(item))
None
}
val numbers = List(1, 2, 3, 4, 5)
val found = findFirst(numbers)(_ > 3) // Some(4)
// Complex control flow
def processData(data: List[String]): Either[String, List[Int]] =
boundary[Either[String, List[Int]]] {
val results = data.map { str =>
str.toIntOption match
case Some(num) => num
case None => break(Left(s"Invalid number: $str"))
}
Right(results)
}Advanced utility types for type-level programming and implicit resolution.
/**
* Negation in implicit search - provides evidence that no instance of T exists
* Useful for conditional compilation and type-level branching
*/
final class NotGiven[+T] private():
/** Get the singleton NotGiven value */
def value: NotGiven[Nothing] = NotGiven.value
object NotGiven:
/** Singleton NotGiven value */
val value: NotGiven[Nothing] = new NotGiven[Nothing]
/** Provide NotGiven[T] if no given T is available */
given [T](using NotGiven[T]): NotGiven[T] = value.asInstanceOf[NotGiven[T]]Usage Examples:
// Conditional compilation based on available implicits
trait JsonEncoder[T]:
def encode(value: T): String
given JsonEncoder[String] = _.toString
given JsonEncoder[Int] = _.toString
def toJson[T](value: T)(using encoder: JsonEncoder[T]): String =
encoder.encode(value)
def toJsonOrFallback[T](value: T)(using encoder: NotGiven[JsonEncoder[T]]): String =
s"No encoder available for ${value.getClass.getSimpleName}"
// This works - encoder available
val jsonString = toJson("hello")
// This works - no encoder available
val fallback = toJsonOrFallback(List(1, 2, 3))Utilities for converting between tupled and untupled function forms.
/**
* Type class for converting between regular functions and tupled functions
* Experimental feature for functional programming patterns
*/
sealed trait TupledFunction[F, G]:
/** Convert regular function to tupled form */
def tupled(f: F): G
/** Convert tupled function to regular form */
def untupled(g: G): F
object TupledFunction:
// Instances for different arities
given TupledFunction[A => R, Tuple1[A] => R] = ???
given TupledFunction[(A, B) => R, ((A, B)) => R] = ???
given TupledFunction[(A, B, C) => R, ((A, B, C)) => R] = ???
// ... more aritiesUsage Examples:
// Convert between function forms
val add: (Int, Int) => Int = _ + _
val tupledAdd: ((Int, Int)) => Int = TupledFunction.tupled(add)
val untupledAdd: (Int, Int) => Int = TupledFunction.untupled(tupledAdd)
// Use with higher-order functions
val pairs = List((1, 2), (3, 4), (5, 6))
val sums = pairs.map(tupledAdd) // List(3, 7, 11)
// Functional composition
def compose[A, B, C](f: A => B, g: B => C): A => C = a => g(f(a))
def composeT[A, B, C](f: ((A, B)) => C): (A => B) => A => C =
g => a => f((a, g(a)))Utilities for parsing command line arguments and options.
/**
* Command line parser with support for options, flags, and arguments
*/
object CommandLineParser:
/** Parse command line arguments into structured format */
def parse(args: Array[String]): ParseResult
/** Create parser with specific configuration */
def create(config: ParserConfig): CommandLineParser
/**
* Result of command line parsing
*/
case class ParseResult(
options: Map[String, String],
flags: Set[String],
arguments: List[String],
errors: List[String]
)
/**
* Configuration for command line parser
*/
case class ParserConfig(
supportedOptions: Set[String],
supportedFlags: Set[String],
allowUnknown: Boolean = false
)Usage Examples:
// Basic parsing
val args = Array("--verbose", "--output", "result.txt", "input.txt")
val result = CommandLineParser.parse(args)
println(result.flags) // Set("verbose")
println(result.options) // Map("output" -> "result.txt")
println(result.arguments) // List("input.txt")
// Custom parser
val config = ParserConfig(
supportedOptions = Set("output", "config"),
supportedFlags = Set("verbose", "help"),
allowUnknown = false
)
val parser = CommandLineParser.create(config)
val customResult = parser.parse(args)
// Pattern matching on results
customResult match
case ParseResult(opts, flags, args, Nil) if flags.contains("help") =>
println("Help requested")
case ParseResult(opts, flags, args, Nil) =>
println(s"Processing with options: $opts")
case ParseResult(_, _, _, errors) =>
println(s"Parsing errors: ${errors.mkString(", ")}")Type-safe number parsing from strings with compile-time validation.
/**
* Type class for parsing numbers from strings
* Provides compile-time validation for number formats
*/
trait FromDigits[T]:
/** Parse string to number, may throw exception */
def fromDigits(digits: String): T
object FromDigits:
given FromDigits[Int] = _.toInt
given FromDigits[Long] = _.toLong
given FromDigits[Float] = _.toFloat
given FromDigits[Double] = _.toDouble
given FromDigits[BigInt] = BigInt(_)
given FromDigits[BigDecimal] = BigDecimal(_)
/**
* Extension methods for string to number conversion
*/
extension (s: String)
/** Convert string to number of type T */
def parseAs[T](using FromDigits[T]): T = summon[FromDigits[T]].fromDigits(s)
/** Safe conversion returning Option */
def parseAsOption[T](using FromDigits[T]): Option[T] =
try Some(parseAs[T]) catch case _ => NoneUsage Examples:
// Type-safe number parsing
val intValue = "42".parseAs[Int] // 42
val longValue = "123456789".parseAs[Long] // 123456789L
val doubleValue = "3.14159".parseAs[Double] // 3.14159
// Safe parsing with Option
val validInt = "42".parseAsOption[Int] // Some(42)
val invalidInt = "abc".parseAsOption[Int] // None
// Custom number types
case class UserId(value: Int)
given FromDigits[UserId] = s => UserId(s.toInt)
val userId = "12345".parseAs[UserId] // UserId(12345)
// Compile-time validation for literals
inline def parseAtCompileTime[T](inline s: String)(using FromDigits[T]): T =
inline s match
case _ => compiletime.constValue[T] // Simplified - actual implementation more complexSupport for non-local return patterns with proper resource management.
/**
* Non-local return support with proper cleanup
*/
object NonLocalReturns:
/** Execute block with non-local return capability */
def returning[T](body: ReturnThrowable[T] ?=> T): T
/** Throw non-local return with value */
def throwReturn[T](value: T)(using ReturnThrowable[T]): Nothing
/**
* Capability for non-local returns
*/
sealed class ReturnThrowable[T] extends Throwable with scala.util.control.ControlThrowableUsage Examples:
import scala.util.control.NonLocalReturns.*
// Non-local return from nested function
def findFirstMatch(data: List[List[String]], target: String): Option[String] =
returning {
for
sublist <- data
item <- sublist
do
if item.contains(target) then
throwReturn(Some(item))
None
}
// Early exit from complex processing
def processComplexData(data: ComplexData): ProcessResult =
returning {
val stage1 = processStage1(data)
if stage1.hasErrors then throwReturn(ProcessResult.failure("Stage 1 failed"))
val stage2 = processStage2(stage1)
if stage2.hasErrors then throwReturn(ProcessResult.failure("Stage 2 failed"))
val stage3 = processStage3(stage2)
ProcessResult.success(stage3)
}// Boundary control flow types
object boundary:
def apply[T](body: Label[T] ?=> T): T
def break[T](value: T)(using Label[T]): Nothing
def break()(using Label[Unit]): Nothing
sealed abstract class Label[-T]
final class Break[T](val value: T) extends Throwable
// Utility types
final class NotGiven[+T] private():
def value: NotGiven[Nothing]
sealed trait TupledFunction[F, G]:
def tupled(f: F): G
def untupled(g: G): F
// Command line parsing types
case class ParseResult(
options: Map[String, String],
flags: Set[String],
arguments: List[String],
errors: List[String]
)
case class ParserConfig(
supportedOptions: Set[String],
supportedFlags: Set[String],
allowUnknown: Boolean
)
// Number parsing types
trait FromDigits[T]:
def fromDigits(digits: String): T
// Non-local returns
sealed class ReturnThrowable[T] extends ThrowableInstall with Tessl CLI
npx tessl i tessl/maven-org-scala-lang--scala3-library-sjs1-3