mirror of
https://github.com/ilyakooo0/vty.git
synced 2024-11-29 08:49:40 +03:00
start of vty 4 postmortem
Ignore-this: e2fffce4f0ab1cfcc1db121c8659ecdf darcs-hash:20091007040028-f0a0d-f0edb1508665da5e04ca340a45affd4f75af42bc.gz
This commit is contained in:
parent
cae018f8a9
commit
fe55cd4dd4
@ -0,0 +1,89 @@
|
||||
The first project I focused on when I became fun-employed was improving Vty: A terminal output
|
||||
library for Haskell software.
|
||||
<lj-cut/>
|
||||
Oh I know what you're thinking... Well no, but *I* think it's rediculous to spend time on a
|
||||
*terminal* library. Something like OpenGL or web related, hell anything where any significant activity
|
||||
has happened in the past few years seems more reasonable. Oh well.
|
||||
|
||||
This is a diary of completing vty 4 mostly written after I was done. No really specific technical
|
||||
stuff is contained in this post. I suppose it counts as a sort of postmortem.
|
||||
|
||||
I had taken over as maintainer of vty 3 from Stefan O'Rear. Vty 3 already worked great and I didn't
|
||||
really see me doing much. Still there is always something to improve. In this case vty did not
|
||||
support the various terminals people wanted to use. And characters that occupy multiple output
|
||||
columns were causing corruption.
|
||||
|
||||
Plus, optimization is always fun. So trying my hands at optimizing Haskell code sounded great.
|
||||
Especially when, for the most part, there was an already fast and already working version to compare
|
||||
performance data against: Vty 3.
|
||||
|
||||
I figured low level optimization was what I should start on. Which only makes sense considering I
|
||||
was only interested in optimization fun at the time. ;-) The result of this were much faster than
|
||||
before. However, since I wasn't changing the design in any significant fashion some optimizations
|
||||
could not be implemented. In the end this route was only useful to define reasonable performance
|
||||
goals for a rewritter output layer.
|
||||
|
||||
In addition I was learning Mandarin at the time. I wanted to, of course, create software to help me
|
||||
study. Since I have an infatuation with terminal user interfaces I wanted a terminal library that
|
||||
could handle double-width characters. I couldn't see an effective way to implement this with vty 3's
|
||||
implementation.
|
||||
|
||||
Anybody who has needed to reimplement, or deal with the horrors of a botch reimplementation, knows
|
||||
how dangerous this can be. A botched reimplementation ends up costing more than continueing to
|
||||
maintain the old implementation. A reimplementation is only feasable if the immediate cost of
|
||||
performing the work is offset by the profits the improvements provide.
|
||||
|
||||
A particular source of trouble for vty was the insanity of dealing with terminals or terminal
|
||||
emulators. I'm never going to refer to the physical box of relays from the 70s and 80s that is
|
||||
properly called a terminal again. Terminal emulators are now be refered to as terminals and the
|
||||
others don't exist. So...
|
||||
|
||||
Terminals are software driven character displays and a keyboard. The software controls the diplay by
|
||||
serializing to the STDOUT UTF-8 byte character sequences. Which are then displayed. And control
|
||||
codes which modify the display of the characters. Input from the keyboard and events are read from
|
||||
STDIN.
|
||||
|
||||
Why the fuck something as old as a terminal hasn't been beaten down into a simple, universally
|
||||
supported set of operations by now is a mystery. I don't think curses are terminfo count. I suspect
|
||||
if support for everything that cannot support the required interface is dropped things would only be
|
||||
better. For this reason I only focused on supporting the following terminals: xterm-256-color with
|
||||
UTF-8; Mac OS X Terminal.app; gnome terminal, kde terminal; and rxvt-unicode. Basically: All the
|
||||
terminals I could easily use and behaved close to how I expected.
|
||||
|
||||
While I did not consider supporting the Windows platform I hoped that the abstractions used to
|
||||
handle the various non-Windows terminals would simplify supporting Windows in the future.
|
||||
|
||||
To assure the re-implementation did not introduce regressions I repeatedly:
|
||||
0. Characterized vty 3's implementation. Both in terms of functionality and performance.
|
||||
1. Defined the semantics for the new implementation.
|
||||
2. Verified the new implementation performed as expected: The semantics defined in 1 were
|
||||
implemented correctly; No characteristics of vty 3's implementation that should be maintained
|
||||
are missing; Verified characteristics of vty 3 that caused issues were not maintained.
|
||||
|
||||
Not all the verification steps could be automated. Some I didn't know how to. Others were
|
||||
just verified through informal analysis.
|
||||
|
||||
The verification of some features was done by implementing an interactive test that guided and
|
||||
recorded the results of a manual review. For instance the libraries representation of red and what
|
||||
is actually required to get a terminal to display red. The only reasonable way to verify that final
|
||||
map was for me to sit there and look at the output. Then record whether or not the output was as
|
||||
expected. Since the same tests were going to have to be performed repeatedly and I wanted to record
|
||||
the results of the tests I formalized this process in software: tests/interactive_terminal_test.hs.
|
||||
This program recorded the results of: Describing a test to a user; Performing the test; Requesting
|
||||
from the user if the test passed or failed; Then recording the users response. This paid for itself
|
||||
very quickly. Not only did provide the framework to easily create about 15 individual tests. But
|
||||
the program could also worked as a sort of bug reporting tool for users.
|
||||
|
||||
The verification that could be entirely automated was done either through the type system or
|
||||
<a href="http://en.wikipedia.org/wiki/QuickCheck">QuickCheck 2</a> based verification tests.
|
||||
In short an loose terms: QuickCheck informally verifies equations satisfy user specified predicates
|
||||
for arbitrarially generated input. Not all input is attempted; that'd take too long. However enough
|
||||
is tried to be reasonably sure that an implementation works. The looseness of the verification is
|
||||
made up for the fact that QuickCheck tests are *extremely* easy and quick to implement.
|
||||
|
||||
I used a very simple Makefile to manage the execution of tests. The usage followed:
|
||||
make => built and ran all tests.
|
||||
make TEST => build and run test with name TEST. The output for a test was logged to a "results"
|
||||
directory.
|
||||
Nothing fancy, but enough.
|
||||
|
Loading…
Reference in New Issue
Block a user