docs/unix-phil
view unix-phil.ms @ 61:733f4fb03071
a huge bunch of improvements of my wordings by Andrew Antle
author | meillo@marmaro.de |
---|---|
date | Sun, 18 Apr 2010 20:44:15 +0200 |
parents | 840cbc667009 |
children |
line source
1 .so style
3 .TL
4 .ps +4
5 Why the Unix Philosophy still matters
6 .AU
7 markus schnalke <meillo@marmaro.de>
8 .AB
9 .ti \n(.iu
10 This paper explains the importance of the Unix Philosophy for software design.
11 Today, few software designers are aware of these concepts,
12 and thus a lot of modern software is more limited than necessary
13 and makes less use of software leverage than possible.
14 Knowing and following the guidelines of the Unix Philosophy makes software more valuable.
15 .AE
17 .FS
18 .ps -1
19 This paper was prepared for the ``Software Analysis'' seminar at University Ulm.
20 Mentor was professor Franz Schweiggert.
21 Handed in on 2010-04-16.
22 You may retrieve this document from
23 .CW \s-1http://marmaro.de/docs \ .
24 .FE
26 .H 1 Introduction
27 .LP
28 The Unix Philosophy is the essence of how the Unix operating system,
29 especially its toolchest, was designed.
30 It is not a limited set of fixed rules,
31 but a loose set of guidelines which tell how to write software that
32 suites Unix well.
33 Actually, the Unix Philosophy describes what is common in typical Unix software.
34 The Wikipedia has an accurate definition:
35 .[
36 wikipedia
37 unix philosophy
38 .]
39 .QP
40 The \fIUnix philosophy\fP is a set of cultural norms and philosophical
41 approaches to developing software based on the experience of leading
42 developers of the Unix operating system.
43 .PP
44 As there is no single definition of the Unix Philosophy,
45 several people have stated their view on what it comprises.
46 Best known are:
47 .IP \(bu
48 Doug McIlroy's summary: ``Write programs that do one thing and do it well.''
49 .[
50 mahoney
51 oral history
52 .]
53 .IP \(bu
54 Mike Gancarz' book ``The UNIX Philosophy''.
55 .[
56 gancarz
57 unix philosophy
58 .]
59 .IP \(bu
60 Eric S. Raymond's book ``The Art of UNIX Programming''.
61 .[
62 raymond
63 art of unix programming
64 .]
65 .LP
66 These different views on the Unix Philosophy have much in common.
67 Especially, the main concepts are similar in all of them.
68 McIlroy's definition can surely be called the core of the Unix Philosophy,
69 but the fundamental idea behind it all is ``small is beautiful''.
71 .PP
72 The Unix Philosophy explains how to design good software for Unix.
73 Many concepts described here are based on Unix facilities.
74 Other operating systems may not offer such facilities,
75 hence it may not be possible to design software for such systems
76 according to the Unix Philosophy.
77 .PP
78 The Unix Philosophy has an idea of what the process of software development
79 should look like, but large parts of the philosophy are quite independent
80 from a concrete development process.
81 However, one will soon recognize that some development processes work well
82 with the ideas of the Unix Philosophy and support them, while others are
83 at cross-purposes.
84 Kent Beck's books about Extreme Programming are valuable supplemental
85 resources on this topic.
86 .PP
87 The question of how to actually write code and how the code should look
88 in detail, are beyond the scope of this paper.
89 Kernighan and Pike's book ``The Practice of Programming''
90 .[
91 kernighan pike
92 practice of programming
93 .]
94 covers this topic.
95 Its point of view corresponds to the one espoused in this paper.
97 .H 1 "Importance of software design in general
98 .LP
99 Software design consists of planning how the internal structure
100 and external interfaces of software should look.
101 It has nothing to do with visual appearance.
102 If we were to compare a program to a car, then its color would not matter.
103 Its design would be the car's size, its shape, the locations of doors,
104 the passenger/space ratio, the available controls and instruments,
105 and so forth.
106 .PP
107 Why should software be designed at all?
108 It is accepted as general knowledge,
109 that even a bad plan is better than no plan.
110 Not designing software means programming without a plan.
111 This will surely lead to horrible results,
112 being horrible to use and horrible to maintain.
113 These two aspects are the visible ones.
114 Often invisible though, are the wasted possible gains.
115 Good software design can make these gains available.
116 .PP
117 A software's design deals with qualitative properties.
118 Good design leads to good quality, and quality is important.
119 Any car may be able to drive from point A to point B,
120 but it depends on the qualitative decisions made in the design of the vehicle,
121 whether it is a good choice for passenger transport or not,
122 whether it is a good choice for a rough mountain area,
123 and whether the ride will be fun.
125 .PP
126 Requirements for a piece of software are twofold:
127 functional and non-functional.
128 .IP \(bu
129 Functional requirements directly define the software's functions.
130 They are the reason why software gets written.
131 Someone has a problem and needs a tool to solve it.
132 Being able to solve the problem is the main functional goal.
133 This is the driving force behind all programming effort.
134 Functional requirements are easier to define and to verify.
135 .IP \(bu
136 Non-functional requirements are called \fIquality\fP requirements, too.
137 The quality of software shows through the properties that are not directly
138 related to the software's basic functions.
139 Tools of bad quality often do solve the problems they were written for,
140 but introduce problems and difficulties for usage and development later on.
141 Qualitative aspects are often overlooked at first sight,
142 and are often difficult to define clearly and to verify.
143 .PP
144 Quality is hardly interesting when software gets built initially,
145 but it has a high impact on usability and maintenance of the software later.
146 A short-sighted person might see the process of developing software as
147 one mainly concerned with building something up.
148 But, experience shows that building software the first time is
149 only a small portion of the overall work involved.
150 Bug fixing, extending, rebuilding of parts \(en maintenance work \(en
151 soon take a large part of the time spent on a software project.
152 And of course, the time spent actually using the software.
153 These processes are highly influenced by the software's quality.
154 Thus, quality must not be neglected.
155 However, the problem with quality is that you hardly ``stumble over''
156 bad quality during the first build,
157 although this is the time when you should care about good quality most.
158 .PP
159 Software design has little to do with the basic function of software \(en
160 this requirement will get satisfied anyway.
161 Software design is more about quality aspects.
162 Good design leads to good quality, bad design to bad quality.
163 The primary functions of software will be affected modestly by bad quality,
164 but good quality can provide a lot of additional benefits,
165 even at places one never expected it.
166 .PP
167 The ISO/IEC\|9126-1 standard, part\|1,
168 .[
169 iso product quality
170 .]
171 defines the quality model as consisting of:
172 .IP \(bu
173 .I Functionality
174 (suitability, accuracy, inter\%operability, security)
175 .IP \(bu
176 .I Reliability
177 (maturity, fault tolerance, recoverability)
178 .IP \(bu
179 .I Usability
180 (understandability, learnability, operability, attractiveness)
181 .IP \(bu
182 .I Efficiency
183 (time behavior, resource utilization)
184 .IP \(bu
185 .I Maintainability
186 (analyzability, changeability, stability, testability)
187 .IP \(bu
188 .I Portability
189 (adaptability, installability, co-existence, replaceability)
190 .LP
191 Good design can improve these properties in software;
192 poorly designed software likely suffers in these areas.
193 .PP
194 One further goal of software design is consistency.
195 Consistency eases understanding, using, and working on things.
196 Consistent internal structure and consistent external interfaces
197 can be provided by good design.
198 .PP
199 Software should be well designed because good design avoids many
200 problems during its lifetime.
201 Also, because good design can offer much additional gain.
202 Indeed, much effort should be spent on good design to make software more valuable.
203 The Unix Philosophy provides a way to design software well.
204 It offers guidelines to achieve good quality and high gain for the effort spent.
207 .H 1 "The Unix Philosophy
208 .LP
209 The origins of the Unix Philosophy have already been introduced.
210 This chapter explains the philosophy, oriented on Gancarz,
211 .[
212 gancarz
213 unix philosophy
214 .]
215 and shows concrete examples of its application.
217 .H 2 Pipes
218 .LP
219 The following examples demonstrate how the Unix Philosophy is applied.
220 Knowledge of using the Unix shell is assumed.
221 .PP
222 Counting the number of files in the current directory:
223 .DS
224 ls | wc -l
225 .DE
226 The
227 .CW ls
228 command lists all files in the current directory, one per line,
229 and
230 .CW "wc -l
231 counts the number of lines.
232 .PP
233 Counting the number of files that do not contain ``foo'' in their name:
234 .DS
235 ls | grep -v foo | wc -l
236 .DE
237 Here, the list of files is filtered by
238 .CW grep
239 to remove all lines that contain ``foo''.
240 The rest equals the previous example.
241 .PP
242 Finding the five largest entries in the current directory:
243 .DS
244 du -s * | sort -nr | sed 5q
245 .DE
246 .CW "du -s *
247 returns the recursively summed sizes of all files in the current directory
248 \(en no matter if they are regular files or directories.
249 .CW "sort -nr
250 sorts the list numerically in reverse order (descending).
251 Finally,
252 .CW "sed 5q
253 quits after it has printed the fifth line.
254 .PP
255 The presented command lines are examples of what Unix people would use
256 to get the desired output.
257 There are other ways to get the same output;
258 it is the user's decision which way to go.
259 .PP
260 The examples show that many tasks on a Unix system
261 are accomplished by combining several small programs.
262 The connection between the programs is denoted by the pipe operator `|'.
263 .PP
264 Pipes, and their extensive and easy use, are one of the great
265 achievements of the Unix system.
266 Pipes were possible in earlier operating systems,
267 but never before have they been such a central part of the concept.
268 In the early seventies when Doug McIlroy introduced pipes into the
269 Unix system,
270 ``it was this concept and notation for linking several programs together
271 that transformed Unix from a basic file-sharing system to an entirely new way of computing.''
272 .[
273 aughenbaugh
274 unix oral history
275 .]
276 .PP
277 Being able to specify pipelines in an easy way is,
278 however, not enough by itself;
279 it is only one half.
280 The other is the design of the programs that are used in the pipeline.
281 They need interfaces that allow them to be used in this way.
283 .H 2 "Interface design
284 .LP
285 Unix is, first of all, simple \(en everything is a file.
286 Files are sequences of bytes, without any special structure.
287 Programs should be filters, which read a stream of bytes from standard input (stdin)
288 and write a stream of bytes to standard output (stdout).
289 If the files \fIare\fP sequences of bytes,
290 and the programs \fIare\fP filters on byte streams,
291 then there is exactly one data interface.
292 Hence it is possible to combine programs in any desired way.
293 .PP
294 Even a handful of small programs yields a large set of combinations,
295 and thus a large set of different functions.
296 This is leverage!
297 If the programs are orthogonal to each other \(en the best case \(en
298 then the set of different functions is greatest.
299 .PP
300 Programs can also have a separate control interface
301 in addition to their data interface.
302 The control interface is often called the ``user interface'',
303 because it is usually designed to be used by humans.
304 The Unix Philosophy discourages the assumption that the user will be human.
305 Interactive use of software is slow use of software,
306 because the program waits for user input most of the time.
307 Interactive software also requires the user to be in front of the computer,
308 occupying his attention during usage.
309 .PP
310 Now, back to the idea of combining several small programs
311 to perform a more specific function:
312 If these single tools were all interactive,
313 how would the user control them?
314 It is not only a problem to control several programs at once
315 if they run at the same time;
316 it is also very inefficient to have to control each program
317 when they are intended to act in concert.
318 Hence, the Unix Philosophy discourages designing programs which demand
319 interactive use.
320 The behavior of programs should be defined at invocation.
321 This is done by specifying arguments to the program call
322 (command line switches).
323 Gancarz discusses this topic as ``avoid[ing] captive user interfaces''.
324 .[ [
325 gancarz unix philosophy
326 .], page 88 ff.]
327 .PP
328 Non-interactive use is also an advantage for testing during development.
329 Testing interactive programs is much more complicated
330 than testing non-interactive counterparts.
332 .H 2 "The toolchest approach
333 .LP
334 A toolchest is a set of tools.
335 Instead of one big tool for all tasks, there are many small tools,
336 each for one task.
337 Difficult tasks are solved by combining several small, simple tools.
338 .PP
339 The Unix toolchest \fIis\fP a set of small, (mostly) non-interactive programs
340 that are filters on byte streams.
341 They are, to a large extent, unrelated in their function.
342 Hence, the Unix toolchest provides a large set of functions
343 that can be accessed by combining the programs in the desired way.
344 .PP
345 The act of software development benefits from small toolchest programs, too.
346 Writing small programs is generally easier and less error-prone
347 than writing large programs.
348 Hence, writing a large set of small programs is still easier and
349 less error-prone than writing one large program with all the
350 functionality included.
351 If the small programs are combinable, then they offer even an even larger set
352 of functions than the single monolithic program.
353 Hence, one gets two advantages out of writing small, combinable programs:
354 They are easier to write and they offer a greater set of functions through
355 combination.
356 .PP
357 There are also two main drawbacks of the toolchest approach.
358 First, one simple, standardized interface has to be sufficient.
359 If one feels the need for more ``logic'' than a stream of bytes,
360 then a different approach might be required.
361 Also, a design where a stream of bytes is sufficient,
362 might not be conceivable.
363 By becoming more familiar with the ``Unix style of thinking'',
364 developers will more often and easier find simple designs where
365 a stream of bytes is a sufficient interface.
366 .PP
367 The second drawback of the toolchest approach concerns the users.
368 A toolchest is often more difficult to use because
369 it is necessary to become familiar with each tool and
370 be able to choose and use the right one in any given situation.
371 Additionally, one needs to know how to combine the tools in a sensible way.
372 The issue is similar to having a sharp knife \(en
373 it is a powerful tool in the hand of a master,
374 but of no value in the hand of an unskilled person.
375 However, learning single, small tools of a toolchest is often easier than
376 learning a complex tool.
377 The user will already have a basic understanding of an as yet unknown tool
378 if the tools of a toolchest have a common, consistent style.
379 He will be able to transfer knowledge of one tool to another.
380 .PP
381 This second drawback can be removed to a large extent
382 by adding wrappers around the basic tools.
383 Novice users do not need to learn several tools if a professional wraps
384 complete command lines into a higher-level script.
385 Note that the wrapper script still calls the small tools;
386 it is just like a skin around them.
387 No complexity is added this way,
388 but new programs can be created out of existing one with very little effort.
389 .PP
390 A wrapper script for finding the five largest entries in the current directory
391 might look like this:
392 .DS
393 #!/bin/sh
394 du -s * | sort -nr | sed 5q
395 .DE
396 The script itself is just a text file that calls the commands
397 that a professional user would type in directly.
398 It is probably beneficial to make the program flexible in regard to
399 the number of entries it prints:
400 .DS
401 #!/bin/sh
402 num=5
403 [ $# -eq 1 ] && num="$1"
404 du -sh * | sort -nr | sed "${num}q"
405 .DE
406 This script acts like the one before when called without an argument,
407 but the user can also specify a numerical argument to define the number
408 of lines to print.
409 One can surely imagine even more flexible versions;
410 however, they will still rely on the external programs
411 which actually do the work.
413 .H 2 "A powerful shell
414 .LP
415 The Unix shell provides the ability to combine small programs into large ones.
416 But a powerful shell is a great feature in other ways, too;
417 for instance, by being scriptable.
418 Control statements are built into the shell
419 and the functions are the normal programs of the system.
420 As the programs are already known,
421 learning to program in the shell becomes easy.
422 Using normal programs as functions in the shell programming language
423 is only possible because they are small and combinable tools in a toolchest style.
424 .PP
425 The Unix shell encourages writing small scripts,
426 by combining existing programs because it is so easy to do.
427 This is a great step towards automation.
428 It is wonderful if the effort to automate a task equals the effort
429 to do the task a second time by hand.
430 If this holds,
431 then the user will be happy to automate everything he does more than once.
432 .PP
433 Small programs that do one job well, standardized interfaces between them,
434 a mechanism to combine parts to larger parts, and an easy way to automate tasks
435 will inevitably produce software leverage,
436 achieving multiple times the benefit of the initial investment.
437 .PP
438 The shell also encourages rapid prototyping.
439 Many well known programs started as quickly hacked shell scripts,
440 and turned into ``real'' programs later written in C.
441 Building a prototype first is a way to avoid the biggest problems
442 in application development.
443 Fred Brooks explains in ``No Silver Bullet'':
444 .[
445 brooks
446 no silver bullet
447 .]
448 .QP
449 The hardest single part of building a software system is deciding precisely what to build.
450 No other part of the conceptual work is so difficult as establishing the detailed
451 technical requirements, [...].
452 No other part of the work so cripples the resulting system if done wrong.
453 No other part is more difficult to rectify later.
454 .PP
455 Writing a prototype is a great method for becoming familiar with the requirements
456 and to run into real problems early.
457 .[ [
458 gancarz
459 unix philosophy
460 .], page 28 f.]
461 .PP
462 Prototyping is often seen as a first step in building software.
463 This is, of course, good.
464 However, the Unix Philosophy has an \fIadditional\fP perspective on prototyping:
465 After having built the prototype, one might notice that the prototype is already
466 \fIgood enough\fP.
467 Hence, no reimplementation in a more sophisticated programming language
468 might be of need, at least for the moment.
469 Maybe later, it might be necessary to rewrite the software, but not now.
470 By delaying further work, one keeps the flexibility to react on
471 changing requirements.
472 Software parts that are not written will not miss the requirements.
473 Well known is Gordon Bell's classic saying:
474 ``The cheapest, fastest, and most reliable components are those
475 that aren't there.''
476 .\" FIXME: ref?
478 .H 2 "Worse is better
479 .LP
480 The Unix Philosophy aims for the 90% solution;
481 others call it the ``Worse is better'' approach.
482 Experience from real life projects shows:
483 .PP
484 (1) It is almost impossible to define the
485 requirements completely and correctly the first time.
486 Hence one should not try to; one will fail anyway.
487 .PP
488 (2) Requirements change during time.
489 Hence it is best to delay requirement-based design decisions as long as possible.
490 Software should be small and flexible as long as possible in order
491 to react to changing requirements.
492 Shell scripts, for example, are more easily adjusted than C programs.
493 .PP
494 (3) Maintenance work is hard work.
495 Hence, one should keep the amount of code as small as possible;
496 it should only fulfill the \fIcurrent\fP requirements.
497 Software parts that will be written in the future
498 do not need maintenance until that time.
499 .PP
500 See Brooks' ``The Mythical Man-Month'' for reference.
501 .[ [
502 brooks
503 mythical man-month
504 .], page 115 ff.]
505 .PP
506 Starting with a prototype in a scripting language has several advantages:
507 .IP \(bu
508 As the initial effort is low, one will likely start right away.
509 .IP \(bu
510 Real requirements can be identified quickly since working parts are
511 available sooner.
512 .IP \(bu
513 When software is usable and valuable, it gets used, and thus tested.
514 This ensures that problems will be found in the early stages of development.
515 .IP \(bu
516 The prototype might be enough for the moment;
517 thus, further work can be delayed until a time
518 when one knows about the requirements and problems more thoroughly.
519 .IP \(bu
520 Implementing only the parts that are actually needed at the moment
521 introduces less programming and maintenance work.
522 .IP \(bu
523 If the situation changes such that the software is not needed anymore,
524 then less effort was spent on the project than it would have been
525 if a different approach had been taken.
527 .H 2 "Upgrowth and survival of software
528 .LP
529 So far, \fIwriting\fP or \fIbuilding\fP software has been discussed.
530 Although ``writing'' and ``building'' are just verbs,
531 they do imply a specific view on the work process they describe.
532 A better verb would be to \fI``grow''\fP.
533 Creating software in the sense of the Unix Philosophy is an incremental process.
534 It starts with an initial prototype, which evolves as requirements change.
535 A quickly hacked shell script might become a large, sophisticated,
536 compiled program this way.
537 Its lifetime begins with the initial prototype and ends when the software is not used anymore.
538 While alive, it will be extended, rearranged, rebuilt.
539 Growing software matches the view that ``software is never finished. It is only released.''
540 .[ [
541 gancarz
542 unix philosophy
543 .], page 26]
544 .PP
545 Software can be seen as being controlled by evolutionary processes.
546 Successful software is software that is used by many for a long time.
547 This implies that the software is necessary, useful, and better than the alternatives.
548 Darwin describes ``the survival of the fittest.''
549 .[
550 darwin
551 origin of species
552 .]
553 In relation to software, the most successful software is the fittest;
554 the one that survives.
555 (This may be at the level of one creature, or at the level of one species.)
556 The fitness of software is affected mainly by four properties:
557 portability of code, portability of data, range of usability, and reusability of parts.
558 .PP
559 (1)
560 .I "``Portability of code''
561 means using high-level programming languages,
562 sticking to the standard,
563 .[ [
564 kernighan pike
565 practice of programming
566 .], chapter\|8]
567 and avoiding optimizations that introduce dependencies on specific hardware.
568 Hardware has a much shorter lifespan than software.
569 By chaining software to specific hardware,
570 its lifetime is limited to that of this hardware.
571 In contrast, software should be easy to port \(en
572 adaptation is the key to success.
573 .PP
574 (2)
575 .I "``Portability of data''
576 is best achieved by avoiding binary representations
577 to store data, since binary representations differ from machine to machine.
578 Textual representation is favored.
579 Historically, \s-1ASCII\s0 was the character set of choice;
580 for the future, \s-1UTF\s0-8 might be the better way forward.
581 Important is that it is a plain text representation in a
582 very common character set encoding.
583 Apart from being able to transfer data between machines,
584 readable data has the great advantage that humans are able to directly
585 read and edit it with text editors and other tools from the Unix toolchest.
586 .[ [
587 gancarz
588 unix philosophy
589 .], page 56 ff.]
590 .PP
591 (3)
592 A large
593 .I "``range of usability''
594 ensures good adaptation, and thus good survival.
595 It is a special distinction when software becomes used in fields of endeavor,
596 the original authors never imagined.
597 Software that solves problems in a general way will likely be used
598 for many kinds of similar problems.
599 Being too specific limits the range of usability.
600 Requirements change through time, thus use cases change or even vanish.
601 As a good example of this point,
602 Allman identifies flexibility to be one major reason for sendmail's success:
603 .[
604 allman
605 sendmail
606 .]
607 .QP
608 Second, I limited myself to the routing function [...].
609 This was a departure from the dominant thought of the time, [...].
610 .QP
611 Third, the sendmail configuration file was flexible enough to adapt
612 to a rapidly changing world [...].
613 .LP
614 Successful software adapts itself to the changing world.
615 .PP
616 (4)
617 .I "``Reusability of parts''
618 goes one step further.
619 Software may become obsolete and completely lose its field of action,
620 but the constituent parts of the software may be general and independent enough
621 to survive this death.
622 If software is built by combining small independent programs,
623 then these parts are readily available for reuse.
624 Who cares that the large program is a failure,
625 if parts of it become successful instead?
627 .H 2 "Summary
628 .LP
629 This chapter explained ideas central to the Unix Philosophy.
630 For each of the ideas, the advantages they introduce were explained.
631 The Unix Philosophy is a set of guidelines that help in the design of
632 more valuable software.
633 From the viewpoint of a software developer or software designer,
634 the Unix Philosophy provides answers to many software design problems.
635 .PP
636 The various ideas comprising the Unix Philosophy are very interweaved
637 and can hardly be applied independently.
638 The most important messages are:
639 .I "``Keep it simple!''" ,
640 .I "``Do one thing well!''" ,
641 and
642 .I "``Use software leverage!''
646 .H 1 "Case study: \s-1MH\s0
647 .LP
648 The previous chapter introduced and explained the Unix Philosophy
649 from a general point of view.
650 The driving force was that of the guidelines;
651 references to existing software were given only sparsely.
652 In this and the next chapter, concrete software will be
653 the driving force in the discussion.
654 .PP
655 This first case study is about the mail user agents (\s-1MUA\s0)
656 \s-1MH\s0 (``mail handler'') and its descendant \fInmh\fP
657 (``new mail handler'').
658 .[
659 nmh website
660 .]
661 \s-1MUA\s0s provide functions to read, compose, and organize mail,
662 but (ideally) not to transfer it.
663 In this document, the name \s-1MH\s0 will be used to include nmh.
664 A distinction will only be made if differences between
665 \s-1MH\s0 and nmh are described.
668 .H 2 "Historical background
669 .LP
670 Electronic mail was available in Unix from a very early stage.
671 The first \s-1MUA\s0 on Unix was \f(CWmail\fP,
672 which was already present in the First Edition.
673 .[ [
674 salus
675 quarter century of unix
676 .], page 41 f.]
677 It was a small program that either printed the user's mailbox file
678 or appended text to someone else's mailbox file,
679 depending on the command line arguments.
680 .[
681 manual mail(1)
682 .]
683 It was a program that did one job well.
684 This job was emailing, which was very simple then.
685 .PP
686 Later, emailing became more powerful, and thus more complex.
687 The simple \f(CWmail\fP, which knew nothing of subjects,
688 independent handling of single messages,
689 and long-term email storage, was not powerful enough anymore.
690 In 1978 at Berkeley, Kurt Shoens wrote \fIMail\fP (with a capital `M')
691 to provide additional functions for emailing.
692 Mail was still one program, but was large and did several jobs.
693 Its user interface was modeled after \fIed\fP.
694 Ed is designed for humans, but is still scriptable.
695 \fImailx\fP is the adaptation of Berkeley Mail for System V.
696 .[
697 ritter
698 mailx history
699 .]
700 Elm, pine, mutt, and a slew of graphical \s-1MUA\s0s
701 followed Mail's direction:
702 large, monolithic programs which included all emailing functions.
703 .PP
704 A different way was taken by the people of \s-1RAND\s0 Corporation.
705 Initially, they also had used a monolithic mail system
706 called \s-1MS\s0 (for ``mail system'').
707 But in 1977, Stockton Gaines and Norman Shapiro
708 came up with a proposal for a new email system concept \(en
709 one that honored the Unix Philosophy.
710 The concept was implemented by Bruce Borden in 1978 and 1979.
711 This was the birth of \s-1MH\s0 \(en the ``mail handler''.
712 .PP
713 Since then, \s-1RAND\s0, the University of California at Irvine and
714 at Berkeley, and several others have contributed to the software.
715 However, it's core concepts remained the same.
716 In the late 90s, when development of \s-1MH\s0 slowed down,
717 Richard Coleman started with \fInmh\fP, the new mail handler.
718 His goal was to improve \s-1MH\s0 especially in regard to
719 the requirements of modern emailing.
720 Today, nmh is developed by various people on the Internet.
721 .[
722 ware
723 rand history
724 .]
725 .[
726 peek
727 mh
728 .]
730 .H 2 "Contrasts to monolithic mail systems
731 .LP
732 All \s-1MUA\s0s are monolithic, except \s-1MH\s0.
733 Although some very little known toolchest \s-1MUA\s0s might also exist,
734 this statement reflects the situation pretty well.
735 .PP
736 Monolithic \s-1MUA\s0s gather all their functions in one program.
737 In contrast, \s-1MH\s0 is a toolchest of many small tools \(en one for each job.
738 Following is a list of important programs of \s-1MH\s0's toolchest
739 and their function.
740 It gives an indication of what the toolchest looks like.
741 .IP \(bu
742 .CW inc :
743 incorporate new mail (this is how mail enters the system)
744 .IP \(bu
745 .CW scan :
746 list messages in folder
747 .IP \(bu
748 .CW show :
749 show message
750 .IP \(bu
751 .CW next\fR/\fPprev :
752 show next/previous message
753 .IP \(bu
754 .CW folder :
755 change current folder
756 .IP \(bu
757 .CW refile :
758 refile message into different folder
759 .IP \(bu
760 .CW rmm :
761 remove message
762 .IP \(bu
763 .CW comp :
764 compose new message
765 .IP \(bu
766 .CW repl :
767 reply to message
768 .IP \(bu
769 .CW forw :
770 forward message
771 .IP \(bu
772 .CW send :
773 send prepared message (this is how mail leaves the system)
774 .LP
775 \s-1MH\s0 has no special user interface like monolithic \s-1MUA\s0s have.
776 The user does not leave the shell to run \s-1MH\s0;
777 instead he uses the various \s-1MH\s0 programs within the shell.
778 Using a monolithic program with a captive user interface
779 means ``entering'' the program, using it, and ``exiting'' the program.
780 Using toolchests like \s-1MH\s0 means running programs,
781 alone or in combination with others, also from other toolchests,
782 without leaving the shell.
784 .H 2 "Data storage
785 .LP
786 \s-1MH\s0's mail storage consists of a hierarchy under the user's
787 \s-1MH\s0 directory (usually \f(CW$HOME/Mail\fP),
788 where mail folders are directories and mail messages are text files
789 within them.
790 Each mail folder contains a file \f(CW.mh_sequences\fP which lists
791 the public message sequences of that folder,
792 for instance, the \fIunseen\fP sequence for new messages.
793 Mail messages are text files located in a mail folder.
794 The files contain the messages as they were received,
795 and they are named by ascending numbers in each folder.
796 .PP
797 This mailbox format is called ``\s-1MH\s0'' after the \s-1MUA\s0.
798 Alternatives are \fImbox\fP and \fImaildir\fP.
799 In the mbox format, all messages are stored within one file.
800 This was a good solution in the early days, when messages
801 were only a few lines of text deleted within a short period of time.
802 Today, with single messages often including several megabytes
803 of attachments, this is a bad solution.
804 Another disadvantage of the mbox format is that it is
805 more difficult to write tools that work on mail messages,
806 because it is always necessary to first find and extract
807 the relevant message in the mbox file.
808 With the \s-1MH\s0 mailbox format, each message is a separate file.
809 Also, the problem of concurrent access to one mailbox is
810 reduced to the problem of concurrent access to one message.
811 The maildir format is generally similar to the \s-1MH\s0 format,
812 but modified towards guaranteed reliability.
813 This involves some complexity, unfortunately.
814 .PP
815 Working with \s-1MH\s0's toolchest on mailboxes is much like
816 working with Unix' toolchest on directory trees:
817 \f(CWscan\fP is like \f(CWls\fP,
818 \f(CWshow\fP is like \f(CWcat\fP,
819 \f(CWfolder\fP is like \f(CWcd\fP and \f(CWpwd\fP,
820 \f(CWrefile\fP is like \f(CWmv\fP,
821 and \f(CWrmm\fP is like \f(CWrm\fP.
822 .PP
823 \s-1MH\s0 extends the context of processes in Unix by two more items
824 for its tools:
825 .IP \(bu
826 The current mail folder, which is similar to the current working directory.
827 For mail folders, \f(CWfolder\fP provides the corresponding functionality
828 of \f(CWcd\fP and \f(CWpwd\fP for directories.
829 .IP \(bu
830 Sequences, which are named sets of messages in a mail folder.
831 The current message, relative to a mail folder, is a special sequence.
832 It enables commands like \f(CWnext\fP and \f(CWprev\fP.
833 .LP
834 In contrast to the general process context in Unix,
835 which is maintained by the kernel,
836 \s-1MH\s0's context must be maintained by the tools themselves.
837 Usually there is one context per user, which resides in his
838 \f(CWcontext\fP file in the \s-1MH\s0 directory,
839 but a user can have several contexts, too.
840 Public sequences are an exception, as they belong to a mail folder,
841 and reside in the \f(CW.mh_sequences\fP file there.
842 .[
843 man page mh-profile mh-sequence
844 .]
846 .H 2 "Discussion of the design
847 .LP
848 This section discusses \s-1MH\s0 in regard to the tenets
849 of the Unix Philosophy that Gancarz identified.
851 .PP
852 .B "Small is beautiful
853 and
854 .B "do one thing well
855 are two design goals that are directly visible in \s-1MH\s0.
856 Gancarz actually uses \s-1MH\s0 in his book as example under the
857 headline ``Making \s-1UNIX\s0 Do One Thing Well'':
858 .[ [
859 gancarz
860 unix philosophy
861 .], page 125 ff.]
862 .QP
863 [\s-1MH\s0] consists of a series of programs which
864 when combined give the user an enormous ability
865 to manipulate electronic mail messages.
866 A complex application, it shows that not only is it
867 possible to build large applications from smaller
868 components, but also that such designs are actually preferable.
869 .LP
870 The various programs of \s-1MH\s0 were relatively easy to write,
871 because each one was small, limited to one function,
872 and had clear boundaries.
873 For the same reasons, they are also easy to maintain.
874 Further more, the system can easily get extended:
875 One only needs to place a new program into the toolchest.
876 This was done when \s-1MIME\s0 support was added
877 (e.g. \f(CWmhbuild\fP).
878 Also, different programs can exist to do basically the same job
879 in different ways (e.g. in nmh: \f(CWshow\fP and \f(CWmhshow\fP).
880 .PP
881 If someone needs a mail system with some additional
882 functionality that is not available anywhere yet,
883 it is beneficial to expand a toolchest system like \s-1MH\s0.
884 There he can add new functionality by simply adding additional
885 programs to the toolchest;
886 he does not risk to break existing functionality by doing so.
888 .PP
889 .B "Store data in flat text files" ;
890 this principle was followed by \s-1MH\s0.
891 This is not surprising, because email messages are already plain text.
892 \s-1MH\s0 stores the messages as it receives them,
893 thus any other tool that works on \s-1RFC\s0\|2822 compliant mail
894 messages can operate
895 on the messages in an \s-1MH\s0 mailbox.
896 All other files \s-1MH\s0 uses are plain text as well.
897 It is therefore possible and encouraged to use the text processing
898 tools of Unix' toolchest to extend \s-1MH\s0's toolchest.
900 .PP
901 .B "Avoid captive user interfaces" .
902 \s-1MH\s0 is perfectly suited for non-interactive use.
903 It offers all functions directly, without captive user interfaces.
904 If users want a graphical user interface,
905 they can have it with \fIxmh\fP, \fIexmh\fP,
906 or with the Emacs interface \fImh-e\fP.
907 These are frontends for the \s-1MH\s0 toolchest.
908 This means all email-related work is still done by \s-1MH\s0 tools,
909 but the frontend calls the appropriate commands when the user
910 clicks on buttons or pushes a key.
911 .PP
912 Providing additional user interfaces in form of frontends is a good
913 approach, because it does not limit the power of the backend itself.
914 The frontend will only be able to make a subset of the
915 backend's power and flexibility available to the user,
916 but if it is a separate program,
917 then the missing parts can still be accessed at the backend directly.
918 If it is integrated, then this will be much more difficult.
919 An additional advantage is the ability to have different frontends
920 to the same backend.
922 .PP
923 .B "Choose portability over efficiency
924 and
925 .B "use shell scripts to increase leverage and portability" .
926 These two tenets are indirectly, but nicely, demonstrated by
927 Bolsky and Korn in their book about the Korn Shell.
928 .[
929 bolsky korn
930 korn shell
931 .]
932 Chapter\|18 of the book shows a basic implementation
933 of a subset of \s-1MH\s0 in ksh scripts.
934 This is just a demonstration, but a brilliant one.
935 It shows how quickly one can implement such a prototype with shell scripts,
936 and how readable they are.
937 The implementation in scripting language may not be very fast,
938 but it can be fast enough, and this is all that matters.
939 By having the code in an interpreted language, like the shell,
940 portability becomes a minor issue if we assume the interpreter
941 to be widespread.
942 .PP
943 This demonstration also shows how easy it is to create single programs
944 of toolchest software.
945 Eight tools (two of them having multiple names) and 16 functions
946 with supporting code are presented to the reader.
947 The tools comprise less than 40 lines of ksh each,
948 in total about 200 lines.
949 The functions comprise less than 80 lines of ksh each,
950 in total about 450 lines.
951 Such small software is easy to write, easy to understand,
952 and thus easy to maintain.
953 A toolchest improves one's ability to only write some parts of a
954 program while still creating a working result.
955 Expanding the toolchest, even without global changes,
956 will likely be possible.
958 .PP
959 .B "Use software leverage to your advantage
960 and the lesser tenet
961 .B "allow the user to tailor the environment
962 are ideally followed in the design of \s-1MH\s0.
963 Tailoring the environment is heavily encouraged by the ability to
964 directly define default options to programs.
965 It is even possible to define different default options
966 depending on the name under which a program is called.
967 Software leverage is heavily encouraged by the ease of
968 creating shell scripts that run a specific command line,
969 built of several \s-1MH\s0 programs.
970 There are few pieces of software that encourages users to tailor their
971 environment and to leverage the use of the software like \s-1MH\s0.
972 .PP
973 Just to cite one example:
974 One might prefer a different listing format for the \f(CWscan\fP
975 program.
976 It is possible to take one of the distributed format files
977 or to write one yourself.
978 To use the format as default for \f(CWscan\fP, a single line,
979 reading
980 .DS
981 scan: -form FORMATFILE
982 .DE
983 must be added to \f(CW.mh_profile\fP.
984 If one wants this alternative format available as an additional command,
985 instead of changing the default, he just needs to create a link to
986 \f(CWscan\fP, for instance titled \f(CWscan2\fP.
987 The line in \f(CW.mh_profile\fP would then start with \f(CWscan2\fP,
988 as the option should only be in effect for a program that is invoked as
989 \f(CWscan2\fP.
991 .PP
992 .B "Make every program a filter
993 is hard to find implemented in \s-1MH\s0.
994 The reason is that most of \s-1MH\s0's tools provide
995 basic file system operations for mailboxes.
996 It is for the same reason because that \f(CWls\fP, \f(CWcp\fP, \f(CWmv\fP,
997 and \f(CWrm\fP aren't filters neither.
998 \s-1MH\s0 does not provide many filters itself,
999 but it provides a basis upon which to write filters.
1000 An example would be a mail text highlighter,
1001 a program that makes use of a color terminal to display header lines,
1002 quotations, and signatures in distinct colors.
1003 The author's version of such a program is an awk script with 25 lines.
1005 .PP
1006 .B "Build a prototype as soon as possible
1007 was again well followed by \s-1MH\s0.
1008 This tenet, of course, focuses on early development, which is a
1009 long time ago for \s-1MH\s0.
1010 But without following this guideline at the very beginning,
1011 Bruce Borden may have not convinced the management of \s-1RAND\s0
1012 to ever create \s-1MH\s0.
1013 In Bruce' own words:
1014 .[ [
1015 ware rand history
1016 .], page 132]
1017 .QP
1018 [...] but [Stockton Gaines and Norm Shapiro] were not able
1019 to convince anyone that such a system would be fast enough to be usable.
1020 I proposed a very short project to prove the basic concepts,
1021 and my management agreed.
1022 Looking back, I realize that I had been very lucky with my first design.
1023 Without nearly enough design work,
1024 I built a working environment and some header files
1025 with key structures and wrote the first few \s-1MH\s0 commands:
1026 inc, show/next/prev, and comp.
1027 [...]
1028 With these three, I was able to convince people that the structure was viable.
1029 This took about three weeks.
1031 .H 2 "Problems
1032 .LP
1033 \s-1MH\s0 is not without its problems.
1034 There are two main problems: one is technical, the other pertains to human behavior.
1035 .PP
1036 \s-1MH\s0 is old and email today is quite different than it was in the time
1037 when \s-1MH\s0 was designed.
1038 \s-1MH\s0 adapted to the changes fairly well, but it has its limitations.
1039 \s-1MIME\s0 support and support for different character encodings
1040 is available, but only on a moderate level.
1041 This comes from limited development resources.
1042 A larger and more active developer base could quickly remedy this.
1043 But \s-1MH\s0 is also limited by design, which is the larger problem.
1044 \s-1IMAP\s0, for example, conflicts with \s-1MH\s0's design to a large extent.
1045 These design conflicts are not easily solvable
1046 and may require a redesign.
1047 \s-1IMAP\s0 may be too incompatible with the classic mail model,
1048 which \s-1MH\s0 covers, so \s-1MH\s0 may never support it well.
1049 (Using \s-1IMAP\s0 and a filesystem abstraction layer to only map
1050 a remote directory into the local filesystem, is a different topic.
1051 \s-1IMAP\s0 support is seen as being able to access the special
1052 mail features of the protocol.)
1053 .PP
1054 The other kind of problem relates to human habits.
1055 In this world, where almost all \s-1MUA\s0s are monolithic,
1056 it is very difficult to convince people to use a toolchest-style \s-1MUA\s0
1057 like \s-1MH\s0.
1058 These habits are so strong, that even people who understand the concept
1059 and advantages of \s-1MH\s0 are reluctant to switch,
1060 simply because \s-1MH\s0 is different.
1061 Unfortunately, the frontends to \s-1MH\s0, which could provide familiar
1062 look and feel, are quite outdated and thus not very appealing in comparison
1063 to the modern interfaces of many monolithic \s-1MUA\s0s.
1064 One notable exception is \fImh-e\fP which provides an Emacs interface
1065 to \s-1MH\s0.
1066 \fIMh-e\fP looks much like \fImutt\fP or \fIpine\fP,
1067 but it has buttons, menus, and graphical display capabilities.
1069 .H 2 "Summary
1070 .LP
1071 \s-1MH\s0 is an \s-1MUA\s0 that follows the Unix Philosophy in its design.
1072 It consists of a toolchest of small tools, each of which does one job well.
1073 The toolchest approach offers great flexibility to the user.
1074 It is possible to utilize the complete power of the Unix shell with \s-1MH\s0.
1075 This makes \s-1MH\s0 a very powerful mail system,
1076 and extending and customizing \s-1MH\s0 is easy and encouraged.
1077 .PP
1078 Apart from the user's perspective, \s-1MH\s0 is development-friendly.
1079 Its overall design follows clear rules.
1080 The single tools do only one job; thus they are easy to understand,
1081 write, and maintain.
1082 They are all independent and do not interfere with the others.
1083 Automated testing of their function is a straightforward task.
1084 .PP
1085 It is sad, that \s-1MH\s0's dissimilarity to other \s-1MUA\s0s is its
1086 largest problem, as this dissimilarity is also its largest advantage.
1087 Unfortunately, most people's habits are stronger
1088 than the attraction of the clear design and the power \s-1MH\s0 offers.
1092 .H 1 "Case study: uzbl
1093 .LP
1094 The last chapter focused on the \s-1MUA\s0 \s-1MH\s0,
1095 which is an old and established piece of software.
1096 This chapter covers uzbl, a fresh new project.
1097 Uzbl is a web browser that adheres to the Unix Philosophy.
1098 Its name comes from the \fILolspeak\fP word for ``usable'';
1099 both are pronounced in the same way.
1101 .H 2 "Historical background
1102 .LP
1103 Uzbl was started by Dieter Plaetinck in April 2009.
1104 The idea was born in a thread on the Arch Linux forums.
1105 .[
1106 arch linux forums
1107 browser
1108 .]
1109 After some discussion about the failures of well-known web browsers,
1110 Plaetinck (alias Dieter@be) came up with a rough proposal
1111 of how a better web browser could look.
1112 In response to another member who asked if Plaetinck would write this
1113 program because it sounded fantastic, Plaetinck replied:
1114 ``Maybe, if I find the time ;-)''.
1115 .PP
1116 Fortunately, he found the time.
1117 One day later, the first prototype was out.
1118 One week later, uzbl had its own website.
1119 .[
1120 uzbl website
1121 .]
1122 One month after the initial code was presented,
1123 a mailing list was set up to coordinate and discuss further development,
1124 and a wiki was added to store documentation and scripts that cropped up
1125 on the mailing list and elsewhere.
1126 .PP
1127 In the first year of uzbl's existence, it was heavily developed on various branches.
1128 Plaetinck's task became more and more to only merge the best code from the
1129 different branches into his main branch, and to apply patches.
1130 .[
1131 lwn uzbl
1132 .]
1133 About once a month, Plaetinck released a new version.
1134 In September 2009, he presented several forks of uzbl.
1135 .[ [
1136 uzbl website
1137 .], news archive]
1138 Uzbl actually opened the field for a whole family of web browsers with
1139 a similar design.
1140 .PP
1141 In July 2009, \fILinux Weekly News\fP published an interview with
1142 Plaetinck about uzbl.
1143 .[
1144 lwn uzbl
1145 .]
1146 In September 2009, the uzbl web browser was on \fISlashdot\fP.
1147 .[
1148 slashdot uzbl
1149 .]
1151 .H 2 "Contrasts to other web browsers
1152 .LP
1153 Like most \s-1MUA\s0s are monolithic, but \s-1MH\s0 is a toolchest,
1154 most web browsers are monolithic, but uzbl is a frontend to a toolchest.
1155 .PP
1156 Today, uzbl is divided into uzbl-core and uzbl-browser.
1157 Uzbl-core is, as its name indicates, the core of uzbl.
1158 It handles commands and events to interface with other programs,
1159 and displays webpages by using \fIwebkit\fP as its rendering engine.
1160 Uzbl-browser combines uzbl-core with a selection of handler scripts,
1161 a status bar, an event manager, yanking, pasting, page searching,
1162 zooming, and much more functionality, to form a ``complete'' web browser.
1163 In the following text, the term ``uzbl'' usually refers to uzbl-browser,
1164 so uzbl-core is included.
1165 .PP
1166 Unlike most other web browsers, uzbl is mainly the mediator between
1167 various tools that cover single jobs.
1168 Uzbl listens for commands on a named pipe (fifo), a Unix socket,
1169 and on stdin, and it writes events to a Unix socket and to stdout.
1170 Loading a webpage in a running uzbl instance requires only:
1171 .DS
1172 echo 'uri http://example.org' >/path/to/uzbl-fifo
1173 .DE
1174 The rendering of the webpage is done by libwebkit,
1175 around which uzbl-core is built.
1176 .PP
1177 Downloads, browsing history, bookmarks, and the like are not provided
1178 by the core itself like they are in other web browsers.
1179 Uzbl-browser also only provides ``handler scripts'' which wrap
1180 external applications to provide the actual functionality.
1181 For instance, \fIwget\fP is used to download files and uzbl-browser
1182 includes a script that calls wget with appropriate options in
1183 a prepared environment.
1184 .PP
1185 Modern web browsers are proud to have addons, plugins, modules,
1186 and so forth.
1187 This is their effort to achieve similar goals.
1188 But instead of using existing external programs, modern web browsers
1189 include these functions.
1191 .H 2 "Discussion of the design
1192 .LP
1193 This section discusses uzbl in regard to the Unix Philosophy,
1194 as identified by Gancarz.
1196 .PP
1197 .B "Make each program do one thing well" .
1198 Uzbl tries to be a web browser and nothing else.
1199 The common definition of a web browser is highly influenced by
1200 existing implementations of web browsers.
1201 But a web browser should be a program to browse the web, and nothing more.
1202 This is the one thing it should do.
1203 .PP
1204 Web browsers should not, for instance, manage downloads;
1205 this is the job of download managers.
1206 A download manager is primary concerned with downloading files.
1207 Modern web browsers provide download management only as a secondary feature.
1208 How could they do this job better than programs that exist only for
1209 this very job?
1210 And why would anyone want less than the best download manager available?
1211 .PP
1212 A web browser's job is to let the user browse the web.
1213 This means, navigating through websites by following links.
1214 Rendering the \s-1HTML\s0 sources is a different job, too.
1215 In uzbl's case, this is covered by the webkit rendering engine.
1216 Handling audio and video content, PostScript, \s-1PDF\s0,
1217 and other such files are also not the job of a web browser.
1218 Such content should be handled by external programs
1219 that were written to handle such data.
1220 Uzbl strives to do it this way.
1221 .PP
1222 Remember Doug McIlroy's words:
1223 .I
1224 ``Write programs that do one thing and do it well.
1225 Write programs to work together.''
1226 .R
1227 .PP
1228 The lesser tenet
1229 .B "allow the user to tailor the environment
1230 applies here as well.
1231 Previously, the question, ``Why would anyone want anything less than the
1232 best program for the job?'' was put forward.
1233 But as personal preferences matter, it might be more important to ask:
1234 ``Why would anyone want something other than his preferred program for
1235 the job?''
1236 .PP
1237 Users typically want one program for a specific job.
1238 Hence, whenever one wishes to download something,
1239 the same download manager should be used.
1240 More advanced users might want to use one download manager in a certain
1241 situation and another in a different situation;
1242 they should be able to configure it this way.
1243 With uzbl, any download manager can be used.
1244 To switch to a different one, a single line in a small handler script
1245 needs to be changed.
1246 Alternatively, it would be possible to query which download manager to use by
1247 reading a global file or an environment variable in the handler script.
1248 Of course, uzbl can use a different handler script as well.
1249 This simply requires a one line change in uzbl's configuration file.
1250 .PP
1251 Uzbl neither has its own download manager nor depends on a specific one;
1252 hence, uzbl's browsing abilities will not be crippled by having
1253 a bad download manager.
1254 Uzbl's download capabilities will be as good as the best
1255 download manager available on the system.
1256 Of course, this applies to all of the other supplementary tools, too.
1258 .PP
1259 .B "Use software leverage to your advantage" .
1260 Uzbl is designed to be extended by external tools.
1261 These external tools are usually wrapped by small handler shell scripts.
1262 Shell scripts form the basis for the glue which holds the various
1263 parts together.
1264 .PP
1265 The history mechanism of uzbl shall be presented as an example.
1266 Uzbl is configured to spawn a script to append an entry to the history
1267 whenever the event of a fully loaded page occurs.
1268 The script to append the entry to the history is not much more than:
1269 .DS
1270 #!/bin/sh
1271 file=/path/to/uzbl-history
1272 echo `date +'%Y-%m-%d %H:%M:%S'`" $6 $7" >> $file
1273 .DE
1274 \f(CW$6\fP and \f(CW$7\fP expand to the \s-1URL\s0 and the page title,
1275 respectively.
1276 .PP
1277 For loading an entry, a key is bound to spawn a load-from-history script.
1278 The script reverses the history to have newer entries first,
1279 displays \fIdmenu\fP to let the user select an item,
1280 and then writes the selected \s-1URL\s0 into uzbl's command input pipe.
1281 With error checking and corner case handling removed,
1282 the script looks like this:
1283 .DS
1284 #!/bin/sh
1285 file=/path/to/uzbl-history
1286 goto=`tac $file | dmenu | cut -d' ' -f 3`
1287 echo "uri $goto" > $4
1288 .DE
1289 \f(CW$4\fP expands to the path of the command input pipe of the current
1290 uzbl instance.
1292 .PP
1293 .B "Avoid captive user interfaces" .
1294 One could say that uzbl, to a large extent, actually \fIis\fP
1295 a captive user interface.
1296 But the difference from other web browsers is that uzbl is only
1297 the captive user interface frontend (and the core of the backend).
1298 Many parts of the backend are independent of uzbl.
1299 For some external programs, handler scripts are distributed with uzbl;
1300 but arbitrary additional functionality can always be added if desired.
1301 .PP
1302 The frontend is captive \(en that is true.
1303 This is okay for the task of browsing the web, as this task is only relevant
1304 to humans.
1305 Automated programs would \fIcrawl\fP the web, that means,
1306 read the source directly, including all semantics.
1307 The graphical representation is just for humans to understand the semantics
1308 more intuitively.
1310 .PP
1311 .B "Make every program a filter" .
1312 Graphical web browsers are almost dead ends in the chain of information flow.
1313 Thus it is difficult to see what graphical web browsers should filter.
1314 Graphical web browsers exist almost exclusively to be interactively used
1315 by humans.
1316 The only case in which one might want to automate the rendering function is
1317 to generate images of rendered webpages.
1319 .PP
1320 .B "Small is beautiful"
1321 is not easy to apply to a web browser because modern web technology
1322 is very complex; hence, the rendering task is very complex.
1323 Unfortunately, modern web browsers ``have'' to consist of many thousand
1324 lines of code,
1325 Using the toolchest approach and wrappers can help to split the browser
1326 into several small parts, though.
1327 .PP
1328 As of March 2010, uzbl-core consists of about 3\,500 lines of C code.
1329 The distribution includes another 3\,500 lines of Shell and Python code,
1330 which are the handler scripts and plugins like one to provide a modal
1331 interface.
1332 Further more, uzbl makes use of external tools like
1333 \fIwget\fP and \fIsocat\fP.
1334 Up to this point, uzbl looks pretty neat and small.
1335 The ugly part of uzbl is the rendering engine, webkit.
1336 Webkit consists of roughly 400\,000 (!) lines of code.
1337 Unfortunately, small rendering engines are not feasible anymore
1338 due to the nature of the modern web.
1340 .PP
1341 .B "Build a prototype as soon as possible" .
1342 Plaetinck made his code public right from the beginning.
1343 Discussion and development was, and still is, open to everyone interested,
1344 and development versions of uzbl can be obtained very easily from the
1345 code repository.
1346 Within the first year of uzbl's existence, a new version was released
1347 more often than once a month.
1348 Different forks and branches arose introducing new features which were
1349 then considered for merging into the main branch.
1350 The experiences with using prototypes influenced further development.
1351 Actually, all development was community driven.
1352 Plaetinck says, three months after uzbl's birth:
1353 ``Right now I hardly code anything myself for Uzbl.
1354 I just merge in other people's code, ponder a lot, and lead the discussions.''
1355 .[
1356 lwn
1357 uzbl
1358 .]
1361 .H 2 "Problems
1362 .LP
1363 Similar to \s-1MH\s0, uzbl suffers from being different.
1364 It is sad, but people use what they know.
1365 Fortunately, uzbl's user interface can be made to look and feel very similar
1366 to the one of the well known web browsers,
1367 hiding the internal differences.
1368 But uzbl has to provide this similar look and feel to be accepted
1369 as a ``normal'' browser by ``normal'' users.
1370 .PP
1371 The more important problem here is the modern web.
1372 The modern web is simply broken.
1373 It has state in a state-less protocol, misuses technologies,
1374 and is helplessly overloaded.
1375 This results in rendering engines that ``must'' consist
1376 of hundreds of thousands of lines of code.
1377 They also must combine and integrate many different technologies
1378 to make our modern web accessible.
1379 This results, however, in a failing attempt to provide good usability.
1380 Website-to-image converters are almost impossible to run without
1381 human interaction because of state in sessions, impossible
1382 deep-linking, and ``unautomatable'' technologies.
1383 .PP
1384 The web was misused in order to attempt to fulfill all kinds of wishes.
1385 Now web browsers, and ultimately users, suffer from it.
1388 .H 2 "Summary
1389 .LP
1390 ``Uzbl is a browser that adheres to the Unix Philosophy'',
1391 is how uzbl is seen by its authors.
1392 Indeed, uzbl follows the Unix Philosophy in many ways.
1393 It consists of independent parts that work together,
1394 while its core is mainly a mediator which glues the parts together.
1395 .PP
1396 Software leverage is put to excellent use.
1397 External tools are used, independent tasks are separated out
1398 to independent parts and glued together with small handler scripts.
1399 .PP
1400 Since uzbl roughly consists of a set of tools and a bit of glue,
1401 anyone can put the parts together and expand it in any desired way.
1402 Flexibility and customization are properties that make it valuable
1403 for advanced users, but may keep novice users from understanding
1404 and using it.
1405 .PP
1406 But uzbl's main problem is the modern web, which makes it very difficult
1407 to design a sane web browser.
1408 Despite this bad situation, uzbl does a fairly good job.
1411 .H 1 "Final thoughts
1413 .LP
1414 This paper explained why good design is important.
1415 It introduced the Unix Philosophy as a set of guidelines that encourage
1416 good design in order to create good quality software.
1417 Then, real world software that was designed with the Unix Philosophy
1418 in mind was discussed.
1419 .PP
1420 Throughout this paper, the aim was do explain \fIwhy\fP something
1421 should be done the Unix way.
1422 Reasons were given to substantiate the claim that the Unix Philosophy
1423 is a preferable way of designing software.
1424 .PP
1425 The Unix Philosophy is close to the software developer's point of view.
1426 Its main goal is taming the beast known as ``software complexity''.
1427 Hence it strives first and foremost for simplicity of software.
1428 It might appear that usability for humans is a minor goal,
1429 but actually, the Unix Philosophy sees usability as a result of sound design.
1430 Sound design does not need to be ultimately intuitive,
1431 but it will provide a consistent way to access the enormous power
1432 of software leverage.
1433 .PP
1434 Being able to solve some specific concrete problem becomes less and less
1435 important as there is software available for nearly every possible task
1436 today.
1437 But the quality of software matters.
1438 It is important that we have \fIgood\fP software.
1439 .sp
1440 .LP
1441 .B "But why the Unix Philosophy?
1442 .PP
1443 The largest problem of software development is the complexity involved.
1444 It is the only part of the job that computers cannot take over.
1445 The Unix Philosophy fights complexity, as it is the main enemy.
1446 .PP
1447 On the other hand,
1448 the most unique advantage of software is its ability to leverage.
1449 Current software still fails to make the best possible use of this ability.
1450 The Unix Philosophy concentrates on exploiting this great opportunity.
1453 .bp
1454 .TL
1455 References
1456 .LP
1457 .XS
1458 .sp .5v
1459 .B
1460 References
1461 .XE
1462 .ev r
1463 .nr PS -1
1464 .nr VS -1
1465 .[
1466 $LIST$
1467 .]
1468 .nr PS +1
1469 .nr VS +1
1470 .ev
1472 .bp
1473 .TL
1474 Table of Contents
1475 .LP
1476 .PX no