\documentstyle[11pt]{article}
\input{use-full-page}

\begin{document}
\bibliographystyle{alpha}
\title{A Critical Evaluation of the C-Shell}
\author{Gary T. Leavens}
\maketitle

The UNIX ``C-shell'', csh \cite[Entry ``csh'']{UNIX42},
is a command language with the syntax of the ``C'' programming language.
Unfortunately, its syntax is sufficiently different from C syntax,
and this lack of sharp distinction or close compatibility makes csh
programming unnecessarily difficult.
On the other hand, the history mechanism and other user-interface features
of csh make csh attractive for interactive users.

In the following, the main features of csh are described,
and then csh is evaluated as a programming language.

\section{Command Language Features}

A command language should facilitate programming in the large,
job control, and navigation over the user's state. 

\subsection{Programming in the Large}

The essential feature of a language for programming in the large
is the ability to call programs (as commands).
In csh, programs can be called with positional arguments,
separated by whitespace (blanks or tabs).
Keyword arguments are supported to a limited extent by the
``shell environment'' and to a limited extent by the conventional use
of first parameters of the form ``-k value.''

Programs also can obtain information from files.
In UNIX, a process has access to several numbered file descriptors,
and so does not need to know the names of all files it uses.
By convention in C programs, the standard input, standard output,
and standard error output files are assigned file descriptors 0, 1, and 2.
Csh follows the Bourne shell \cite{Bourne78} \cite[Entry ``sh'']{UNIX42}
in using the characters \verb|<|, and \verb|>|
to attach files to standard input and standard output.
In csh, the standard error output can be directed to the same file as
the standard output by using the characters \verb|>&|.
(However, the more general mechanism of the Bourne shell for attaching
files to an arbitrary file descriptor has been abandoned by csh.)
Csh also follows the Bourne shell in using the characters \verb|<<| to indicate
the start of user-supplied input.

Another essential feature of programming in the large is composition
primitives.
Csh provides mechanisms for combining programs in sequence (\verb|;|),
in parallel (\verb|&|), conditionally (\verb|if|, \verb|switch|),
and repeatedly (\verb|foreach|, \verb|while|).
More interesting is a mechanism present in the Bourne shell: pipelining.
Programs combined in a pipeline run in parallel, but the output of one is
directed into the input of another.

The last requirement for programming in the large is
abstraction mechanisms.
Csh provides command files (called shell scripts),
individual procedures written in csh and stored in separate files.
However, the dynamic scoping of csh makes it difficult to package several
procedures into a coherent whole.
The most notable problem concerns finding other procedures,
which is done by a dynamic search through the directories listed in the
(dynamic) value of shell environment variable named ``PATH''.
If the called shell procedure needs to invoke another command,
it must either invoke it in a way that avoids the dynamic search
or it must reset the ``PATH'' variable to something it knows will work.
Either option  makes the text of the command file dependent on information
(the locations of other command files or executables)
that is likely to change.

\subsection{Job Control}

Csh provides adequate
facilities for running programs in the background (\verb|bg|),
finding the status of jobs (\verb|jobs|),
changing the status of jobs (\verb|fg|, \verb|bg|, \verb|kill|),
waiting for jobs to complete (\verb|wait|),
and handling interrupts.

\subsection{Navigation}


Since the purpose of a command is to cause side-effects on the user's state
(e.g., the file system),
and since the user's state is typically complex and structured,
a command language needs to provide a way for the user to access parts
of the state.

The best feature of csh is its history mechanism,
which lets the user navigate the sequence of previously executed commands
and minimizes typing.

Csh allows the user to navigate the file system by positioning the user
in the directory structure and by providing file name
expansion and completion.

The main primitive for moving about the directory structure is the \verb|cd|
command, which changes the shell's working directory.
Csh also maintains a directory stack, which will remember where the user
was and allows subtasks to be executed without forgetting context.
Furthermore, csh has special syntax \verb|~user|
for finding the ``home'' directory
of a user, which typically gives access to all of that user's files.

The other aids to navigation of the file system are file name expansion
which allows one to name several files by giving a pattern,
and file name completion,
which in interactive use expands a partial file name as far as possible.
This latter feature saves typing.

Other features of csh allow more mundane listing of parts of the users state,
such as currently running jobs.

\section{Csh as a Programming Language}

A command language should also be a reasonable programming language
in its domain, having well thought-out mechanisms,
and following established principles of programming language design.

\subsection{Syntax}

The syntax of csh is rather baroque and context sensitive.
Part of the problem is that the syntax is supposed to be like the syntax of C,
which is itself rather complex.
The other part of the problem is the changes that were made to the syntax of C
necessitated by the different application areas.
Thus csh violates the syntactic consistency principle in several ways.
First csh has constructs that are similar but not identical to C;
for example, the {\tt switch} statement of C (which is not one of C's most
attractive features) is adopted in csh, but the {\tt break} statement
that goes with it is made into {\tt breaksw};
another example is the lack of statement sequences delimited by curly brackets
as in C.
Second, csh uses the same tokens for widely different purposes;
for example,
\verb|<| means file redirection in commands but ``strictly less than''
in the context of the expression that follows an {\tt if}.

Another syntactic problem is the distinction between the syntax recognized
in interactive use and the syntax recognized in command files.
The lack of comments in interactive use is especially troubling,
since if one wishes to paste in text from a shell file for its effect,
the comments will not have their desired (non-)effect.

\subsection{Scope Rules}

Csh uses dynamic scoping, as a command file is interpreted in the caller's
environment.
The use of dynamic scoping makes little sense,
since the user is unable to communicate reliably with commands that are
invoked by other commands.

\subsection{Orthogonality}

The most distressingly non-orthogonal part of csh is its distinction between
``expressions'' and ``commands''.
In the Bourne shell, the conditions in a {\tt if} or {\tt while}
are command invocations, which either succeed or fail
depending on their return code (with 0 being success).
In csh, there is a different syntax for these conditions,
one which more closely matches C.
However, csh also provides conditional execution based on the return
status by using \verb|&&| and \verb'||' or the environment
variable {\tt status}.
These separate mechanisms for achieving the same effect are more difficult
to use than in the Bourne shell, because they are less orthogonal.

Furthermore, the treatment of success does not mesh well with the C language's
notion of truth that has been adopted in csh,
since a successful program returns 0 whereas ``true'' in C is 1.
This irregularity makes the specific rules difficult to remember.

\section{Conclusions}

When used interactively, csh has several attractive features:
the history mechanism and filename completion.
However, for programming in the large, csh suffers from a syntax that
is close to C's without being identical,
from its use of dynamic scoping,
and from its poor integration of the notion of the success of a command
with its conditionals.

\bibliography{journal-abbrevs,csh}
\end{document}

