or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

annotations.mdcapabilities.mdcollections.mdcore-types.mdderivation.mdindex.mdmetaprogramming.mdruntime.mdutilities.md

utilities.mddocs/

0

# Control Flow and Utilities

1

2

Boundary-based control flow, utility types, and helper functions including structured exception-like control flow and advanced utility classes.

3

4

## Capabilities

5

6

### Boundary Control Flow

7

8

Structured control flow using boundary/break pattern for non-local returns.

9

10

```scala { .api }

11

/**

12

* Boundary control flow system providing structured "break" functionality

13

*/

14

object boundary:

15

/**

16

* Create a boundary with a label, enabling break operations within the block

17

*/

18

def apply[T](body: Label[T] ?=> T): T

19

20

/**

21

* Break from the nearest enclosing boundary with a value

22

*/

23

def break[T](value: T)(using Label[T]): Nothing

24

25

/**

26

* Break from the nearest enclosing boundary without a value (Unit)

27

*/

28

def break()(using Label[Unit]): Nothing

29

30

/**

31

* Label type for boundary operations

32

* Represents a typed break target within a boundary

33

*/

34

sealed abstract class Label[-T]

35

36

/**

37

* Exception type used internally for break operations

38

*/

39

final class Break[T](val value: T) extends Throwable with scala.util.control.ControlThrowable

40

```

41

42

**Usage Examples:**

43

44

```scala

45

import scala.util.boundary

46

import scala.util.boundary.break

47

48

// Basic boundary usage

49

val result = boundary {

50

for i <- 1 to 100 do

51

if i > 50 then break(i)

52

println(i)

53

-1 // Default value if no break

54

}

55

println(result) // 51

56

57

// Boundary with Unit return type

58

boundary {

59

val items = List(1, 2, 3, 4, 5)

60

for item <- items do

61

if item == 3 then break()

62

println(s"Processing $item")

63

}

64

65

// Nested boundaries with different types

66

val nested = boundary[String] {

67

boundary[Int] {

68

if someCondition then break(42)

69

if otherCondition then break("early exit") // Breaks outer boundary

70

100

71

}.toString

72

}

73

74

// Early return from function

75

def findFirst[T](items: List[T])(predicate: T => Boolean): Option[T] =

76

boundary[Option[T]] {

77

for item <- items do

78

if predicate(item) then break(Some(item))

79

None

80

}

81

82

val numbers = List(1, 2, 3, 4, 5)

83

val found = findFirst(numbers)(_ > 3) // Some(4)

84

85

// Complex control flow

86

def processData(data: List[String]): Either[String, List[Int]] =

87

boundary[Either[String, List[Int]]] {

88

val results = data.map { str =>

89

str.toIntOption match

90

case Some(num) => num

91

case None => break(Left(s"Invalid number: $str"))

92

}

93

Right(results)

94

}

95

```

96

97

### Utility Types

98

99

Advanced utility types for type-level programming and implicit resolution.

100

101

```scala { .api }

102

/**

103

* Negation in implicit search - provides evidence that no instance of T exists

104

* Useful for conditional compilation and type-level branching

105

*/

106

final class NotGiven[+T] private():

107

/** Get the singleton NotGiven value */

108

def value: NotGiven[Nothing] = NotGiven.value

109

110

object NotGiven:

111

/** Singleton NotGiven value */

112

val value: NotGiven[Nothing] = new NotGiven[Nothing]

113

114

/** Provide NotGiven[T] if no given T is available */

115

given [T](using NotGiven[T]): NotGiven[T] = value.asInstanceOf[NotGiven[T]]

116

```

117

118

**Usage Examples:**

119

120

```scala

121

// Conditional compilation based on available implicits

122

trait JsonEncoder[T]:

123

def encode(value: T): String

124

125

given JsonEncoder[String] = _.toString

126

given JsonEncoder[Int] = _.toString

127

128

def toJson[T](value: T)(using encoder: JsonEncoder[T]): String =

129

encoder.encode(value)

130

131

def toJsonOrFallback[T](value: T)(using encoder: NotGiven[JsonEncoder[T]]): String =

132

s"No encoder available for ${value.getClass.getSimpleName}"

133

134

// This works - encoder available

135

val jsonString = toJson("hello")

136

137

// This works - no encoder available

138

val fallback = toJsonOrFallback(List(1, 2, 3))

139

```

140

141

### Function Tupling Support

142

143

Utilities for converting between tupled and untupled function forms.

144

145

```scala { .api }

146

/**

147

* Type class for converting between regular functions and tupled functions

148

* Experimental feature for functional programming patterns

149

*/

150

sealed trait TupledFunction[F, G]:

151

/** Convert regular function to tupled form */

152

def tupled(f: F): G

153

/** Convert tupled function to regular form */

154

def untupled(g: G): F

155

156

object TupledFunction:

157

// Instances for different arities

158

given TupledFunction[A => R, Tuple1[A] => R] = ???

159

given TupledFunction[(A, B) => R, ((A, B)) => R] = ???

160

given TupledFunction[(A, B, C) => R, ((A, B, C)) => R] = ???

161

// ... more arities

162

```

163

164

**Usage Examples:**

165

166

```scala

167

// Convert between function forms

168

val add: (Int, Int) => Int = _ + _

169

val tupledAdd: ((Int, Int)) => Int = TupledFunction.tupled(add)

170

val untupledAdd: (Int, Int) => Int = TupledFunction.untupled(tupledAdd)

171

172

// Use with higher-order functions

173

val pairs = List((1, 2), (3, 4), (5, 6))

174

val sums = pairs.map(tupledAdd) // List(3, 7, 11)

175

176

// Functional composition

177

def compose[A, B, C](f: A => B, g: B => C): A => C = a => g(f(a))

178

def composeT[A, B, C](f: ((A, B)) => C): (A => B) => A => C =

179

g => a => f((a, g(a)))

180

```

181

182

### Command Line Parsing

183

184

Utilities for parsing command line arguments and options.

185

186

```scala { .api }

187

/**

188

* Command line parser with support for options, flags, and arguments

189

*/

190

object CommandLineParser:

191

/** Parse command line arguments into structured format */

192

def parse(args: Array[String]): ParseResult

193

194

/** Create parser with specific configuration */

195

def create(config: ParserConfig): CommandLineParser

196

197

/**

198

* Result of command line parsing

199

*/

200

case class ParseResult(

201

options: Map[String, String],

202

flags: Set[String],

203

arguments: List[String],

204

errors: List[String]

205

)

206

207

/**

208

* Configuration for command line parser

209

*/

210

case class ParserConfig(

211

supportedOptions: Set[String],

212

supportedFlags: Set[String],

213

allowUnknown: Boolean = false

214

)

215

```

216

217

**Usage Examples:**

218

219

```scala

220

// Basic parsing

221

val args = Array("--verbose", "--output", "result.txt", "input.txt")

222

val result = CommandLineParser.parse(args)

223

224

println(result.flags) // Set("verbose")

225

println(result.options) // Map("output" -> "result.txt")

226

println(result.arguments) // List("input.txt")

227

228

// Custom parser

229

val config = ParserConfig(

230

supportedOptions = Set("output", "config"),

231

supportedFlags = Set("verbose", "help"),

232

allowUnknown = false

233

)

234

235

val parser = CommandLineParser.create(config)

236

val customResult = parser.parse(args)

237

238

// Pattern matching on results

239

customResult match

240

case ParseResult(opts, flags, args, Nil) if flags.contains("help") =>

241

println("Help requested")

242

case ParseResult(opts, flags, args, Nil) =>

243

println(s"Processing with options: $opts")

244

case ParseResult(_, _, _, errors) =>

245

println(s"Parsing errors: ${errors.mkString(", ")}")

246

```

247

248

### Number Parsing

249

250

Type-safe number parsing from strings with compile-time validation.

251

252

```scala { .api }

253

/**

254

* Type class for parsing numbers from strings

255

* Provides compile-time validation for number formats

256

*/

257

trait FromDigits[T]:

258

/** Parse string to number, may throw exception */

259

def fromDigits(digits: String): T

260

261

object FromDigits:

262

given FromDigits[Int] = _.toInt

263

given FromDigits[Long] = _.toLong

264

given FromDigits[Float] = _.toFloat

265

given FromDigits[Double] = _.toDouble

266

given FromDigits[BigInt] = BigInt(_)

267

given FromDigits[BigDecimal] = BigDecimal(_)

268

269

/**

270

* Extension methods for string to number conversion

271

*/

272

extension (s: String)

273

/** Convert string to number of type T */

274

def parseAs[T](using FromDigits[T]): T = summon[FromDigits[T]].fromDigits(s)

275

/** Safe conversion returning Option */

276

def parseAsOption[T](using FromDigits[T]): Option[T] =

277

try Some(parseAs[T]) catch case _ => None

278

```

279

280

**Usage Examples:**

281

282

```scala

283

// Type-safe number parsing

284

val intValue = "42".parseAs[Int] // 42

285

val longValue = "123456789".parseAs[Long] // 123456789L

286

val doubleValue = "3.14159".parseAs[Double] // 3.14159

287

288

// Safe parsing with Option

289

val validInt = "42".parseAsOption[Int] // Some(42)

290

val invalidInt = "abc".parseAsOption[Int] // None

291

292

// Custom number types

293

case class UserId(value: Int)

294

295

given FromDigits[UserId] = s => UserId(s.toInt)

296

297

val userId = "12345".parseAs[UserId] // UserId(12345)

298

299

// Compile-time validation for literals

300

inline def parseAtCompileTime[T](inline s: String)(using FromDigits[T]): T =

301

inline s match

302

case _ => compiletime.constValue[T] // Simplified - actual implementation more complex

303

```

304

305

### Non-Local Returns

306

307

Support for non-local return patterns with proper resource management.

308

309

```scala { .api }

310

/**

311

* Non-local return support with proper cleanup

312

*/

313

object NonLocalReturns:

314

/** Execute block with non-local return capability */

315

def returning[T](body: ReturnThrowable[T] ?=> T): T

316

317

/** Throw non-local return with value */

318

def throwReturn[T](value: T)(using ReturnThrowable[T]): Nothing

319

320

/**

321

* Capability for non-local returns

322

*/

323

sealed class ReturnThrowable[T] extends Throwable with scala.util.control.ControlThrowable

324

```

325

326

**Usage Examples:**

327

328

```scala

329

import scala.util.control.NonLocalReturns.*

330

331

// Non-local return from nested function

332

def findFirstMatch(data: List[List[String]], target: String): Option[String] =

333

returning {

334

for

335

sublist <- data

336

item <- sublist

337

do

338

if item.contains(target) then

339

throwReturn(Some(item))

340

None

341

}

342

343

// Early exit from complex processing

344

def processComplexData(data: ComplexData): ProcessResult =

345

returning {

346

val stage1 = processStage1(data)

347

if stage1.hasErrors then throwReturn(ProcessResult.failure("Stage 1 failed"))

348

349

val stage2 = processStage2(stage1)

350

if stage2.hasErrors then throwReturn(ProcessResult.failure("Stage 2 failed"))

351

352

val stage3 = processStage3(stage2)

353

ProcessResult.success(stage3)

354

}

355

```

356

357

## Types

358

359

```scala { .api }

360

// Boundary control flow types

361

object boundary:

362

def apply[T](body: Label[T] ?=> T): T

363

def break[T](value: T)(using Label[T]): Nothing

364

def break()(using Label[Unit]): Nothing

365

366

sealed abstract class Label[-T]

367

final class Break[T](val value: T) extends Throwable

368

369

// Utility types

370

final class NotGiven[+T] private():

371

def value: NotGiven[Nothing]

372

373

sealed trait TupledFunction[F, G]:

374

def tupled(f: F): G

375

def untupled(g: G): F

376

377

// Command line parsing types

378

case class ParseResult(

379

options: Map[String, String],

380

flags: Set[String],

381

arguments: List[String],

382

errors: List[String]

383

)

384

385

case class ParserConfig(

386

supportedOptions: Set[String],

387

supportedFlags: Set[String],

388

allowUnknown: Boolean

389

)

390

391

// Number parsing types

392

trait FromDigits[T]:

393

def fromDigits(digits: String): T

394

395

// Non-local returns

396

sealed class ReturnThrowable[T] extends Throwable

397

```