A line fails at the prompt, and you fix it there
A function with a typo in it is applied to a list. It fails on the first item. The prompt keeps the stopped machine as a value, you look inside it, bind the name it could not find, and run it on: the list comes out whole. Nothing is retyped.
You need: the command line host and
one terminal, in the directory it was built in. You have it when a
prompt answers : 23.
1. Tell the prompt to keep a failure
Open a prompt:
./o.se -f o.se.osen/osen.ose
One line, in the machine’s own instruction language, since it speaks to the prompt rather than to a program. From now on a line that fails is held instead of thrown away:
> /!/inner/trap
: []
2. Write the bug
A factor, and a function that multiplies by it, with the factor’s name misspelt in the body:
> /factor : 3
/factor -> /_e
> /scale : ({ (/v, /factr) /o/mul }, ["/v"]) /o/defn
/scale -> /_e
3. Run it
> (((1, 2, 3), /scale) /o/map) /o/println
Caught exception: /factr is not bound. Did you mean /factor?
ose: halted, and held as /m. From here:
(/m, <value>) /o/machine/store/value bind the name it could not find, and go on
(/m, "/name") /o/machine/fix/name read another name instead, not run
(/m, <value>) /o/machine/use/value answer the step that failed with a value, and go on
(/m, <frame>, <value>) /o/machine/return answer an enclosing call; /o/backtrace numbers them
(/m) /o/db look at it: its stack, names and frames
(/m) /o/machine/run run a copy as it stands
The map got one item in, the function read /factr, and nothing binds
it. The prompt stopped the machine at that read and bound it to /m.
The menu is the vocabulary for what follows.
4. Look at it
> (/m) /o/db
prints the machine whole. The parts that matter:
/stack : (
/v : 1,
: "/factr",
/error : [ 65550, "/factr is not bound. Did you mean /factor?" ],
...
),
/env : (
/factor : 3,
/scale : <fn (/v)>,
...
(
/v : 1
),
()
),
/pending : (
...
: "/o/mul"
),
The stack holds the item it was on, the name it was reading and the
error. The environment is every scope the line had open, the function’s
own, with /v at 1, innermost. Pending is what the step had left to do: the
multiply. (/m) /o/backtrace lists the open frames, the print, the map
and the multiply, outermost first.
5. Bind the name, and run it on
Two repairs in one line. /o/machine/bind puts the name in every
environment the machine has, so the two items to come find it;
/o/machine/fix/bind supplies it to the step that already failed. Each
answers a new machine and leaves /m as it was:
> /fixed : ((/m, 3, "/factr") /o/machine/bind, 3) /o/machine/fix/bind
/fixed -> /_e
> (/fixed) /o/machine/run
: [ 3, 6, 9 ]
: <machine 604 bytes>
The list printed, and the machine that printed it came back, finished.
6. A call that refused
A different kind of failure: not a name that is missing but a call that cannot answer. The menu changes with it:
> ((1, 0) /o/div) /o/println
Caught exception: out of range in /o/div
ose: halted, and held as /m. From here:
(/m, (<args>)) /o/machine/retry/with apply the call again, to other arguments
(/m) /o/machine/retry apply it again as it was, after rebinding what it calls
(/m, <value>) /o/machine/use/value answer the step that failed with a value, and go on
...
> (/m, 2) /o/machine/use/value
: 2
: <machine 7272 bytes>
/o/machine/use/value answers the failed step with the value given and
runs on: the print got 2.
What happened
- A failure is kept, not reported. With the trap on, a line that fails stops where it failed and is bound to a name, whole: stack, names, open frames and what was left to do.
- Every repair answers a new machine.
/mis untouched, so a wrong repair costs one more line. - This is what a board does with a loop. The same machine, kept at the fault, is what arrives at the prompt in Fix a loop that failed on a board.
If something goes wrong
| what you see | do |
|---|---|
the error prints and no held as /m line |
the trap line in step 1 was not typed in this prompt |
/m is not bound |
nothing has failed since the trap was set: run step 3 |
| the run in step 5 answers a machine and no list | the line used /o/machine/fix/bind alone; the two items to come read the name again. Type the pair as shown |
/fixed -> /_e and then an error about /factr |
the name in the bind is spelt differently from the one in the function |