@hobin/developer 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +215 -372
- package/REFERENCE_ROUTING.md +243 -0
- package/extensions/developer.ts +533 -18
- package/extensions/machine.ts +45 -0
- package/extensions/references/behavior-preserving-structural-change.md +87 -8
- package/extensions/skills.ts +330 -52
- package/extensions/state.ts +227 -2
- package/package.json +9 -3
- package/skills/abstraction-review/SKILL.md +37 -23
- package/skills/abstraction-review/reference-policy.json +66 -0
- package/skills/abstraction-review/references/field-card.md +113 -168
- package/skills/abstraction-review/references/repair-table.md +66 -80
- package/skills/abstraction-review/references/worked-examples.md +79 -256
- package/skills/model/SKILL.md +31 -13
- package/skills/model/reference-policy.json +96 -0
- package/skills/model/references/contract-and-replacement-models.md +112 -0
- package/skills/model/references/logic-query-semantics.md +89 -0
- package/skills/model/references/planning-models.md +75 -0
- package/skills/model/references/problem-modeling.md +143 -276
- package/skills/model/references/proof-obligations.md +71 -0
- package/skills/model/references/relational-constraint-models.md +110 -0
- package/skills/model/references/solver-result-boundaries.md +83 -0
- package/skills/model/references/temporal-behavior-models.md +106 -0
- package/skills/naming-judgment/SKILL.md +17 -4
- package/skills/naming-judgment/reference-policy.json +29 -0
- package/skills/naming-judgment/references/domain-naming.md +29 -10
- package/skills/schedule/SKILL.md +16 -6
- package/skills/schedule/reference-policy.json +29 -0
- package/skills/schedule/references/structural-change-timing.md +81 -18
- package/skills/signal/SKILL.md +17 -6
- package/skills/signal/reference-policy.json +29 -0
- package/skills/signal/references/structural-movement.md +87 -14
- package/skills/sketch/SKILL.md +38 -42
- package/skills/sketch/reference-policy.json +212 -0
- package/skills/sketch/references/accumulator-invariants.md +125 -0
- package/skills/sketch/references/closure-and-conventional-interfaces.md +87 -0
- package/skills/sketch/references/composition-by-wishes.md +69 -0
- package/skills/sketch/references/data-driven-design.md +99 -22
- package/skills/sketch/references/data-shape-template-catalog.md +58 -19
- package/skills/sketch/references/design-levels-and-boundaries.md +133 -0
- package/skills/sketch/references/earned-abstraction.md +75 -0
- package/skills/sketch/references/generative-recursion.md +122 -0
- package/skills/sketch/references/generic-dispatch-systems.md +75 -0
- package/skills/sketch/references/language-semantics.md +82 -0
- package/skills/sketch/references/meaning-preserving-conversions.md +69 -0
- package/skills/sketch/references/process-shape-and-resources.md +157 -0
- package/skills/sketch/references/representation-barriers.md +73 -0
- package/skills/sketch/references/responsibility-and-collaboration.md +108 -0
- package/skills/sketch/references/runtime-and-compilation.md +84 -0
- package/skills/sketch/references/selection-and-creation.md +76 -0
- package/skills/sketch/references/state-history-and-order.md +126 -0
- package/skills/sketch/references/type-transitions.md +54 -0
- package/skills/sketch/references/variation-roles.md +59 -0
- package/skills/verify/SKILL.md +17 -6
- package/skills/verify/reference-policy.json +30 -0
- package/skills/verify/references/verifier-selection-and-pass-but-wrong.md +152 -192
- package/SOURCES.md +0 -104
- package/skills/abstraction-review/references/recipe-cards.md +0 -322
- package/skills/model/references/worked-models-and-specialized-techniques.md +0 -218
- package/skills/sketch/references/abstraction-barriers-and-closure.md +0 -160
- package/skills/sketch/references/abstraction-composition-and-state.md +0 -184
- package/skills/sketch/references/composition-generative-recursion-and-accumulators.md +0 -196
- package/skills/sketch/references/generic-operations-and-languages.md +0 -134
- package/skills/sketch/references/processes-state-and-time.md +0 -171
- package/skills/sketch/references/responsibility-and-variation.md +0 -245
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# Abstraction, Composition, And State
|
|
2
|
-
|
|
3
|
-
Use this reference when a sketch must choose a level of language, hide a
|
|
4
|
-
representation, compose reusable units, expose the process a procedure creates,
|
|
5
|
-
or place history. The core insight is not “add an abstraction.” It is:
|
|
6
|
-
|
|
7
|
-
> Let each level speak only through the vocabulary immediately below it, so a
|
|
8
|
-
> representation, process, or state choice can change without forcing every
|
|
9
|
-
> caller to change.
|
|
10
|
-
|
|
11
|
-
An abstraction is real only when it hides a consequential choice and leaves a
|
|
12
|
-
smaller, truthful contract.
|
|
13
|
-
|
|
14
|
-
## Complete Example: A Representation Barrier
|
|
15
|
-
|
|
16
|
-
Requirement: calculate and display the duration of a schedule while accepting
|
|
17
|
-
several storage formats.
|
|
18
|
-
|
|
19
|
-
### Wishful use
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
label(schedule) = formatDuration(duration(schedule))
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
The top level speaks about schedules and durations, not tuples, JSON keys, or
|
|
26
|
-
date-library objects.
|
|
27
|
-
|
|
28
|
-
### Public vocabulary and law
|
|
29
|
-
|
|
30
|
-
```text
|
|
31
|
-
makeSchedule(start, end, timezone) -> Schedule
|
|
32
|
-
startOf(schedule) -> Instant
|
|
33
|
-
endOf(schedule) -> Instant
|
|
34
|
-
timezoneOf(schedule) -> Timezone
|
|
35
|
-
|
|
36
|
-
law: endOf(makeSchedule(s, e, z)) == e
|
|
37
|
-
law: startOf(makeSchedule(s, e, z)) == s
|
|
38
|
-
invariant: e is not earlier than s
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
### Two representations
|
|
42
|
-
|
|
43
|
-
```text
|
|
44
|
-
Representation A: { start, end, timezone }
|
|
45
|
-
Representation B: [timezone, epochStart, epochEnd]
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
`duration` is written only with `startOf` and `endOf`. Switching A to B should
|
|
49
|
-
change constructors/selectors and boundary adapters, not `duration` or `label`.
|
|
50
|
-
That replacement test is what makes the barrier concrete. A `Schedule` type
|
|
51
|
-
whose callers still read `.epochEnd` is only a new name for a leaked
|
|
52
|
-
representation.
|
|
53
|
-
|
|
54
|
-
### Where policy lives
|
|
55
|
-
|
|
56
|
-
Validation and normalization belong to the constructor or an explicit external
|
|
57
|
-
adapter. The selectors do not invent fallback timezones. If callers need raw
|
|
58
|
-
source distinctions, the barrier must preserve them or expose a separate source
|
|
59
|
-
view; normalization is a loss of ability as well as a gain in guarantees.
|
|
60
|
-
|
|
61
|
-
## Three-Level Sketch
|
|
62
|
-
|
|
63
|
-
For consequential designs, write the levels explicitly:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
product level:
|
|
67
|
-
label, reschedule, overlaps
|
|
68
|
-
|
|
69
|
-
domain representation level:
|
|
70
|
-
makeSchedule, startOf, endOf, timezoneOf
|
|
71
|
-
|
|
72
|
-
mechanism level:
|
|
73
|
-
JSON fields, database columns, date-library values
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
Check every dependency arrow. Product operations may use the domain vocabulary;
|
|
77
|
-
only the representation owner may use mechanism details. Add another level only
|
|
78
|
-
when it introduces meaningful primitives, combinations, or reusable names.
|
|
79
|
-
|
|
80
|
-
## Select The Specific Reference
|
|
81
|
-
|
|
82
|
-
| Unresolved question | Read | Required output |
|
|
83
|
-
| --- | --- | --- |
|
|
84
|
-
| wished top level, representation barrier, higher-order unit, closure, or conventional interface | [Abstraction Barriers And Closure](abstraction-barriers-and-closure.md) | level map, public operations/laws, hidden representation, replacement and closure checks |
|
|
85
|
-
| process shape, cost, state/history, identity, concurrency, streams, or event order | [Processes, State, And Time](processes-state-and-time.md) | process trace/cost or explicit history owner and ordering law |
|
|
86
|
-
| multiple representations, generic operations, registration, symbolic data, DSL, evaluator, or runtime boundary | [Generic Operations And Languages](generic-operations-and-languages.md) | variant-operation matrix or language vocabulary plus evaluator contract |
|
|
87
|
-
|
|
88
|
-
Read [Responsibility And Variation](responsibility-and-variation.md) instead when
|
|
89
|
-
the main question is who should own knowledge, collaboration, creation, or a
|
|
90
|
-
changing role.
|
|
91
|
-
|
|
92
|
-
## Modules As Models
|
|
93
|
-
|
|
94
|
-
A module is a useful model of an environment, not merely a folder. Fill:
|
|
95
|
-
|
|
96
|
-
```text
|
|
97
|
-
environment: real context and change pressure
|
|
98
|
-
model: represented facets and deliberately ignored facts
|
|
99
|
-
interface: sense exposed to users
|
|
100
|
-
assumptions: environmental facts required for the model to remain useful
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Example:
|
|
104
|
-
|
|
105
|
-
```text
|
|
106
|
-
module: ExchangeRateQuote
|
|
107
|
-
environment: provider responses, currencies, timestamps, outages
|
|
108
|
-
model: base, quote, rate, observedAt
|
|
109
|
-
ignored: provider request IDs and transport headers
|
|
110
|
-
interface: convert(amount), age(now)
|
|
111
|
-
assumptions: rate is positive; observedAt uses a comparable clock
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
If a caller needs provider headers to decide freshness, either freshness is
|
|
115
|
-
owned by the wrong layer or the model omitted a required fact.
|
|
116
|
-
|
|
117
|
-
A coherent **principled component** may share assumptions internally and use
|
|
118
|
-
weak indirection. An **adaptable system** needs stronger interfaces between
|
|
119
|
-
components with different assumptions or replacement pressure. Do not impose
|
|
120
|
-
plugin-style indirection inside every cohesive unit, and do not expose internals
|
|
121
|
-
between independently evolving units.
|
|
122
|
-
|
|
123
|
-
## Pull, Transform, Push
|
|
124
|
-
|
|
125
|
-
Many processes can be sketched as:
|
|
126
|
-
|
|
127
|
-
```text
|
|
128
|
-
pull: acquire and validate external information
|
|
129
|
-
transform: compute a context-light domain result
|
|
130
|
-
push: interpret effects or update the environment
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
Example:
|
|
134
|
-
|
|
135
|
-
```text
|
|
136
|
-
pullOrders() -> Orders
|
|
137
|
-
planNotifications(Orders) -> List<Notification>
|
|
138
|
-
sendNotifications(List<Notification>) -> DeliveryReport
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
This split is useful when failures, retries, and tests differ by phase. Reject it
|
|
142
|
-
when one atomic transaction or shared-state invariant is the actual product
|
|
143
|
-
boundary.
|
|
144
|
-
|
|
145
|
-
## Sketch Output
|
|
146
|
-
|
|
147
|
-
```text
|
|
148
|
-
Top level: product operations written wishfully
|
|
149
|
-
Levels: vocabulary and allowed dependency direction
|
|
150
|
-
Barrier: public operations/laws, hidden choice, invariant owner
|
|
151
|
-
Replacement: alternative implementation that should leave callers unchanged
|
|
152
|
-
Composition: primitives, combinators, closure boundary, finalizers
|
|
153
|
-
Process: generated work, cost, time, failure, and ordering
|
|
154
|
-
Module: environment, model, interface, assumptions
|
|
155
|
-
State: history owner or explicit stream/log
|
|
156
|
-
Checks: leak, replacement, closure, trace, and order evidence
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
## Failure Diagnosis
|
|
160
|
-
|
|
161
|
-
| Symptom | Return to |
|
|
162
|
-
| --- | --- |
|
|
163
|
-
| wished function merely renames a mechanism | product vocabulary and hidden choice |
|
|
164
|
-
| callers assemble or inspect raw representation | barrier operations and leak check |
|
|
165
|
-
| composed result cannot be combined again | closure boundary and finalizer split |
|
|
166
|
-
| short code creates unexplained stack/buffer/order cost | process trace |
|
|
167
|
-
| module boundary follows directories only | environment/model/interface/assumptions |
|
|
168
|
-
| same call changes after prior interactions | history placement |
|
|
169
|
-
| new variant edits every old package | generic operation axes |
|
|
170
|
-
| configuration syntax has no evaluator/error semantics | ordinary data/functions or language contract |
|
|
171
|
-
|
|
172
|
-
## Source Trace
|
|
173
|
-
|
|
174
|
-
- Harold Abelson and Gerald Jay Sussman with Julie Sussman, *Structure and
|
|
175
|
-
Interpretation of Computer Programs*, Second Edition, MIT Press, 1996:
|
|
176
|
-
black-box abstraction, data-abstraction barriers, closure, conventional
|
|
177
|
-
interfaces, procedure/process distinction, generic operations, state,
|
|
178
|
-
streams, and metalinguistic abstraction.
|
|
179
|
-
- Zachary Tellman, *Elements of Clojure*, 2019: modules as models,
|
|
180
|
-
environment/model/interface/assumptions, principled versus adaptable systems,
|
|
181
|
-
units of computation, and process construction.
|
|
182
|
-
- Hillel Wayne, *Logic for Programmers*, version 0.14.0, May 4, 2026:
|
|
183
|
-
ability-guarantee tradeoffs and the separation of mathematical models from
|
|
184
|
-
runtime semantics.
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# Composition, Generative Recursion, And Accumulators
|
|
2
|
-
|
|
3
|
-
Use this reference after the base data recipe when structure alone does not
|
|
4
|
-
finish the design. It distinguishes four moves that are often blurred together:
|
|
5
|
-
designing an auxiliary, abstracting completed designs, generating new
|
|
6
|
-
subproblems, and remembering knowledge that traversal would otherwise lose.
|
|
7
|
-
|
|
8
|
-
## Design By Composition
|
|
9
|
-
|
|
10
|
-
Write a wishful top level before helper bodies:
|
|
11
|
-
|
|
12
|
-
```text
|
|
13
|
-
publishableTasks(tasks):
|
|
14
|
-
return sortByPriority(onlyReady(normalize(tasks)))
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
For each wished operation, run the full small recipe:
|
|
18
|
-
|
|
19
|
-
```text
|
|
20
|
-
purpose: what subproblem it solves
|
|
21
|
-
contract: input and output meanings
|
|
22
|
-
examples: representative success and boundary cases
|
|
23
|
-
template: derived from its data
|
|
24
|
-
reason: why it is a distinct subproblem
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
An auxiliary is earned when it solves a separate domain subproblem, processes a
|
|
28
|
-
referenced data definition, or generalizes a problem that the direct design
|
|
29
|
-
exposes. “The original function is long” is not an independent purpose.
|
|
30
|
-
|
|
31
|
-
## Abstraction From Completed Examples
|
|
32
|
-
|
|
33
|
-
Start with at least two correct concrete designs that share a template.
|
|
34
|
-
|
|
35
|
-
```text
|
|
36
|
-
sum(numbers):
|
|
37
|
-
Empty -> 0
|
|
38
|
-
Node(first, rest) -> first + sum(rest)
|
|
39
|
-
|
|
40
|
-
allReady(tasks):
|
|
41
|
-
Empty -> true
|
|
42
|
-
Node(first, rest) -> first.ready && allReady(rest)
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Align corresponding positions:
|
|
46
|
-
|
|
47
|
-
| Role | `sum` | `allReady` |
|
|
48
|
-
| --- | --- | --- |
|
|
49
|
-
| base | `0` | `true` |
|
|
50
|
-
| item projection | identity | `task.ready` |
|
|
51
|
-
| combine | `+` | `&&` |
|
|
52
|
-
|
|
53
|
-
Only now is a fold-shaped candidate visible:
|
|
54
|
-
|
|
55
|
-
```text
|
|
56
|
-
fold(sequence, base, project, combine)
|
|
57
|
-
```
|
|
58
|
-
|
|
59
|
-
The shared template is evidence, not approval. Check that the roles have stable
|
|
60
|
-
meaning, old functions become simple calls, process/cost does not accidentally
|
|
61
|
-
change, and one realistic new case fits without adding flags. `abstraction-review`
|
|
62
|
-
owns the promotion decision.
|
|
63
|
-
|
|
64
|
-
## Structural Versus Generative Recursion
|
|
65
|
-
|
|
66
|
-
Structural recursion consumes pieces selected directly from the input data
|
|
67
|
-
definition. Generative recursion creates a new problem by domain knowledge.
|
|
68
|
-
|
|
69
|
-
```text
|
|
70
|
-
structural: totalEstimate(rest)
|
|
71
|
-
// rest is a field in Node(Task, Tasks)
|
|
72
|
-
|
|
73
|
-
generative: binarySearch(sorted, lower, midpoint - 1)
|
|
74
|
-
// the next interval is calculated, not selected from a data field
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
Misclassifying the second as structural hides the algorithm idea and its
|
|
78
|
-
termination obligation.
|
|
79
|
-
|
|
80
|
-
## Generative Recursion Recipe
|
|
81
|
-
|
|
82
|
-
Answer four questions before the body:
|
|
83
|
-
|
|
84
|
-
```text
|
|
85
|
-
trivial: which problems have a direct answer?
|
|
86
|
-
generate: how are new subproblems produced?
|
|
87
|
-
solve/combine: how do recursive answers form this answer?
|
|
88
|
-
terminate: why do generated problems approach a trivial case?
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
Worked binary-search sketch:
|
|
92
|
-
|
|
93
|
-
```text
|
|
94
|
-
search(sorted, target, low, high):
|
|
95
|
-
if low > high:
|
|
96
|
-
return NotFound // trivial
|
|
97
|
-
|
|
98
|
-
mid = floor((low + high) / 2) // generation knowledge
|
|
99
|
-
if sorted[mid] == target:
|
|
100
|
-
return Found(mid) // trivial
|
|
101
|
-
if target < sorted[mid]:
|
|
102
|
-
return search(sorted, target, low, mid - 1)
|
|
103
|
-
return search(sorted, target, mid + 1, high)
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
Process examples must show generated intervals:
|
|
107
|
-
|
|
108
|
-
```text
|
|
109
|
-
[0, 6] -> [4, 6] -> [4, 4] -> Found(4)
|
|
110
|
-
[0, 0] -> [1, 0] -> NotFound
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
Termination measure: `high - low + 1` is a natural number for non-trivial
|
|
114
|
-
calls, and each recursive call strictly decreases it. If no decreasing measure
|
|
115
|
-
is known, state the possible non-termination boundary rather than asserting
|
|
116
|
-
that the input “gets smaller.”
|
|
117
|
-
|
|
118
|
-
## Accumulator Recipe
|
|
119
|
-
|
|
120
|
-
Do not begin by adding an extra parameter. First identify the lost knowledge or
|
|
121
|
-
repeated work in a conventional design.
|
|
122
|
-
|
|
123
|
-
Example pressure: repeatedly appending to the end while reversing a sequence
|
|
124
|
-
reprocesses prior results. Introduce `seenReversed` with an invariant:
|
|
125
|
-
|
|
126
|
-
```text
|
|
127
|
-
original == reverse(seenReversed) ++ remaining
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
Trace the relation:
|
|
131
|
-
|
|
132
|
-
```text
|
|
133
|
-
original [a,b,c], remaining [a,b,c], seenReversed []
|
|
134
|
-
original [a,b,c], remaining [b,c], seenReversed [a]
|
|
135
|
-
original [a,b,c], remaining [c], seenReversed [b,a]
|
|
136
|
-
original [a,b,c], remaining [], seenReversed [c,b,a]
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
The invariant determines initialization, update, and result:
|
|
140
|
-
|
|
141
|
-
```text
|
|
142
|
-
reverse(items):
|
|
143
|
-
loop(remaining, seenReversed):
|
|
144
|
-
Empty -> seenReversed
|
|
145
|
-
Node(first, rest) -> loop(rest, prepend(first, seenReversed))
|
|
146
|
-
return loop(items, Empty)
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
Check the invariant at three points:
|
|
150
|
-
|
|
151
|
-
1. initialization relates the original input to the initial accumulator;
|
|
152
|
-
2. one transition preserves the relationship;
|
|
153
|
-
3. the base case plus the invariant implies the promised result.
|
|
154
|
-
|
|
155
|
-
Different invariants create different algorithms. Choose the simplest invariant
|
|
156
|
-
that solves observed pressure; an accumulator with no stated meaning is hidden
|
|
157
|
-
state.
|
|
158
|
-
|
|
159
|
-
## Iterative Refinement
|
|
160
|
-
|
|
161
|
-
When a required case cannot be expressed or a forbidden case remains possible,
|
|
162
|
-
change the data definition and propagate the change through:
|
|
163
|
-
|
|
164
|
-
```text
|
|
165
|
-
data examples
|
|
166
|
-
-> behavior examples
|
|
167
|
-
-> templates
|
|
168
|
-
-> implementations
|
|
169
|
-
-> tests
|
|
170
|
-
-> serialized/public compatibility surfaces
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
A local type edit is incomplete when old persisted forms or callers remain in
|
|
174
|
-
circulation.
|
|
175
|
-
|
|
176
|
-
## Failure Diagnosis
|
|
177
|
-
|
|
178
|
-
| Symptom | Repair |
|
|
179
|
-
| --- | --- |
|
|
180
|
-
| wished helper has no examples or independent purpose | inline it or run its own recipe |
|
|
181
|
-
| abstraction is derived from one function | complete another concrete design first |
|
|
182
|
-
| abstract parameters are implementation fragments | restate stable variation roles |
|
|
183
|
-
| generated recursive call lacks an algorithm idea | return to structural template or state generation rule |
|
|
184
|
-
| termination says only “smaller” | provide a well-founded measure or explicit divergence boundary |
|
|
185
|
-
| accumulator is added for style | show lost knowledge, repeated work, or process pressure |
|
|
186
|
-
| accumulator update is guessed | derive it from the invariant |
|
|
187
|
-
|
|
188
|
-
## Source Trace
|
|
189
|
-
|
|
190
|
-
- [*How to Design Programs*, official living edition](https://htdp.org/2026-5-28/Book/index.html):
|
|
191
|
-
design by composition, abstraction from concrete functions, generative
|
|
192
|
-
recursion and termination, accumulators and invariants, and iterative
|
|
193
|
-
refinement.
|
|
194
|
-
- Harold Abelson and Gerald Jay Sussman with Julie Sussman, *Structure and
|
|
195
|
-
Interpretation of Computer Programs*, Second Edition, MIT Press, 1996:
|
|
196
|
-
wishful procedure decomposition, higher-order abstraction, and process shape.
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
# Generic Operations And Languages
|
|
2
|
-
|
|
3
|
-
Use this reference when several representations must coexist additively, or
|
|
4
|
-
when ordinary data and functions are becoming a small language with its own
|
|
5
|
-
evaluation semantics.
|
|
6
|
-
|
|
7
|
-
## Two Axes Of Generic Operations
|
|
8
|
-
|
|
9
|
-
Write the matrix before choosing classes, visitors, multimethods, or a registry:
|
|
10
|
-
|
|
11
|
-
| Representation | `charge` | `refund` | `describe` |
|
|
12
|
-
| --- | --- | --- | --- |
|
|
13
|
-
| Card | method | method | method |
|
|
14
|
-
| Bank transfer | method | unsupported | method |
|
|
15
|
-
| Store credit | method | method | method |
|
|
16
|
-
|
|
17
|
-
There are two independent pressures:
|
|
18
|
-
|
|
19
|
-
- horizontal: higher-level operations should not know representation fields;
|
|
20
|
-
- vertical: adding a representation should not require editing every old
|
|
21
|
-
representation package.
|
|
22
|
-
|
|
23
|
-
One possible data-directed surface is:
|
|
24
|
-
|
|
25
|
-
```text
|
|
26
|
-
register(kind, operation, method)
|
|
27
|
-
applyGeneric(operation, taggedValue, ...args)
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
Specify duplicate registration, missing method, load order, type transitions,
|
|
31
|
-
and error visibility. Then add a fake representation. Existing callers and old
|
|
32
|
-
representation modules should remain unchanged. If only two stable variants
|
|
33
|
-
exist, a local conditional may be cheaper and clearer.
|
|
34
|
-
|
|
35
|
-
## Coercion And Meaning Preservation
|
|
36
|
-
|
|
37
|
-
For mixed representations, draw paths:
|
|
38
|
-
|
|
39
|
-
```text
|
|
40
|
-
Integer -> Rational -> Decimal
|
|
41
|
-
Money(USD) -X-> Money(EUR) without an exchange-rate context
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
For each edge state preserved meaning and lost ability: precision, identity,
|
|
45
|
-
order, metadata, or capability. Choose direct operation, coercion, canonical
|
|
46
|
-
representation, or explicit rejection. A convenient path that silently loses
|
|
47
|
-
meaning is not genericity.
|
|
48
|
-
|
|
49
|
-
## Symbolic Data Boundary
|
|
50
|
-
|
|
51
|
-
When code inspects formulas, queries, or rules, represent notation as data:
|
|
52
|
-
|
|
53
|
-
```text
|
|
54
|
-
Expr = Number(value) | Variable(name) | Sum(left, right) | Product(left, right)
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Algorithms use predicates/selectors/constructors or pattern matching on this
|
|
58
|
-
semantic definition, not string indexes. Constructors may own simplification:
|
|
59
|
-
|
|
60
|
-
```text
|
|
61
|
-
makeSum(0, x) -> x
|
|
62
|
-
makeSum(x, 0) -> x
|
|
63
|
-
makeSum(x, y) -> Sum(x, y)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
That policy must be explicit because it changes the representation while
|
|
67
|
-
preserving intended expression meaning.
|
|
68
|
-
|
|
69
|
-
## When Data Becomes A Language
|
|
70
|
-
|
|
71
|
-
A rule table, query builder, workflow schema, or configuration is a language
|
|
72
|
-
only when it has:
|
|
73
|
-
|
|
74
|
-
```text
|
|
75
|
-
primitives: smallest valid expressions
|
|
76
|
-
combination: how expressions form larger expressions
|
|
77
|
-
abstraction: how recurring expressions receive reusable names
|
|
78
|
-
validation: well-formed versus invalid programs
|
|
79
|
-
evaluation: what an expression means in an environment
|
|
80
|
-
errors: parse, validation, runtime, and unsupported behavior
|
|
81
|
-
evolution: versioning, migrations, and compatibility
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Worked policy DSL sketch:
|
|
85
|
-
|
|
86
|
-
```text
|
|
87
|
-
Policy = Allow(Role) | HasTag(Tag) | All(List<Policy>) | Any(List<Policy>)
|
|
88
|
-
|
|
89
|
-
evaluate(Allow("admin"), env) = env.user.role == "admin"
|
|
90
|
-
evaluate(All([]), env) = true
|
|
91
|
-
evaluate(All([p, ...rest]), env) = evaluate(p, env) && evaluate(All(rest), env)
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
Define invalid states, such as an unknown role or empty `Any`, rather than
|
|
95
|
-
letting a host-language exception become language semantics.
|
|
96
|
-
|
|
97
|
-
## Evaluator Boundary
|
|
98
|
-
|
|
99
|
-
Keep the evaluator contract distinct from syntax:
|
|
100
|
-
|
|
101
|
-
```text
|
|
102
|
-
evaluate : Program x Environment -> Result | LanguageError
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
State evaluation order, scope, effects, termination limits, and resource
|
|
106
|
-
budgets. A mathematically equivalent rewrite may not preserve host-language
|
|
107
|
-
short-circuiting, effects, or exceptions.
|
|
108
|
-
|
|
109
|
-
Do not build a DSL when ordinary typed data plus functions keep policy more
|
|
110
|
-
visible. The evaluator, migrations, debugging tools, and error messages are
|
|
111
|
-
product code, not free infrastructure.
|
|
112
|
-
|
|
113
|
-
## Artifact
|
|
114
|
-
|
|
115
|
-
```text
|
|
116
|
-
Variant-operation matrix:
|
|
117
|
-
Representation barrier:
|
|
118
|
-
Registration/dispatch and unsupported policy:
|
|
119
|
-
Conversion graph and preserved meaning:
|
|
120
|
-
Language primitives/combinations/abstractions:
|
|
121
|
-
Validation and evaluator contract:
|
|
122
|
-
Errors, effects, versioning, and limits:
|
|
123
|
-
Fake variant or example program check:
|
|
124
|
-
Simpler ordinary-data alternative:
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
## Source Trace
|
|
128
|
-
|
|
129
|
-
- *Structure and Interpretation of Computer Programs*, Second Edition,
|
|
130
|
-
sections 2.4-2.5 and chapters 4-5: multiple representations, generic
|
|
131
|
-
operations, data-directed programming, symbolic data, metalinguistic
|
|
132
|
-
abstraction, evaluators, and explicit machines.
|
|
133
|
-
- Hillel Wayne, *Logic for Programmers*, version 0.14.0, May 4, 2026:
|
|
134
|
-
model/runtime distinctions and ability-guarantee tradeoffs.
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
# Processes, State, And Time
|
|
2
|
-
|
|
3
|
-
Use this reference when returned values alone do not describe correctness. The
|
|
4
|
-
same procedure text can generate recursive, iterative, tree-shaped, delayed, or
|
|
5
|
-
stateful processes with different time, space, order, and failure behavior.
|
|
6
|
-
|
|
7
|
-
## Procedure Versus Process
|
|
8
|
-
|
|
9
|
-
Trace a representative execution:
|
|
10
|
-
|
|
11
|
-
```text
|
|
12
|
-
procedure: retry(operation, 3)
|
|
13
|
-
process:
|
|
14
|
-
attempt 1 -> retryable failure -> wait 100 ms
|
|
15
|
-
attempt 2 -> retryable failure -> wait 200 ms
|
|
16
|
-
attempt 3 -> success
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
Record:
|
|
20
|
-
|
|
21
|
-
```text
|
|
22
|
-
result
|
|
23
|
-
work generated at each step
|
|
24
|
-
deferred work or stack growth
|
|
25
|
-
state retained or duplicated
|
|
26
|
-
time/space scale
|
|
27
|
-
ordering and failure surface
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
A recursive tree walk and an iterative queue walk may return the same nodes but
|
|
31
|
-
have different stack, ordering, and memory contracts. A fluent one-line pipeline
|
|
32
|
-
may materialize three full collections. Short procedure text is not evidence of
|
|
33
|
-
a cheap or simple process.
|
|
34
|
-
|
|
35
|
-
## State Means History Matters
|
|
36
|
-
|
|
37
|
-
Compare two calls with identical explicit input:
|
|
38
|
-
|
|
39
|
-
```text
|
|
40
|
-
account.withdraw(40) -> Accepted
|
|
41
|
-
account.withdraw(40) -> Rejected
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
If prior interactions explain the difference, state is part of the contract.
|
|
45
|
-
Fill:
|
|
46
|
-
|
|
47
|
-
```text
|
|
48
|
-
required history: accepted deposits and withdrawals
|
|
49
|
-
sufficient summary: current balance
|
|
50
|
-
owner: account instance
|
|
51
|
-
writers: deposit and withdraw
|
|
52
|
-
identity: two equal balances may be different accounts
|
|
53
|
-
aliases: references that observe the same mutation
|
|
54
|
-
order law: sufficient-funds check and balance update are one transition
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Local state is modular when it hides a coherent history behind a small
|
|
58
|
-
interface. It is hazardous when aliases, retries, concurrency, or persistence
|
|
59
|
-
make the history owner unclear.
|
|
60
|
-
|
|
61
|
-
## Explicit State Machine Alternative
|
|
62
|
-
|
|
63
|
-
Represent time as data when transitions need review, replay, or distribution:
|
|
64
|
-
|
|
65
|
-
```text
|
|
66
|
-
Payment = Created | Authorizing(attempt) | Authorized(id) | Failed(reason)
|
|
67
|
-
|
|
68
|
-
transition(Created, Authorize) -> Authorizing(1)
|
|
69
|
-
transition(Authorizing(n), Retryable) -> Authorizing(n + 1)
|
|
70
|
-
transition(Authorizing(_), Approved(id)) -> Authorized(id)
|
|
71
|
-
transition(Authorized(_), Approved(_)) -> invalid or idempotent policy
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
State the unchanged part of each transition and cover stale, duplicate,
|
|
75
|
-
reordered, retried, and concurrent events. A correct enum is not a correct
|
|
76
|
-
history model.
|
|
77
|
-
|
|
78
|
-
## Event Order And Atomicity
|
|
79
|
-
|
|
80
|
-
For concurrent withdrawal, the forbidden interleaving is:
|
|
81
|
-
|
|
82
|
-
```text
|
|
83
|
-
A reads 100
|
|
84
|
-
B reads 100
|
|
85
|
-
A writes 20 after withdrawing 80
|
|
86
|
-
B writes 20 after withdrawing 80
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
Both calls appear accepted although 160 was withdrawn. The order law is not
|
|
90
|
-
“serialize everything”; it is:
|
|
91
|
-
|
|
92
|
-
```text
|
|
93
|
-
read balance -> check funds -> write next balance
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
must behave as one protected transition for a given account. Choose a lock,
|
|
97
|
-
transaction, queue, compare-and-swap loop, or merge policy only after stating
|
|
98
|
-
that law and its waiting/fairness cost.
|
|
99
|
-
|
|
100
|
-
## Streams And Logs
|
|
101
|
-
|
|
102
|
-
An explicit stream/log represents successive states or events:
|
|
103
|
-
|
|
104
|
-
```text
|
|
105
|
-
events -> fold(transition, initialState) -> currentState
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
It improves replay, audit, time travel, merge reasoning, and functional
|
|
109
|
-
composition. It also creates retention, ordering, identity, versioning, and
|
|
110
|
-
reconstruction-cost obligations. Choose it when history is product evidence,
|
|
111
|
-
not merely because mutation is unfashionable.
|
|
112
|
-
|
|
113
|
-
For delayed streams also record demand:
|
|
114
|
-
|
|
115
|
-
```text
|
|
116
|
-
producer pace
|
|
117
|
-
consumer pace
|
|
118
|
-
buffer/backpressure
|
|
119
|
-
single-use versus replayable
|
|
120
|
-
failure and cancellation
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
## Pull, Transform, Push Process Check
|
|
124
|
-
|
|
125
|
-
```text
|
|
126
|
-
pull: where external time and failure enter
|
|
127
|
-
transform: domain computation and its data contract
|
|
128
|
-
push: effect interpretation, idempotency, and partial failure
|
|
129
|
-
apex: coordinator that owns the whole process outcome
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
The separation is false when pull retries silently alter transform semantics or
|
|
133
|
-
push performs an unreported partial success. Conversely, splitting one atomic
|
|
134
|
-
transaction into these phases may violate the actual invariant.
|
|
135
|
-
|
|
136
|
-
## Process/State Artifact
|
|
137
|
-
|
|
138
|
-
```text
|
|
139
|
-
Procedure promise:
|
|
140
|
-
Representative process trace:
|
|
141
|
-
Shape and time/space cost:
|
|
142
|
-
Required history and sufficient summary:
|
|
143
|
-
State or log owner and writers:
|
|
144
|
-
Identity and alias behavior:
|
|
145
|
-
Order/atomicity law:
|
|
146
|
-
Retry, stale, duplicate, and concurrency policy:
|
|
147
|
-
Alternative representation considered:
|
|
148
|
-
Evidence and residual risk:
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Failure Diagnosis
|
|
152
|
-
|
|
153
|
-
- Result tests pass but stack, buffering, or order matters: add a process-shaped
|
|
154
|
-
verifier.
|
|
155
|
-
- Same call changes but no history is named: revise the state contract.
|
|
156
|
-
- A state machine lists states but not events and next states: derive the
|
|
157
|
-
transition relation.
|
|
158
|
-
- All work is serialized: narrow the protected order law.
|
|
159
|
-
- A log is proposed without replay/audit/merge pressure: local state may be the
|
|
160
|
-
smaller honest model.
|
|
161
|
-
- A pipeline stage hides effects: expose the phase or rename the process
|
|
162
|
-
honestly.
|
|
163
|
-
|
|
164
|
-
## Source Trace
|
|
165
|
-
|
|
166
|
-
- *Structure and Interpretation of Computer Programs*, Second Edition,
|
|
167
|
-
chapters 1 and 3: procedure/process distinction, state and assignment,
|
|
168
|
-
identity and sharing, concurrency, constraints, delayed evaluation, and
|
|
169
|
-
streams.
|
|
170
|
-
- Zachary Tellman, *Elements of Clojure*, 2019: units of computation and the
|
|
171
|
-
construction of pull-transform-push processes.
|