or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-collections.mdindex.mdrecords-and-classes.mdtype-checked-collections.mdutilities.md

core-collections.mddocs/

0

# Core Persistent Collections

1

2

Immutable alternatives to Python's built-in collections that use structural sharing for memory efficiency. All collections provide O(log32 n) performance for most operations and return new instances rather than modifying in-place.

3

4

## Capabilities

5

6

### PMap - Persistent Dictionary

7

8

Immutable mapping similar to Python's dict with efficient updates and lookups. Supports all standard mapping operations plus additional persistent-specific methods.

9

10

```python { .api }

11

def pmap(initial: Union[Mapping[KT, VT], Iterable[Tuple[KT, VT]]] = {}, pre_size: int = 0) -> PMap[KT, VT]:

12

"""

13

Create a persistent map from a mapping or iterable of key-value pairs.

14

15

Parameters:

16

- initial: Initial mapping or iterable of (key, value) pairs

17

- pre_size: Expected size for optimization (optional)

18

19

Returns:

20

PMap instance

21

"""

22

23

def m(**kwargs) -> PMap[str, Any]:

24

"""

25

Create a persistent map from keyword arguments.

26

27

Returns:

28

PMap instance with kwargs as key-value pairs

29

"""

30

31

class PMap:

32

def get(self, key, default=None):

33

"""Get value for key, return default if key not found."""

34

35

def set(self, key, value) -> 'PMap':

36

"""Return new PMap with key set to value."""

37

38

def remove(self, key) -> 'PMap':

39

"""Return new PMap without key. Raises KeyError if key missing."""

40

41

def discard(self, key) -> 'PMap':

42

"""Return new PMap without key. Silent if key missing."""

43

44

def update(self, *mappings) -> 'PMap':

45

"""Return new PMap with items from other mappings."""

46

47

def update_with(self, update_fn, *mappings) -> 'PMap':

48

"""Return new PMap updated with merge function for conflicts."""

49

50

def evolver(self) -> 'PMapEvolver':

51

"""Return mutable-like interface for efficient batch updates."""

52

53

def transform(self, *transformations) -> 'PMap':

54

"""Apply path-based transformations to nested structure."""

55

56

def keys(self) -> 'PSet':

57

"""Return PSet of keys."""

58

59

def values(self) -> 'PMapValues':

60

"""Return view of values."""

61

62

def items(self) -> 'PMapItems':

63

"""Return view of key-value pairs."""

64

65

def copy(self) -> 'PMap':

66

"""Return self (immutable, so copy is identity)."""

67

```

68

69

### PVector - Persistent List

70

71

Immutable sequence similar to Python's list with efficient append, random access, and slicing operations.

72

73

```python { .api }

74

def pvector(iterable: Iterable = ()) -> PVector:

75

"""

76

Create a persistent vector from an iterable.

77

78

Parameters:

79

- iterable: Items to include in vector

80

81

Returns:

82

PVector instance

83

"""

84

85

def v(*elements) -> PVector:

86

"""

87

Create a persistent vector from arguments.

88

89

Returns:

90

PVector containing the arguments as elements

91

"""

92

93

class PVector:

94

def append(self, element) -> 'PVector':

95

"""Return new PVector with element appended."""

96

97

def extend(self, iterable) -> 'PVector':

98

"""Return new PVector with elements from iterable appended."""

99

100

def set(self, index: int, value) -> 'PVector':

101

"""Return new PVector with element at index replaced."""

102

103

def mset(self, *args) -> 'PVector':

104

"""Multi-set: mset(index1, val1, index2, val2, ...)"""

105

106

def delete(self, index: int, stop: int = None) -> 'PVector':

107

"""Return new PVector with elements removed."""

108

109

def remove(self, value) -> 'PVector':

110

"""Return new PVector with first occurrence of value removed."""

111

112

def evolver(self) -> 'PVectorEvolver':

113

"""Return mutable-like interface for efficient batch updates."""

114

115

def transform(self, *transformations) -> 'PVector':

116

"""Apply path-based transformations to nested structure."""

117

118

def tolist(self) -> list:

119

"""Convert to Python list."""

120

121

def index(self, value, start: int = 0, stop: int = None) -> int:

122

"""Return index of first occurrence of value."""

123

124

def count(self, value) -> int:

125

"""Return number of occurrences of value."""

126

```

127

128

### PSet - Persistent Set

129

130

Immutable set with efficient membership testing, set operations, and updates.

131

132

```python { .api }

133

def pset(iterable: Iterable = (), pre_size: int = 8) -> PSet:

134

"""

135

Create a persistent set from an iterable.

136

137

Parameters:

138

- iterable: Items to include in set

139

- pre_size: Expected size for optimization

140

141

Returns:

142

PSet instance

143

"""

144

145

def s(*elements) -> PSet:

146

"""

147

Create a persistent set from arguments.

148

149

Returns:

150

PSet containing the arguments as elements

151

"""

152

153

class PSet:

154

def add(self, element) -> 'PSet':

155

"""Return new PSet with element added."""

156

157

def update(self, iterable) -> 'PSet':

158

"""Return new PSet with elements from iterable added."""

159

160

def remove(self, element) -> 'PSet':

161

"""Return new PSet without element. Raises KeyError if missing."""

162

163

def discard(self, element) -> 'PSet':

164

"""Return new PSet without element. Silent if missing."""

165

166

def evolver(self) -> 'PSetEvolver':

167

"""Return mutable-like interface for efficient batch updates."""

168

169

def union(self, *others) -> 'PSet':

170

"""Return new PSet with elements from all sets."""

171

172

def intersection(self, *others) -> 'PSet':

173

"""Return new PSet with elements common to all sets."""

174

175

def difference(self, *others) -> 'PSet':

176

"""Return new PSet with elements not in other sets."""

177

178

def symmetric_difference(self, other) -> 'PSet':

179

"""Return new PSet with elements in either set but not both."""

180

181

def issubset(self, other) -> bool:

182

"""Test whether every element is in other."""

183

184

def issuperset(self, other) -> bool:

185

"""Test whether every element in other is in this set."""

186

187

def isdisjoint(self, other) -> bool:

188

"""Return True if sets have no elements in common."""

189

190

def copy(self) -> 'PSet':

191

"""Return self (immutable, so copy is identity)."""

192

```

193

194

### PBag - Persistent Multiset

195

196

Immutable multiset (bag) that allows duplicate elements and tracks element counts.

197

198

```python { .api }

199

def pbag(elements: Iterable) -> PBag:

200

"""

201

Create a persistent bag from an iterable.

202

203

Parameters:

204

- elements: Items to include (duplicates allowed)

205

206

Returns:

207

PBag instance

208

"""

209

210

def b(*elements) -> PBag:

211

"""

212

Create a persistent bag from arguments.

213

214

Returns:

215

PBag containing the arguments as elements

216

"""

217

218

class PBag:

219

def add(self, element) -> 'PBag':

220

"""Return new PBag with element added (increments count)."""

221

222

def remove(self, element) -> 'PBag':

223

"""Return new PBag with one occurrence of element removed."""

224

225

def count(self, element) -> int:

226

"""Return number of occurrences of element."""

227

228

def update(self, iterable) -> 'PBag':

229

"""Return new PBag with elements from iterable added."""

230

```

231

232

### PList - Persistent Linked List

233

234

Immutable singly-linked list optimized for prepending operations and functional programming patterns.

235

236

```python { .api }

237

def plist(iterable: Iterable = (), reverse: bool = False) -> PList:

238

"""

239

Create a persistent linked list from an iterable.

240

241

Parameters:

242

- iterable: Items to include

243

- reverse: If True, reverse the order

244

245

Returns:

246

PList instance

247

"""

248

249

def l(*elements) -> PList:

250

"""

251

Create a persistent linked list from arguments.

252

253

Returns:

254

PList containing the arguments as elements

255

"""

256

257

class PList:

258

def cons(self, element) -> 'PList':

259

"""Return new PList with element prepended."""

260

261

def mcons(self, iterable) -> 'PList':

262

"""Return new PList with elements from iterable prepended."""

263

264

@property

265

def first(self):

266

"""First element of the list."""

267

268

@property

269

def rest(self) -> 'PList':

270

"""PList of remaining elements after first."""

271

272

def reverse(self) -> 'PList':

273

"""Return new PList in reverse order."""

274

275

def remove(self, element) -> 'PList':

276

"""Return new PList with first occurrence of element removed."""

277

278

def split(self, index: int) -> tuple:

279

"""Return tuple of (left, right) PLists split at index."""

280

```

281

282

### PDeque - Persistent Double-Ended Queue

283

284

Immutable double-ended queue with efficient operations at both ends and optional maximum length.

285

286

```python { .api }

287

def pdeque(iterable: Iterable = None, maxlen: int = None) -> PDeque:

288

"""

289

Create a persistent deque from an iterable.

290

291

Parameters:

292

- iterable: Items to include

293

- maxlen: Maximum length (None for unlimited)

294

295

Returns:

296

PDeque instance

297

"""

298

299

def dq(*elements) -> PDeque:

300

"""

301

Create a persistent deque from arguments.

302

303

Returns:

304

PDeque containing the arguments as elements

305

"""

306

307

class PDeque:

308

def append(self, element) -> 'PDeque':

309

"""Return new PDeque with element appended to right."""

310

311

def appendleft(self, element) -> 'PDeque':

312

"""Return new PDeque with element prepended to left."""

313

314

def extend(self, iterable) -> 'PDeque':

315

"""Return new PDeque with elements from iterable appended."""

316

317

def extendleft(self, iterable) -> 'PDeque':

318

"""Return new PDeque with elements from iterable prepended."""

319

320

def pop(self, count: int = 1) -> 'PDeque':

321

"""Return new PDeque with count elements removed from right."""

322

323

def popleft(self, count: int = 1) -> 'PDeque':

324

"""Return new PDeque with count elements removed from left."""

325

326

@property

327

def left(self):

328

"""Leftmost element."""

329

330

@property

331

def right(self):

332

"""Rightmost element."""

333

334

@property

335

def maxlen(self) -> int:

336

"""Maximum length (None if unlimited)."""

337

338

def rotate(self, steps: int) -> 'PDeque':

339

"""Return new PDeque rotated by steps."""

340

341

def reverse(self) -> 'PDeque':

342

"""Return new PDeque in reverse order."""

343

344

def remove(self, element) -> 'PDeque':

345

"""Return new PDeque with first occurrence of element removed."""

346

```

347

348

## Factory Function Shortcuts

349

350

Convenient single-character aliases for creating collections:

351

352

```python { .api }

353

def m(**kwargs) -> PMap[str, Any]: ... # pmap from keyword arguments

354

def v(*elements: T) -> PVector[T]: ... # pvector from arguments

355

def s(*elements: T) -> PSet[T]: ... # pset from arguments

356

def b(*elements: T) -> PBag[T]: ... # pbag from arguments

357

def l(*elements: T) -> PList[T]: ... # plist from arguments

358

def dq(*elements: T) -> PDeque[T]: ... # pdeque from arguments

359

```

360

361

## Evolver Interfaces

362

363

All main collections provide `.evolver()` methods returning mutable-like interfaces for efficient batch updates:

364

365

```python { .api }

366

class PMapEvolver:

367

def __setitem__(self, key, value) -> None: ...

368

def __delitem__(self, key) -> None: ...

369

def set(self, key, value) -> 'PMapEvolver': ...

370

def remove(self, key) -> 'PMapEvolver': ...

371

def is_dirty(self) -> bool: ...

372

def persistent(self) -> PMap: ...

373

374

class PVectorEvolver:

375

def __setitem__(self, index: int, value) -> None: ...

376

def __delitem__(self, index: int) -> None: ...

377

def append(self, value) -> 'PVectorEvolver': ...

378

def extend(self, iterable) -> 'PVectorEvolver': ...

379

def set(self, index: int, value) -> 'PVectorEvolver': ...

380

def delete(self, value) -> 'PVectorEvolver': ...

381

def is_dirty(self) -> bool: ...

382

def persistent(self) -> PVector: ...

383

384

class PSetEvolver:

385

def add(self, element) -> 'PSetEvolver': ...

386

def remove(self, element) -> 'PSetEvolver': ...

387

def is_dirty(self) -> bool: ...

388

def persistent(self) -> PSet: ...

389

```

390

391

## Usage Examples

392

393

```python

394

# Efficient batch updates using evolvers

395

pm = pmap({'a': 1, 'b': 2})

396

evolver = pm.evolver()

397

evolver['c'] = 3

398

evolver['d'] = 4

399

del evolver['a']

400

new_pm = evolver.persistent() # Get immutable result

401

402

# Chaining operations

403

pv = pvector([1, 2, 3])

404

result = pv.append(4).extend([5, 6]).set(0, 0) # pvector([0, 2, 3, 4, 5, 6])

405

406

# Set operations

407

ps1 = pset([1, 2, 3])

408

ps2 = pset([3, 4, 5])

409

union = ps1.union(ps2) # pset([1, 2, 3, 4, 5])

410

intersection = ps1 & ps2 # pset([3]) - using operator

411

```