Most of my ``lectures'' are meant as conversation starters. Talking With Computers covers a lot of territory and the text is meant to expose readers to different computational perspectives. Time spent in class is an opportunity to explore those perspectives and a chance to challenge existing views and invent new ones.
The first time I taught this course I began the first lecture by talking about some of the code I'd written during the summer. Some was written to deal with problems that came up like dealing with a particularly virulent computer virus attack, some of it was part of my research and some of it was just for fun. Hacking for fun is no stranger than working on crossword puzzles or reading junky paperbacks while sunning yourself on the beach.
This year we'll look at an application that I wrote (once again) while on vacation on Prince Edward Island. The application was inspired by reading about famous computer pioneers and what motivated them. I've called the application Memories Incorporated and you can read more about it by clicking on the name. Your first assignment will be to read this piece and the article by Vannevar Bush which it provides a link to. We'll use Memories Incorporated as motivation for much of the first part of the course. In particular, you'll be learning about the various technologies (programming languages, networking protocols, database systems) that make Memories Incorporated possible. Go ahead and read about Memories Incorporated now before we move on to the material in Chapter 1 of Talking With Computers.
In this section, we'll analyze the shell script described in the Everyday Magic section of Chapter 1, picking it apart, looking at it from different perspectives and then thinking about how to extend it. Since this lecture contains a couple of graphics that don't display particularly well in a browser, I've summarized the main ``talking points'' on this web page in few slides in PDF. Here's the script from Chapter 1:1
% ls home.html syllabus.html % ls *.html | sed 's/html//' | awk '{print "mv " $1 "html " $1 "htm"}' | sh % ls home.htm syllabus.htm
Dissect this script by identifying smaller computational components:
ls *.html -- filter2 a list of file names using regular expressions and pattern matching
sed 's/html//' -- edit the file names using simple text manipulation commands3
awk '{print "mv " $1 "html " $1 "htm"}' -- use parameter substitution to implement a simple subroutine4
sh -- exploit the interchangeability of data and code to evaluate subroutine calls
Use the plumbing metaphor to visualize the shell script. What other sort of computations can you imagine using this metaphor? What about the possible role of pumps, valves, drains, T and Y junctions, reservoirs and filters?
![]() |
Let's try another metaphor. Imagine bureaucrats passing paperwork via pneumatic tubes in 19th-century factories and office buildings. Suppose you're the bureaucrat responsible for ``listing directories.'' How is your job different from the person responsible for ``editing streams''? As in the case of plumbing, try to extend the metaphor.
![]() |
Think about extending the script to perform other tasks.
Imagine a general utility for changing file extensions.
How would you specify the from and to extension strings?
Invent a notion of free parameters and explore analogs in everyday speech.
Now go for something more ambitious.
You've changed the extensions for all the HTML files, but what about the internal references to those files?
It should be clear that you can't just change all occurrences of "html" to "htm".
How might you use context to determine when it's appropriate to make a change?
Students are often reluctant to ask questions and concerned about appearing clueless in class. Please don't hesitate to ask your questions; it's very likely that you have the same questions as your classmates. We're not in any hurry; if we don't get to all the material planned for a given class then that's just fine. Here's a sample of questions that students have asked on the first day of class:
What's a program? Or, alternatively, what's not a program? Any piece of text can be interpreted as a program or as data. Think of an old fashioned player piano that takes pieces of music in the form of rolls of paper with holes strategically punched to indicate musical notes. These perforated rolls of paper can be thought of as programs. If you were to punch holes randomly in a roll of paper, you'd probably end up with an awful piece of music, but it would still be a program.
But what if you were to slash a roll of paper into ribbons with a knife? Would that be a program? Sometimes computer scientists talk about syntactically well-formed expressions. What do you think they mean by this? Do you think a syntactically well formed program would necessarily be meaningful to a computer? Do colorless green ideas sleep furiously?5
Why are computers so rigid and difficult to interact with? Computer science is full of conventions that correspond to specific (often pretty rigid) ways of referring to things and exchanging information. Most programs are not very forgiving when it comes to interpreting input. Do they really have to be so unfriendly? Consider the following protocol for responding to a yes-or-no question (the double vertical bars (||) denote logical or):
print "Answer yes or no: " ; response = read the user's response from the terminal ; if response = "yes" || response = "YES" || response = "Yes" || response = "y" || response = "OK" || response = "sure" || ... then do the yes thing else if response = "no" || response = "NO" || response = "No" || response = "n" || response = "no way" || ... then do the no thing else print "Please type 'yes' or 'no'." ; response = read from the terminal ; if response = "yes" then do the yes thing else if response = "no" then do the no thing else print "Sorry; I don't understand!" ;
That seems pretty flexible. Why couldn't we do more of the same and make computers more accommodating? We could and, in some cases, we do, but there are limits to what we can manage with today's technology. Think about how difficult it would be to extend the above protocol to make it absolutely foolproof.
What's the value of all these metaphors involving plumbing parts and pneumatic tubes? Why can't we talk directly about the ``machinery of computation'' (whatever that is)? Well, we'll talk about so-called ``digital circuits'' and how computations are carried out in hardware (in Chapter 9), but we'll still be using metaphors and abstractions. Metaphors and abstractions are important tools in thinking about computation. Software engineers typically use arcane terminology in discussing their projects, but internally they're probably thinking of pieces of code as homunlculi (little men) that pass messages back and forth which is a useful metaphor for thinking about object-oriented programming (covered in Chapter 7).
In this exercise, you'll learn how to move around in the Unix/Linux directory structure accessible from the machines in the Brown Internet Computing Laboratory.6 In particular, you'll learn about the basic commands used to display your current working directory, change your current working directory, list the contents of a directory or directories, and list and modify permissions.
Use info info and man man to read about the commands that will help you learn about other commands. If you need information but don't know the name of the command that you want to learn about, use apropos or man -k followed by a keyword that you think might be relevant to the command you're looking for. For example, the invocations apropos group and man -k group will list all the commands that refer to the word group in their documentation.
Learn about ls, pwd and chdir using info or man and then use these commands to find the following directories; start by looking in the directories at the root of the file system, for example /var/ or /etc/):
the directory where the ls command is found,
the directory containing lefty,
the directory containing all the words in the Second Edition7 of Webster's International Dictionary,
a directory containing source code written in the C or C++ programming languages, and
a directory containing web pages (web pages typically have an extension html or htm).
To find out the path that the shell uses to locate commands try echo $path. Find a command in one of the directories defined in your path and then use man to learn about that command. Summarize what the command does.
Learn about the which command to find out the absolute path names of commands. Find the directory containing your shell program using echo $shell and list the other shells you find there.
Investigate the contents of /usr/, /etc/, /var/, and /bin/ and try to characterize the sorts of things you find in each directory.
The list directory command ls with the list-all option -a lists all files including hidden ones. Use ls -a to identify all the hidden files in your home directory.
The list directory command ls with the long-format option -l provides all sorts of additional information about files. Use ls -l to find the oldest file stored on your system.
Use info to learn about mkdir and then invoke mkdir bin to create a directory in your home directory called bin. Use ls -l to list the permissions associated with this directory.
Learn about chmod and then use this command to change the permissions of your bin directory so that you can read, write and execute in this directory, your default group can read and execute but not write, and no one else can either read, write or execute.
There are directories outside of your home directory where you have the permission to write as well as read.
take a look at the email in your spool file:
% ls /var/spool/mail/
use the tmp directory to store something:
% echo "Hello!" > /tmp/text.txt % cat /tmp/text.txt Hello!
direct some text into the bit bucket:8
% echo "Hello!" > /dev/null
Find out what groups you belong to using the groups command. Use touch test to create a file called test. Use ls -l to determine what group the file belongs to and then use chgrp to change the group ownership of test to some other group that you belong to.
Find out the name of a group that you don't belong to and then attempt to change the group ownership of test to this group. Explain why you think permissioning is handled in this way.
Download all the code fragments in this chapter as a file in zip format.
1 Sometimes it's impossible or simply awkward to write a ``one-line'' shell script on a single line. You can, however, extend a one-line script over multiple lines by telling the shell to ignore carriage returns (also called ``new lines'' or ``line feeds'') using the backslash character \ as in:
% ls *.html | \ sed 's/html//' | \ awk '{print "mv " $1 "html " $1 "htm"}' | \ sh
2 The term filter refers to any program that reads from the standard input, performs some operation on the input, and then writes the result to the standard output. Using Unix pipes you can easily pipe the contents of files or text typed to the terminal through a sequence of filters.
3 The name of this program derives from ``stream editor''. As we'll see in Chapter 2, sed is often used in shell scripts primarily for its powerful substitution command as illustrated here.
4 An interpreter for a special-purpose programming language used for text processing and data formatting. The original version of awk was written in 1977 at AT&T Bell Laboratories by Alfred Aho, Peter Weinberger and Brian Kernighan, hence the name.
5 The linguist Noam Chomsky used this as an example of a sentence whose grammar (referring to its syntactic structure) is correct but its meaning (often referred to as its semantics) is nonsensical. Chomsky was trying to make the point that grammar is not the fundamental structure underlying language as was thought at the time.
6 If you're at home and your computer is running a Microsoft operating system such as Windows 2000 or Windows XP, you can use Cygwin (a Unix/Linux-like environment for Windows) to follow along.
7 The Second Edition of Webster's International Dictionary contains some 234,936 words. The 1934 copyright has lapsed and hence you often find a list of all the words in this dictionary tucked away in a little known directory ready to use for all sorts of text processing applications. As a hint, learn how to use wildcards with the ls command and then look for a directory whose name includes the first few letters of the word dictionary.
8 The null device /dev/null (also known as the ``bit bucket'') is a virtual device which is treated as a device, as far as user level software is concerned, but is generated by the operating system without reference to hardware. When /dev/null is written to, the operating system tells the program that it wrote everything to this device (without actually writing it anywhere); when read from, the reading program is told that it has reached the end of the file.