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

metaprogramming.mddocs/

0

# Metaprogramming

1

2

Compile-time operations, quoted expressions, and macro support for powerful metaprogramming with type-safe code generation and compile-time computation.

3

4

## Capabilities

5

6

### Compile-Time Operations

7

8

Core compile-time functions for constant folding, implicit summoning, and compile-time errors.

9

10

```scala { .api }

11

/**

12

* Get a value of singleton type T at compile time

13

* T must be a constant type like 42 or "hello"

14

*/

15

inline def constValue[T]: T

16

17

/**

18

* Safely get a constant value, returns None if not a constant type

19

*/

20

inline def constValueOpt[T]: Option[T]

21

22

/**

23

* Extract all constant values from a tuple type

24

*/

25

inline def constValueTuple[T <: Tuple]: T

26

27

/**

28

* Pattern match on types without values (erased matching)

29

*/

30

inline def erasedValue[T]: T

31

32

/**

33

* Marker for uninitialized fields (use with caution)

34

*/

35

def uninitialized: Nothing

36

37

/**

38

* Marker for deferred given instances

39

*/

40

def deferred: Nothing

41

42

/**

43

* Emit compile-time error with custom message

44

*/

45

inline def error(msg: String): Nothing

46

47

/**

48

* Get string representation of code expression

49

*/

50

inline def codeOf(arg: Any): String

51

52

/**

53

* Require that expression is a compile-time constant

54

*/

55

inline def requireConst(x: Boolean | Byte | Short | Int | Long | Float | Double | Char | String): Unit

56

57

/**

58

* Delayed implicit summoning - resolved at inline expansion

59

*/

60

inline def summonInline[T]: T

61

62

/**

63

* Conditional implicit summoning with fallback handling

64

*/

65

inline def summonFrom[T](f: Nothing => T): T

66

67

/**

68

* Summon all implicit instances for tuple of types

69

*/

70

inline def summonAll[T <: Tuple]: T

71

72

/**

73

* Force by-name parameter evaluation (compile-time assertion)

74

*/

75

inline def byName[T](x: => T): T

76

```

77

78

**Usage Examples:**

79

80

```scala

81

import scala.compiletime.*

82

83

// Constant value extraction

84

type Three = 3

85

val three: 3 = constValue[Three] // 3

86

87

type Message = "Hello, World!"

88

val msg: String = constValue[Message] // "Hello, World!"

89

90

// Safe constant extraction

91

val maybeConst = constValueOpt[Int] // None (Int is not a singleton type)

92

val definiteConst = constValueOpt[42] // Some(42)

93

94

// Tuple constant extraction

95

type Point = (1, 2, 3)

96

val coords = constValueTuple[Point] // (1, 2, 3)

97

98

// Type-based pattern matching

99

inline def sizeOf[T]: Int = inline erasedValue[T] match

100

case _: Byte => 1

101

case _: Short => 2

102

case _: Int => 4

103

case _: Long => 8

104

case _: Float => 4

105

case _: Double => 8

106

107

// Compile-time errors

108

inline def assertPositive(x: Int): Int =

109

inline if x <= 0 then error("Value must be positive")

110

else x

111

112

// Code introspection

113

val code = codeOf(1 + 2 * 3) // "1.+(2.*(3))"

114

115

// Conditional summoning

116

inline def optionalSummoning[T]: Option[T] = summonFrom {

117

case given T => Some(summon[T])

118

case _ => None

119

}

120

121

// By-name forcing

122

inline def debugTime[T](name: String)(expr: => T): T =

123

println(s"Evaluating $name")

124

byName(expr)

125

```

126

127

### Type-Level Operations

128

129

Compile-time operations on types for type-level programming.

130

131

#### Any Type Operations

132

133

```scala { .api }

134

/**

135

* Convert any type to its string representation

136

*/

137

type ToString[X] <: String

138

139

/**

140

* Type equality test

141

*/

142

type =:=[X, Y] <: Boolean

143

```

144

145

#### Boolean Operations

146

147

```scala { .api }

148

/**

149

* Boolean negation at type level

150

*/

151

type ![X <: Boolean] <: Boolean

152

153

/**

154

* Boolean AND at type level

155

*/

156

type &&[X <: Boolean, Y <: Boolean] <: Boolean

157

158

/**

159

* Boolean OR at type level

160

*/

161

type ||[X <: Boolean, Y <: Boolean] <: Boolean

162

```

163

164

#### Integer Operations

165

166

```scala { .api }

167

/**

168

* Successor (add 1) at type level

169

*/

170

type S[X <: Int] <: Int

171

172

/**

173

* Addition at type level

174

*/

175

type +[X <: Int, Y <: Int] <: Int

176

177

/**

178

* Subtraction at type level

179

*/

180

type -[X <: Int, Y <: Int] <: Int

181

182

/**

183

* Multiplication at type level

184

*/

185

type *[X <: Int, Y <: Int] <: Int

186

187

/**

188

* Division at type level

189

*/

190

type /[X <: Int, Y <: Int] <: Int

191

192

/**

193

* Modulo at type level

194

*/

195

type %[X <: Int, Y <: Int] <: Int

196

197

/**

198

* Less than comparison at type level

199

*/

200

type <[X <: Int, Y <: Int] <: Boolean

201

202

/**

203

* Less than or equal at type level

204

*/

205

type <=[X <: Int, Y <: Int] <: Boolean

206

207

/**

208

* Greater than at type level

209

*/

210

type >[X <: Int, Y <: Int] <: Boolean

211

212

/**

213

* Greater than or equal at type level

214

*/

215

type >=[X <: Int, Y <: Int] <: Boolean

216

217

/**

218

* Absolute value at type level

219

*/

220

type Abs[X <: Int] <: Int

221

222

/**

223

* Maximum of two integers at type level

224

*/

225

type Max[X <: Int, Y <: Int] <: Int

226

227

/**

228

* Minimum of two integers at type level

229

*/

230

type Min[X <: Int, Y <: Int] <: Int

231

```

232

233

#### String Operations

234

235

```scala { .api }

236

/**

237

* String concatenation at type level

238

*/

239

type +[X <: String, Y <: String] <: String

240

241

/**

242

* String length at type level

243

*/

244

type Length[X <: String] <: Int

245

246

/**

247

* Substring extraction at type level

248

*/

249

type Substring[S <: String, IBeg <: Int, IEnd <: Int] <: String

250

251

/**

252

* Regular expression matching at type level

253

*/

254

type Matches[S <: String, Regex <: String] <: Boolean

255

```

256

257

**Usage Examples:**

258

259

```scala

260

import scala.compiletime.ops.*

261

262

// Type-level arithmetic

263

type Five = int.+[2, 3] // 5

264

type Seven = int.*[Five, 1] // 7

265

type Two = int.-[Five, 3] // 2

266

267

// Type-level boolean logic

268

type True = boolean.![false] // true

269

type False = boolean.&&[true, false] // false

270

271

// Type-level string operations

272

type Greeting = string.+["Hello", " World"] // "Hello World"

273

type Len = string.Length[Greeting] // 11

274

type Sub = string.Substring[Greeting, 0, 5] // "Hello"

275

276

// Using in function signatures

277

def vectorOfSize[N <: Int](size: N): IArray[Int] =

278

IArray.fill(constValue[N])(0)

279

280

val vec5 = vectorOfSize[5] // IArray of size 5

281

```

282

283

### Quoted Expressions

284

285

Quotation system for representing and manipulating Scala expressions at compile time.

286

287

```scala { .api }

288

/**

289

* Quoted expression representing Scala code of type T

290

*/

291

abstract class Expr[+T]:

292

/** Show the expression as a string */

293

def show(using Quotes): String

294

/** Get the value if expression is a constant */

295

def value(using Quotes): Option[T]

296

/** Get the value, throwing if not constant */

297

def valueOrAbort(using Quotes)(msg: String): T

298

/** Apply beta reduction to inline definitions */

299

def betaReduce(using Quotes): Expr[T]

300

301

object Expr:

302

/** Lift a value to an expression */

303

def apply[T](value: T)(using ToExpr[T], Quotes): Expr[T]

304

/** Create block expression */

305

def block[T](statements: List[Expr[Any]], expr: Expr[T])(using Quotes): Expr[T]

306

/** Unapply to extract value from constant expression */

307

def unapply[T](expr: Expr[T])(using Quotes): Option[T]

308

/** Create expression from sequence */

309

def ofSeq[T](elems: Seq[Expr[T]])(using Type[T], Quotes): Expr[Seq[T]]

310

/** Create expression from list */

311

def ofList[T](elems: List[Expr[T]])(using Type[T], Quotes): Expr[List[T]]

312

/** Create tuple expression from sequence */

313

def ofTupleFromSeq(elems: Seq[Expr[Any]])(using Quotes): Expr[Tuple]

314

/** Summon implicit and create expression */

315

def summon[T](using Type[T], Quotes): Expr[T]

316

317

/**

318

* Type representation in quoted context

319

*/

320

trait Type[T]:

321

/** Show the type as a string */

322

def show(using Quotes): String

323

324

/**

325

* Quotes context providing access to compiler information

326

*/

327

trait Quotes:

328

/** Reflect API for advanced operations */

329

val reflect: Reflect

330

331

/**

332

* Convert values to expressions

333

*/

334

trait ToExpr[T]:

335

def apply(x: T)(using Quotes): Expr[T]

336

337

/**

338

* Extract values from expressions

339

*/

340

trait FromExpr[T]:

341

def apply(x: Expr[T])(using Quotes): Option[T]

342

343

/**

344

* Variable argument expressions

345

*/

346

object Varargs:

347

def apply[T](elems: Expr[T]*)(using Type[T], Quotes): Expr[Seq[T]]

348

def unapply[T](expr: Expr[Seq[T]])(using Quotes): Option[Seq[Expr[T]]]

349

```

350

351

**Usage Examples:**

352

353

```scala

354

import scala.quoted.*

355

356

// Basic quotation (inside macro)

357

def exampleMacro(using Quotes): Expr[Int] =

358

val two = Expr(2)

359

val three = Expr(3)

360

'{ $two + $three } // Creates expression: 2 + 3

361

362

// Pattern matching on expressions

363

def analyzeExpr(expr: Expr[Int])(using Quotes): String = expr match

364

case Expr(n) => s"Constant: $n"

365

case '{ $x + $y } => s"Addition of ${x.show} and ${y.show}"

366

case _ => "Complex expression"

367

368

// Creating block expressions

369

def blockMacro(using Quotes): Expr[String] =

370

val printExpr = '{ println("Computing...") }

371

val resultExpr = '{ "Hello, World!" }

372

Expr.block(List(printExpr), resultExpr)

373

374

// Working with sequences

375

def listMacro(elems: Expr[Seq[Int]])(using Quotes): Expr[List[Int]] = elems match

376

case Varargs(exprs) =>

377

val listExprs = exprs.map(e => '{ $e }).toList

378

Expr.ofList(listExprs)

379

case _ =>

380

'{ $elems.toList }

381

```

382

383

### Compile-Time Testing

384

385

Utilities for testing compile-time behavior and error handling.

386

387

```scala { .api }

388

/**

389

* Representation of a compile-time error

390

*/

391

case class Error(

392

message: String,

393

line: Int,

394

column: Int,

395

kind: ErrorKind

396

)

397

398

/**

399

* Classification of compile errors

400

*/

401

enum ErrorKind:

402

case Parser, Typer, Other

403

404

/**

405

* Test if code compiles without errors

406

*/

407

def typeChecks(code: String): Boolean

408

409

/**

410

* Get all compile errors for given code

411

*/

412

def typeCheckErrors(code: String): List[Error]

413

```

414

415

**Usage Examples:**

416

417

```scala

418

import scala.compiletime.testing.*

419

420

// Test compilation

421

val goodCode = "val x: Int = 42"

422

val badCode = "val x: String = 42"

423

424

assert(typeChecks(goodCode)) // true

425

assert(!typeChecks(badCode)) // false

426

427

// Analyze errors

428

val errors = typeCheckErrors("val x: String = 42")

429

errors.foreach { error =>

430

println(s"Error at line ${error.line}: ${error.message}")

431

}

432

433

// Use in inline tests

434

inline def testInline(): Unit =

435

inline if !typeChecks("val x: Int = \"hello\"") then

436

println("Type error detected as expected")

437

```

438

439

### Extension Methods for Metaprogramming

440

441

```scala { .api }

442

extension (inline x: Any)

443

/** Cast value to Matchable for pattern matching */

444

inline def asMatchable: Matchable

445

```

446

447

**Usage Examples:**

448

449

```scala

450

def processAny(x: Any): String =

451

x.asMatchable match

452

case s: String => s"String: $s"

453

case i: Int => s"Int: $i"

454

case _ => "Other"

455

```

456

457

## Types

458

459

```scala { .api }

460

// Core metaprogramming types

461

abstract class Expr[+T]

462

trait Type[T]

463

trait Quotes

464

trait ToExpr[T]

465

trait FromExpr[T]

466

467

// Type-level operation types

468

object ops:

469

object any:

470

type ToString[X] <: String

471

type =:=[X, Y] <: Boolean

472

473

object boolean:

474

type ![X <: Boolean] <: Boolean

475

type &&[X <: Boolean, Y <: Boolean] <: Boolean

476

type ||[X <: Boolean, Y <: Boolean] <: Boolean

477

478

object int:

479

type S[X <: Int] <: Int

480

type +[X <: Int, Y <: Int] <: Int

481

type -[X <: Int, Y <: Int] <: Int

482

type *[X <: Int, Y <: Int] <: Int

483

type /[X <: Int, Y <: Int] <: Int

484

type %[X <: Int, Y <: Int] <: Int

485

type <[X <: Int, Y <: Int] <: Boolean

486

type <=[X <: Int, Y <: Int] <: Boolean

487

type >[X <: Int, Y <: Int] <: Boolean

488

type >=[X <: Int, Y <: Int] <: Boolean

489

type Abs[X <: Int] <: Int

490

type Max[X <: Int, Y <: Int] <: Int

491

type Min[X <: Int, Y <: Int] <: Int

492

493

object long:

494

// Similar operations for Long types

495

496

object double:

497

// Similar operations for Double types

498

499

object float:

500

// Similar operations for Float types

501

502

object string:

503

type +[X <: String, Y <: String] <: String

504

type Length[X <: String] <: Int

505

type Substring[S <: String, IBeg <: Int, IEnd <: Int] <: String

506

type Matches[S <: String, Regex <: String] <: Boolean

507

508

// Testing types

509

case class Error(message: String, line: Int, column: Int, kind: ErrorKind)

510

enum ErrorKind

511

```