or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

array-operations.mdextension-system.mdfunction-operations.mdindex.mdmap-set-operations.mdobject-operations.md
tile.json

function-operations.mddocs/

0

# Function Operations

1

2

Function-based operations for complex transformations and custom logic. These operations allow you to apply custom functions to transform data based on current values.

3

4

## Capabilities

5

6

### Apply Operation

7

8

Applies a function to the current value and replaces it with the function's return value.

9

10

```typescript { .api }

11

/**

12

* Apply a function to the current value

13

* @param fn - Function that receives the current value and returns new value

14

* @returns Result of applying the function to the current value

15

*/

16

{ $apply: (v: T) => T }

17

```

18

19

**Usage Examples:**

20

21

```typescript

22

import update from "immutability-helper";

23

24

// Transform numeric value

25

const obj = { count: 5 };

26

const doubled = update(obj, { count: { $apply: x => x * 2 } });

27

// Result: { count: 10 }

28

29

// Transform string value

30

const user = { name: 'alice' };

31

const capitalized = update(user, {

32

name: { $apply: name => name.charAt(0).toUpperCase() + name.slice(1) }

33

});

34

// Result: { name: 'Alice' }

35

36

// Transform array

37

const data = { numbers: [1, 2, 3, 4, 5] };

38

const evensOnly = update(data, {

39

numbers: { $apply: arr => arr.filter(n => n % 2 === 0) }

40

});

41

// Result: { numbers: [2, 4] }

42

43

// Complex object transformation

44

const product = {

45

name: 'laptop',

46

price: 999,

47

specs: { ram: '8GB', storage: '256GB' }

48

};

49

const updated = update(product, {

50

specs: {

51

$apply: specs => ({

52

...specs,

53

ram: '16GB',

54

gpu: 'Integrated'

55

})

56

}

57

});

58

// Result: specs now has ram: '16GB' and new gpu property

59

```

60

61

### Shorthand Function Syntax

62

63

Instead of using `{ $apply: function }`, you can pass a function directly as the specification.

64

65

```typescript { .api }

66

/**

67

* Shorthand syntax for applying a function

68

* @param fn - Function that receives the current value and returns new value

69

* @returns Result of applying the function to the current value

70

*/

71

(v: T) => T

72

```

73

74

**Usage Examples:**

75

76

```typescript

77

import update from "immutability-helper";

78

79

// Shorthand syntax (equivalent to $apply)

80

const obj = { value: 10 };

81

82

// These are equivalent:

83

const result1 = update(obj, { value: { $apply: x => x + 5 } });

84

const result2 = update(obj, { value: x => x + 5 });

85

// Both result in: { value: 15 }

86

87

// Multiple shorthand functions

88

const data = { a: 1, b: 2, c: 3 };

89

const transformed = update(data, {

90

a: x => x * 2,

91

b: x => x + 10,

92

c: x => x.toString()

93

});

94

// Result: { a: 2, b: 12, c: '3' }

95

96

// Nested shorthand

97

const nested = {

98

user: { age: 25, scores: [80, 85, 90] },

99

meta: { count: 3 }

100

};

101

const result = update(nested, {

102

user: {

103

age: age => age + 1,

104

scores: scores => [...scores, 95]

105

},

106

meta: {

107

count: count => count + 1

108

}

109

});

110

// Result: user.age = 26, scores has 95 added, meta.count = 4

111

```

112

113

## Advanced Function Operations

114

115

```typescript

116

import update from "immutability-helper";

117

118

// Conditional updates

119

const user = { name: 'Alice', role: 'user', loginCount: 5 };

120

const conditionalUpdate = update(user, {

121

role: currentRole => currentRole === 'user' && user.loginCount > 3 ? 'trusted' : currentRole,

122

loginCount: count => count + 1

123

});

124

125

// Async function handling (Note: $apply itself is synchronous)

126

const processData = (data: string[]) => {

127

return update(data, {

128

$apply: items => items.map(item => item.toUpperCase()).sort()

129

});

130

};

131

132

// Using external context

133

const multiplier = 3;

134

const numbers = { values: [1, 2, 3, 4] };

135

const scaled = update(numbers, {

136

values: { $apply: arr => arr.map(n => n * multiplier) }

137

});

138

139

// Combining with other operations

140

const complex = {

141

items: [{ id: 1, active: false }, { id: 2, active: true }],

142

count: 2

143

};

144

const processed = update(complex, {

145

items: {

146

$apply: items => items.map(item => ({ ...item, active: !item.active }))

147

},

148

count: count => count * 2

149

});

150

```

151

152

## Error Handling

153

154

Function operations validate their inputs:

155

156

- `$apply` requires the spec value to be a function

157

- Functions should return a value (undefined results are allowed but may cause issues)

158

- Functions are called synchronously and should not throw errors

159

160

```typescript

161

// This will throw an error:

162

update({ value: 1 }, { value: { $apply: 'not a function' } });

163

// Error: update(): expected spec of $apply to be a function

164

165

// Functions should handle edge cases:

166

const safeUpdate = update(obj, {

167

value: {

168

$apply: (current) => {

169

if (typeof current !== 'number') return 0;

170

return current * 2;

171

}

172

}

173

});

174

```

175

176

## Performance Notes

177

178

- Functions are called once per update operation

179

- The function receives the current value as its argument

180

- Return values replace the current value entirely

181

- Reference equality is preserved if the function returns the same reference

182

- Functions should be pure (no side effects) for predictable behavior

183

- Avoid expensive computations in frequently called update functions

184

185

## Best Practices

186

187

```typescript

188

// Good: Pure function

189

const increment = (x: number) => x + 1;

190

update(obj, { count: { $apply: increment } });

191

192

// Good: Simple transformation

193

update(user, { name: name => name.trim().toLowerCase() });

194

195

// Avoid: Side effects

196

update(obj, {

197

value: {

198

$apply: x => {

199

console.log(x); // Side effect - avoid this

200

return x * 2;

201

}

202

}

203

});

204

205

// Good: Handle edge cases

206

update(data, {

207

items: {

208

$apply: items => Array.isArray(items) ? items.filter(Boolean) : []

209

}

210

});

211

```