or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

abstract-syntax-trees.mdexpressions-reification.mdindex.mdmacro-development.mdmirrors-reflective-operations.mdruntime-reflection.mdsymbol-system.mdtype-system.mdtype-tags-type-information.md

expressions-reification.mddocs/

0

# Expressions and Reification

1

2

Typed AST wrappers and reification system for converting between runtime values and compile-time AST representations. Expressions provide a bridge between runtime computation and compile-time code generation and manipulation.

3

4

## Capabilities

5

6

### Expression Wrapper

7

8

Typed wrapper around AST trees providing type-safe access to code representations.

9

10

```scala { .api }

11

/**

12

* Typed expression wrapper providing access to AST and type information

13

*/

14

trait ExprApi[+T] { this: Expr[T] =>

15

/** Underlying abstract syntax tree */

16

def tree: Tree

17

18

/** Static type as determined at compile time */

19

def staticType: Type

20

21

/** Actual type considering runtime type refinements */

22

def actualType: Type

23

24

/** Splice the expression back into code context */

25

def splice: T

26

27

/** Convert to different universe */

28

def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U#Expr[T]

29

}

30

31

/**

32

* Create expression wrapper from tree

33

*/

34

def Expr[T: WeakTypeTag](tree: Tree): Expr[T]

35

```

36

37

**Basic Expression Usage:**

38

39

```scala

40

import scala.reflect.runtime.universe._

41

42

// Create expressions from values

43

val intExpr = Expr[Int](Literal(Constant(42)))

44

val stringExpr = Expr[String](Literal(Constant("hello")))

45

46

println(s"Int expression tree: ${intExpr.tree}")

47

println(s"Int expression type: ${intExpr.staticType}")

48

println(s"String expression tree: ${stringExpr.tree}")

49

println(s"String expression type: ${stringExpr.staticType}")

50

51

// Access expression properties

52

def analyzeExpression[T](expr: Expr[T]): Unit = {

53

println(s"Tree: ${expr.tree}")

54

println(s"Static type: ${expr.staticType}")

55

println(s"Actual type: ${expr.actualType}")

56

println(s"Tree class: ${expr.tree.getClass.getSimpleName}")

57

println()

58

}

59

60

analyzeExpression(intExpr)

61

analyzeExpression(stringExpr)

62

```

63

64

### Reification

65

66

Converting runtime expressions and values into compile-time AST representations.

67

68

```scala { .api }

69

/**

70

* Reify runtime expressions into AST form

71

*/

72

def reify[T](expr: T): Expr[T]

73

74

/**

75

* Reification with explicit type

76

*/

77

def reifyType[T: TypeTag](expr: T): Expr[T]

78

79

/**

80

* Reify expressions with free variables

81

*/

82

def reifyEnclosingRuntimeClass[T](expr: T): Expr[T]

83

```

84

85

**Reification Examples:**

86

87

```scala

88

import scala.reflect.runtime.universe._

89

90

// Simple value reification

91

val numReified = reify(42)

92

val stringReified = reify("Hello World")

93

val boolReified = reify(true)

94

95

println(s"Number: ${numReified.tree}")

96

println(s"String: ${stringReified.tree}")

97

println(s"Boolean: ${boolReified.tree}")

98

99

// Expression reification

100

val mathReified = reify(2 + 3 * 4)

101

val comparisonReified = reify(10 > 5)

102

103

println(s"Math: ${mathReified.tree}")

104

println(s"Comparison: ${comparisonReified.tree}")

105

106

// Complex expression reification

107

val complexReified = reify {

108

val x = 10

109

val y = 20

110

if (x < y) x + y else x - y

111

}

112

113

println(s"Complex: ${complexReified.tree}")

114

115

// Method call reification

116

def greet(name: String): String = s"Hello $name"

117

val methodCallReified = reify(greet("Alice"))

118

119

println(s"Method call: ${methodCallReified.tree}")

120

```

121

122

### Splicing

123

124

Converting AST representations back into runtime values and expressions.

125

126

```scala { .api }

127

/**

128

* Splice expressions back into code context

129

*/

130

trait Splicing {

131

/** Splice expression into surrounding code */

132

def splice[T](expr: Expr[T]): T

133

134

/** Splice with explicit evaluation context */

135

def eval[T](expr: Expr[T]): T

136

137

/** Splice tree directly */

138

def spliceTree[T](tree: Tree): T

139

}

140

```

141

142

**Splicing Examples:**

143

144

```scala

145

import scala.reflect.runtime.universe._

146

147

// Create expressions

148

val addExpr = reify(5 + 3)

149

val stringExpr = reify("Hello".toUpperCase)

150

151

// Splice back to values (conceptual - actual splicing happens at compile time)

152

// In practice, splicing is primarily used within macro contexts

153

154

println(s"Add expression: ${addExpr.tree}")

155

println(s"String expression: ${stringExpr.tree}")

156

157

// Splicing in macro context example (conceptual)

158

def macroWithSplicing(c: scala.reflect.macros.blackbox.Context)(expr: c.Expr[Int]): c.Expr[String] = {

159

import c.universe._

160

161

// Create new expression using spliced value

162

val newExpr = reify {

163

val value = expr.splice // Splice the expression

164

s"The value is: $value"

165

}

166

167

newExpr

168

}

169

```

170

171

### Expression Transformation

172

173

Transforming expressions while preserving type information.

174

175

```scala { .api }

176

/**

177

* Expression transformation operations

178

*/

179

trait ExpressionTransformation[T] { this: Expr[T] =>

180

/** Transform underlying tree */

181

def transform(transformer: Tree => Tree): Expr[T]

182

183

/** Map over expression value */

184

def map[U: WeakTypeTag](f: T => U): Expr[U]

185

186

/** FlatMap over expression */

187

def flatMap[U: WeakTypeTag](f: T => Expr[U]): Expr[U]

188

189

/** Filter expression */

190

def filter(p: T => Boolean): Expr[Option[T]]

191

192

/** Combine with another expression */

193

def zip[U](other: Expr[U]): Expr[(T, U)]

194

}

195

```

196

197

**Expression Transformation Examples:**

198

199

```scala

200

import scala.reflect.runtime.universe._

201

202

// Create base expressions

203

val numExpr = reify(10)

204

val listExpr = reify(List(1, 2, 3, 4, 5))

205

206

// Transform expressions (conceptual API)

207

def transformExpression[T, U: WeakTypeTag](expr: Expr[T])(f: Tree => Tree): Expr[U] = {

208

val transformedTree = f(expr.tree)

209

Expr[U](transformedTree)

210

}

211

212

// Example transformation: double all numbers

213

val doubledExpr = transformExpression[Int, Int](numExpr) { tree =>

214

Apply(Select(tree, TermName("$times")), List(Literal(Constant(2))))

215

}

216

217

println(s"Original: ${numExpr.tree}")

218

println(s"Doubled: ${doubledExpr.tree}")

219

```

220

221

### Expression Composition

222

223

Composing multiple expressions into larger expressions.

224

225

```scala { .api }

226

/**

227

* Expression composition utilities

228

*/

229

object ExprComposition {

230

/** Combine two expressions with binary operation */

231

def combine[A, B, C: WeakTypeTag](

232

exprA: Expr[A],

233

exprB: Expr[B]

234

)(op: (A, B) => C): Expr[C]

235

236

/** Sequence multiple expressions */

237

def sequence[T: WeakTypeTag](exprs: List[Expr[T]]): Expr[List[T]]

238

239

/** Conditional expression composition */

240

def conditional[T: WeakTypeTag](

241

condition: Expr[Boolean],

242

thenExpr: Expr[T],

243

elseExpr: Expr[T]

244

): Expr[T]

245

246

/** Block expression from statements and result */

247

def block[T: WeakTypeTag](

248

statements: List[Expr[Any]],

249

result: Expr[T]

250

): Expr[T]

251

}

252

```

253

254

**Expression Composition Examples:**

255

256

```scala

257

import scala.reflect.runtime.universe._

258

259

// Create component expressions

260

val aExpr = reify(10)

261

val bExpr = reify(20)

262

val condExpr = reify(true)

263

264

// Combine expressions

265

val addExpr = reify(aExpr.splice + bExpr.splice)

266

val multExpr = reify(aExpr.splice * bExpr.splice)

267

268

println(s"Add: ${addExpr.tree}")

269

println(s"Multiply: ${multExpr.tree}")

270

271

// Conditional expression

272

val conditionalExpr = reify {

273

if (condExpr.splice) aExpr.splice else bExpr.splice

274

}

275

276

println(s"Conditional: ${conditionalExpr.tree}")

277

278

// Block expression

279

val blockExpr = reify {

280

val temp1 = aExpr.splice

281

val temp2 = bExpr.splice

282

temp1 + temp2

283

}

284

285

println(s"Block: ${blockExpr.tree}")

286

```

287

288

### Expression Analysis

289

290

Analyzing expressions for various properties and patterns.

291

292

```scala { .api }

293

/**

294

* Expression analysis utilities

295

*/

296

object ExpressionAnalysis {

297

/** Check if expression is pure (no side effects) */

298

def isPure[T](expr: Expr[T]): Boolean

299

300

/** Extract free variables from expression */

301

def freeVariables[T](expr: Expr[T]): Set[String]

302

303

/** Get expression complexity score */

304

def complexity[T](expr: Expr[T]): Int

305

306

/** Check if expression contains specific patterns */

307

def containsPattern[T](expr: Expr[T], pattern: Tree => Boolean): Boolean

308

309

/** Extract all method calls from expression */

310

def extractMethodCalls[T](expr: Expr[T]): List[(String, List[Tree])]

311

312

/** Get all referenced types */

313

def referencedTypes[T](expr: Expr[T]): Set[Type]

314

}

315

```

316

317

**Expression Analysis Examples:**

318

319

```scala

320

import scala.reflect.runtime.universe._

321

322

def analyzeExpression[T](expr: Expr[T]): Unit = {

323

println(s"=== Analyzing Expression ===")

324

println(s"Tree: ${expr.tree}")

325

println(s"Type: ${expr.staticType}")

326

327

// Manual analysis functions (conceptual implementations)

328

def countNodes(tree: Tree): Int = {

329

1 + tree.children.map(countNodes).sum

330

}

331

332

def findLiterals(tree: Tree): List[Any] = {

333

tree.collect {

334

case Literal(Constant(value)) => value

335

}

336

}

337

338

def findIdentifiers(tree: Tree): List[String] = {

339

tree.collect {

340

case Ident(name) => name.toString

341

}

342

}

343

344

def findMethodCalls(tree: Tree): List[String] = {

345

tree.collect {

346

case Apply(Select(_, name), _) => name.toString

347

case Apply(Ident(name), _) => name.toString

348

}

349

}

350

351

println(s"Node count: ${countNodes(expr.tree)}")

352

println(s"Literals: ${findLiterals(expr.tree)}")

353

println(s"Identifiers: ${findIdentifiers(expr.tree)}")

354

println(s"Method calls: ${findMethodCalls(expr.tree)}")

355

println()

356

}

357

358

// Analyze various expressions

359

analyzeExpression(reify(42))

360

analyzeExpression(reify("hello".toUpperCase))

361

analyzeExpression(reify(List(1, 2, 3).map(_ * 2).sum))

362

analyzeExpression(reify {

363

val x = 10

364

val y = 20

365

if (x < y) x + y else x * y

366

})

367

```

368

369

### Advanced Expression Patterns

370

371

Advanced patterns for working with expressions in complex scenarios.

372

373

```scala { .api }

374

/**

375

* Advanced expression patterns and utilities

376

*/

377

object AdvancedExpressionPatterns {

378

/** Partial evaluation of expressions */

379

def partialEval[T](expr: Expr[T]): Expr[T]

380

381

/** Expression memoization */

382

def memoize[T](expr: Expr[T]): Expr[T]

383

384

/** Expression optimization */

385

def optimize[T](expr: Expr[T]): Expr[T]

386

387

/** Dead code elimination */

388

def eliminateDeadCode[T](expr: Expr[T]): Expr[T]

389

390

/** Constant folding */

391

def foldConstants[T](expr: Expr[T]): Expr[T]

392

393

/** Expression serialization */

394

def serialize[T](expr: Expr[T]): String

395

396

/** Expression deserialization */

397

def deserialize[T: WeakTypeTag](serialized: String): Expr[T]

398

}

399

```

400

401

**Complete Expression and Reification Example:**

402

403

```scala

404

import scala.reflect.runtime.universe._

405

406

// Comprehensive expression manipulation example

407

object ExpressionWorkshop {

408

409

// Create various types of expressions

410

val simpleExpr = reify(42)

411

val stringExpr = reify("Hello World")

412

val mathExpr = reify(2 + 3 * 4)

413

val listExpr = reify(List(1, 2, 3, 4, 5))

414

415

val complexExpr = reify {

416

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

417

val doubled = numbers.map(_ * 2)

418

val filtered = doubled.filter(_ > 5)

419

filtered.sum

420

}

421

422

// Expression introspection

423

def inspectExpression[T](name: String, expr: Expr[T]): Unit = {

424

println(s"=== $name ===")

425

println(s"Tree: ${expr.tree}")

426

println(s"Static type: ${expr.staticType}")

427

println(s"Actual type: ${expr.actualType}")

428

println(s"Tree structure:")

429

printTreeStructure(expr.tree, 0)

430

println()

431

}

432

433

def printTreeStructure(tree: Tree, indent: Int): Unit = {

434

val spaces = " " * indent

435

println(s"$spaces${tree.getClass.getSimpleName}: $tree")

436

tree.children.foreach(printTreeStructure(_, indent + 1))

437

}

438

439

// Pattern matching on expressions

440

def analyzeExpressionPattern[T](expr: Expr[T]): String = {

441

expr.tree match {

442

case Literal(Constant(value)) =>

443

s"Literal value: $value (${value.getClass.getSimpleName})"

444

case Ident(name) =>

445

s"Identifier: $name"

446

case Apply(Select(obj, method), args) =>

447

s"Method call: $obj.$method(${args.mkString(", ")})"

448

case Apply(fun, args) =>

449

s"Function call: $fun(${args.mkString(", ")})"

450

case Block(statements, expr) =>

451

s"Block with ${statements.length} statements, result: $expr"

452

case If(condition, thenp, elsep) =>

453

s"Conditional: if ($condition) $thenp else $elsep"

454

case ValDef(mods, name, tpt, rhs) =>

455

s"Value definition: $name = $rhs"

456

case _ =>

457

s"Other: ${tree.getClass.getSimpleName}"

458

}

459

}

460

461

// Expression transformation

462

def transformExpression[T](expr: Expr[T]): Expr[T] = {

463

val transformer = new Transformer {

464

override def transform(tree: Tree): Tree = tree match {

465

// Double all integer literals

466

case Literal(Constant(n: Int)) =>

467

Literal(Constant(n * 2))

468

// Convert string literals to uppercase

469

case Literal(Constant(s: String)) =>

470

Literal(Constant(s.toUpperCase))

471

case _ =>

472

super.transform(tree)

473

}

474

}

475

476

Expr[T](transformer.transform(expr.tree))

477

}

478

479

// Run analysis

480

def runAnalysis(): Unit = {

481

// Inspect all expressions

482

inspectExpression("Simple", simpleExpr)

483

inspectExpression("String", stringExpr)

484

inspectExpression("Math", mathExpr)

485

inspectExpression("List", listExpr)

486

inspectExpression("Complex", complexExpr)

487

488

// Pattern analysis

489

println("=== Pattern Analysis ===")

490

println(s"Simple: ${analyzeExpressionPattern(simpleExpr)}")

491

println(s"String: ${analyzeExpressionPattern(stringExpr)}")

492

println(s"Math: ${analyzeExpressionPattern(mathExpr)}")

493

println(s"List: ${analyzeExpressionPattern(listExpr)}")

494

println()

495

496

// Transformation

497

println("=== Transformation ===")

498

val transformedSimple = transformExpression(simpleExpr)

499

val transformedString = transformExpression(stringExpr)

500

501

println(s"Original simple: ${simpleExpr.tree}")

502

println(s"Transformed simple: ${transformedSimple.tree}")

503

println(s"Original string: ${stringExpr.tree}")

504

println(s"Transformed string: ${transformedString.tree}")

505

506

// Expression composition

507

println("=== Composition ===")

508

val combinedExpr = reify {

509

val a = simpleExpr.splice

510

val b = transformedSimple.splice

511

a + b

512

}

513

println(s"Combined expression: ${combinedExpr.tree}")

514

}

515

}

516

517

// Run the workshop

518

ExpressionWorkshop.runAnalysis()

519

```