I discovered the problem when playing more than 3 moves in the
chessboard app.
But it turns out we've been clobbering each other willy-nilly even in
the chessboard-retro app.
This requires creating a new data structure called buffer, because
strings are too inefficient for appending to, and we need to know how
long they need to be before we clear them.
But I'm not gonna bother to write tests for all the new primitives I
just introduced, because that's not expedient.
One test for mu is how nicely it handles situations like this without
requiring perfect test hygiene. In this case, I can imagine tools that
will extract tests for a particular function out of all known tests.
Especially if it's a pure function that should be easy. Then just show
each test to the programmer and ask him to give it a reasonable name.
This will let me swap in a fake in tests.
Still hacky, though. I'm sure I'm not managing the parameter right in
the chessboard app.
And then there's the question of whether it should also appear as an
output operand.
But it's a start. And using nil to mean 'real' is a reasonable
convention.
If I ever need to handle multiple screens perhaps we'll have to switch
to 1:literal/terminal and 2:literal/terminal, etc. But those are equally
easy to guard on.
Each clause creates its own default-space for local variables.
Now we can justify prepending bodies on every 'function' form.
Later we can optimize away the duplicate default-spaces.
Another cost: we can't mindlessly use 'next-input' anymore. Pity.
Other options considered for 'retro':
'teletype': perhaps most accurate, but arcane
'chat': captures that you have to hit 'enter', but not the rendering
'wrap': captures the auto-wrap when printing text but not that you have
to hit 'enter' when typing
'text': useful as a synonym of 'chat' while conveying more information
in other meanings, but too generic, nobody will get it
Why do the input and output options have to be entangled like this?
The problem is that once main exits it takes two characters at minimum
to truly quit: one to fill the buffer and another to overflow it and
trigger the deadlock detector.
Not the cleanest way to exit in the world either, death by deadlock.
I could swear there was an issue earlier where tagged-values had to
contain pointers for some core function. But I can't find it anymore.
Ok, assume we can store primitives in it and pointers only for
aggregates (and-records and arrays).
Dog slow, though. Drawing the sprite for a single piece takes 12s or
30ms/pixel for 400 pixels. A third of that is the actual racket overhead
of drawing pixel by pixel, which would in itself be too much. We need
bitblts.
(Black queen pixels derived from http://www.wpclipart.com/recreation/games/chess/chess_set_1,
after scaling down to 40x40 and replacing external white pixels with
transparent ones in Gimp.)