\documentstyle{report}
\pagestyle{headings}
\begin{document}
\title {
Survey of Quick Interpreted Languages
}
\author {
Terrence Monroe Brannon \\
PO Box 5027 \\
Bethlehem, PA 18015 \\
$tb06@pl122e.eecs.lehigh.edu$
}
\maketitle
\tableofcontents
\part {Introduction and Conclusion}
The purpose of this report is to expose people to several languages which
can cutdown/eliminate shell programming and C programming.
All of these languages are quick interpreted languages which can do
things in a few lines which might take hundreds of lines of C/shell
code. They typically have all of the following features:
\begin {itemize}
\item The ability to modify the source code at runtime, adding new
procedures or modifying old ones.
\item An efficiently hashed associative data type.
\item Loose typing
\item The interpreter has no preconceptions about each sentence (valid
syntactic phrase) it will execute. In other words it knows nothing (return
type, datatype) ahead of time about the data or functions in memory.
\end {itemize}
These languages are evaluated in terms of the three things that any
programmer desires from a language: power, speed, and ease of use. Power
means a wealth of libraries for any task needed resulting in less time
required for developing/protoyping software. Speed means execution speed.
Ease of use includes how well documented the language is, how
much support there is for problems with the language, and how cleanly
extensible the language is.
\section {The Languages}
\subsection {Lisp: Emacs version}
The Emacs Lisp editor has a core of functions including an interpreter
written C to return Lisp Objects. On top of this a number of Lisp Functions
for common tasks such as editing, buffering, process control, string
handling, user interaction/input completion, and mathematics have been
coded in C.
As a result, virtually Anything Emacs does is done by a callable lisp
function which means you can write programs to take advantage of this
power.
But you can only do it inside of Emacs Lisp for
the most part. The two work arounds are: (1) use emacs-server.el which
allows Emacs to send/receive on sockets, message queues and pipes or (2)
use emacs server mode. (3) For my M.S. thesis, I developed a C library
which allows Tcl and GNU Smalltalk to invoke Emacs' processes and send the
process Lisp forms for evaluation and then have the data converted back
into a format useable by the calling language.
Emacs can interact with other programs is through its batch mode
which is callable from C or shell scripts. Also, Emacs can start up
external programs and talk with them via process objects synchronously or
asynchronously. Danial LaLiberte wrote an Emacs interface to
an incremental parser that runs simultaneously with Emacs and has
bidirectional communication with Emacs.
You may obtain Emacs Lisp via the following ftp site:
\begin {itemize}
\item "/anonymous@src.doc.ic.ac.uk:/pub/gnu"
\item "/anonymous@prep.ai.mit.edu:/pub/gnu"
\end {itemize}
\subsection {Perl}
Combines the best features of awk, sed, and shell programming. The
latest version can be embedded in C programs. It is also easy to call
from the shell.
Perl can be linked with external C libraries, such as curses or
database accessing libraries, like oracle or sybase, making for
easy access to screen-based form programs to deal with your dbase.
Perl may be obtained from the following ftp sites:
\begin {itemize}
\item "/anonymous@convex.com:/pub/perl"
\item "/anonymous@archive.cs.ruu.nl:/DOC"
\end {itemize}
\subsection {Python}
An object-oriented interpreted language. Callable from C as well as the
shell. Interpretation may be sidestepped through the use of the
byte-compiler on files. Python played a major role in testing Amoeba, a
distributed operating system developed at CWI.
Python has been chosen as one of the extension languages for MADE, a
multimedia application development environment being designed and
built for ESPRIT (an EC programme for cooperative computer science
research) together with several European companies.
Several companies have significant interest in Python for
products and/or internal development; amongst these are XVT, Sunrise
Software, Island Software, VI Corporation, and Cabletron.
It's central goal is to provide the best of both worlds:
the dynamic nature of scripting languages like Perl/TCL/REXX,
but also support for general programming found in the more
traditional languages like Icon, C, Modula,...
Python resembles other scripting languages a number of ways:
- dynamic, interpretive, interactive nature
- no explicit compile or link steps needed
- no type declarations (it's dynamically typed)
- high-level operators ('in', concatenation, etc)
- automatic memory allocation/deallocation (no 'pointers')
- high level objects: lists, tuples, strings, associative arrays
- programs can construct and execute program code using strings
- very fast edit/compile/run cycle; no static linking
- well-defined interface to and from C functions and data
- well-defined ways to add C modules to the system and language
Python's features that make it useful for serious programming:
- it's object-oriented; it has a simplified subset of
C++'s 'class' facility, made more useful by python's
dynamic typing; the language is object-oriented from
the ground up (rather than being an add-on, as in C++)
- it supports modules (imported packages, as in Modula-3);
modules replace C's 'include' files and linking, and allow
for multiple-module systems, code sharing, etc.;
- it has a good exception handling system (a 'try' statement,
and a 'raise' statement, with user-defined exceptions);
- it's orthogonal; everything is a first-class object in the
language (functions, modules, classes, class instance methods...)
and can be assigned/passed and used generically;
- it's fairly run-time secure; it does many run-time checks
like index-out-of-bounds, etc., that C usually doesn't;
- it has general data structuring support; Python lists are
heterogeneous, variable length, nestable, support slicing,
concatenation, etc., and come into existance and are reclaimed
automatically; strings and dictionaries are similarly general;
- it's got a symbolic debugger and profiler (written in python,
of course..), and an interactive command-line interface;
as in Lisp, you can enter code and test functions in isolation,
from the interactive command line (even linked C functions);
- it has a large library of built-in modules; it has support
for sockets, regular expressions, posix bindings, etc.
- it supports dynamic loading of C modules on many platforms;
- it has a readable syntax; python code looks like normal
programming languages; tcl and perl can be very unreadable
(IMHO; what was that joke about Perl looking the same after
rot13..); python's syntax is simple, and statement based;
Of course, Python isn't perfect, but it's a good compromise betweem
scripting languages and traditional ones, and so is widely applicable.
'Perfect' languages aren't always useful for real-world tasks (Prolog,
for example), and languages at either extreme are not useful in the other
domain (C is poor for shell coding and prototyping, and awk is useless
for large systems design; Python does both well).
For example, I've used Python successfully for a 4K line expert system
shell project; it would have been at least twice as large in C, and would
have been very difficult in TCL or Perl.
Python uses an indentation-based syntax which may seem unusual at first
to C coders, but after using it I have found it to be very handy, since
there's less to type. [I now forget to type '\}' in my C code, and am
busy calculating how much time I wasted typing all those '\}', 'END', etc.,
just to pander to 'brain-dead' C/Pascal compilers :-)].
Python is available from the following sites:
\begin {itemize}
\item "/anonymous@ftp.cwi.nl:/pub"
\item "/anonymous@gatekeeper.dec.com:/pub/plan/python/cwi"
\item "/anonymous@ftp.uu.net:/languages/python"
\item "/anonymous@wuarchive.wustl.edu:/pub"
\end {itemize}
To get on the mailing list mail {\tt python-list-request@cwi.nl}.
\subsection {Tcl}
Tcl itself is a deceptively simple string-oriented language intended to be
transparently extensible in C or Tcl. Tcl has been extended to make use of
many typically non-unified systems and protocols such as SQL, curses,
ToolTalk, and most notably, X-Windows. Tcl can do a 5 page X-Windows program in
*2* lines and more.
>From having programming in Tcl extensively, I have noticed two very useful
aspects about Tcl. First, Tcl is a modeless language, meaning that it
does not enforce any particular programming paradigm such as
functional, logic, or object-oriented. As a result, it is very easy to
switch between any of the above modes during the same program
execution. Two well-designed object systems (incr Tcl and TheObjects)
exist for Tcl. The author is currently finding embedding a Prolog
interpreter into Tcl a simple task (much easier than the Pascal
pseudo-code). The second thing about Tcl is that all commands and
data (with the exception of associative arrays and C source code for
use in Tcl) are nothing but strings. As a result, programs and data
are highly interchangeable. Tcl contains 3
datatypes -- a word (a collection of ascii characters), a list (a
whitespace separated collection of words) and associative arrays.
Since lists are nothing but strings, they are mutable by both string
and ``list'' operations, where list operations are nothing but string
operations which regard whitespace as word separators.
Tcl has been ported to most unix-like systems (Sun, DEC, Silicon Graphics,
System 5, the free Intel unix-alikes, etc.), VMS, Amiga, MS-DOS, MACOS,
GS/OS, Vxworks, and a number of other operating systems.
Tcl is available at the following ftp sites:
\begin {itemize}
\item "/anonymous@sprite.berkeley.edu:/tcl"
\item "/anonymous@harbor.ecn.purdue.edu:/pub/tcl"
\end {itemize}
\section {Acknowledgements}
\begin {description}
\item [Per Abramsen] For his source code contributions.
\item [Tom Christiansen] For his Perl source code for this paper and also
his general comments.
\item [Lance Ellinghouse] For his Python source code and critique of this
paper.
\item [Bill Janssen] For his additions to this paper.
\item [Daniel Laliberte] For his excellent work with the Free Software
Foundation including co-authorship of the Emacs Lisp Reference Manual and
also his comments on this paper.
\item [Karl Lehenbauer] For co-authorship of Extended Tcl and for his
source code contributions to this paper.
\item [Michael Winikoff] for his critique.
\item [Larry Virden] For his tireless work on the Tcl FAQ (which was the
first time I had ever heard of Tcl) and his critque of this paper.
\end {description}
\subsection {Important Papers / People}
\begin {description}
\item [Catalog of Free Compilers and Interpreters] This document attempts
to catalog freely availiable compilers,
interpreters, libraries, and language tools. Available via anonymous ftp
from:
{\tt /anonymous@idiom.berkeley.ca.us:/pub/compilers-list/FreeCompilers*}
\item [Language List] Collected information on about 2100 computer
languages, past and present. Available from
{\tt /anonymous@primost.cs.wisc.edu:pub/comp.compilers/LanguageList*}
{\tt /anonymous@idiom.berkeley.ca.us: pub/compilers-list/LanguageList*}.
You can also access a hypertext version of the Language List via xmosaic
from the HTTP server: {\tt http://cui\_www.unige.ch}
\end {description}
\section {The Future}
\subsection {More Languages}
\subsection {More Examples and Tests}
\subsection {Multiple Computer Language Programming}
Expression of mathematics in Tcl is cumbersome yet X11 graphics is very
very easy. Perl has excellent string and manipulation tools and a ton of
sysadmin utilities written in it.
The bottom line is that all of these languages have powerful tools ready
to use. Each language also has its weak points. Instead of being stuck
in each language and slaving through its weakness (or lack of a certain
utility), one should be able to fire up an interpreter in any of these
other languages and let it perform on it strong points and return the
answer.
I expect this type of hybrid programming to become almost necessary with
excellent packages and large being written for each langauge.
For my M.S. Thesis, I developed a C library which allows for simulataneous
programming in C, Emacs Lisp, Smalltalk and Tcl.
\subsection {More Software}
A trans-language browser. If you see that a Perl script has been
written to traverse a directory tree and count the number of files
ending in .o whose age is more than 20 days but you are not a Perl
programmer, that Perl script should become and OBJECT to which you SEND
a message to get that work done.
\subsection {Is Interpreted Really Slower?}
I some cases compiled code is really compiled code performing certain
interpretive tasks. As a result, an interpreted language (which is really
just a C program performing syntax-directed tasks) may perform as
fast or faster than compiled code trying to perform interpreted tasks.
Although not currently detailed in this survey, an excellent example of a
language optimized for particular interpreted tasks is Prolog. Consider a
program typically done in an introductory programming class: maintain a
student gradebook and be able to collect information from the gradebook
based on certain criteria such as year in school and overall average.
Analysis of this program reveals three major tasks: {\it hashing} of
students by a unique key, {\it searching} the hashed space,
{\it collecting} related students based on specified criteria. To anyone
experienced in Prolog, there is no question that a Prolog program to
perform this task will be far shorter than the corresponding C program. In
addition, because there is only one method for handling each of the major
tasks of the program, the Prolog interpreter can make use of its optimized
methods for handling each of these tasks. \footnote{The only method of
hashing is by assertion of clauses. The only method of
searching the clauses in a Prolog program is by unification. The only
method of collection of numerous clauses is by recursive list generation.}
Therefore in cases where one is trying to model a changing, evolving,
non-deterministic situation, an interpreted language is best used.
\part {Power}
\chapter {Graphics}
\section{Emacs Lisp}
\section{Perl}
\section{Python}
\subsection {Significant Extensions}
Python has full support for both X11R4/Motif and through the use of the
STDWIN paradigm, the same source code
can do graphics in the following systems:
\begin{enumerate}
\item X-windows
\item Macintosh using either Think C 4.02 or MPW C 2.02
\item Atari ST
\item DOS
\item Silicon Graphics SGI workstations
\end{enumerate}
This approach allows flexibility but means that no one graphics system's
potential is maximized.
\section{Tcl}
\subsection {Significant Extensions}
\begin{description}
\item[TD\_CAD] A drawing program
\item[VOGLE] 3D rendering, fonts
\item[TSipp] Tcl interface to the SIPP 3-D rendering package.
\end{description}
\chapter {User Interface Building}
\section {Emacs Lisp}
Emacs 19 has popup menus and multiple windows.
The ability to synchronously and asynchronously control processes it to use Tcl's WAFE.
\section {Perl}
Again none interally, but the author of WAFE, the tcl/tk graphic
interpreter wrote all of his example programs in Perl (wafemail,
wafenews, wafeftp).
Certainly perl can issue external commands (inferior processes in lisp
parlance). There is also a version of guiperl I've seen Larry demo
for me, so there's at least proof-of-concept that you can link in
the X libs. Whether it will come out with perl5 I don't know.
\section {Python}
STDWIN also handles user interface development tasks.
\subsection {Significant Extensions}
\begin {description}
\item [EZD] Joel Bartlett's very nice WAFE-style system (very nice, check
it out!). *** More comments are needed here... ***
\end {description}
\section {Tcl}
Power is the word. Tcl has numerous user-contributed widgets including
photo widgets, bar graph widgets, editable text widgets, pixmap widgets and
much more.
\subsection {Significant Extensions}
\begin{description}
\item[XF] Menu-driven user interface builder
\item[TkSteal] Allows for a Tk program to have an Emacs widget or a
Ghostscript widget.
\item[Pixmap] A color pixmap editor written in Tcl/Tk
\item[PhotoWidget] A photo widget for Tk.
\item[WAFE] {\it W}idget {\it A}thena {\it F}ront {\it E}nd. Implemented in
Tcl, this package allows for the same generic graphic commands to be used
to develop user interfaces regardless of what language you are programming
in. All you need to do is interface to WAFE from your language.
\item[xy-graph] Includes a Hypertext widget. This means that regardless of
what stream of information comes at your Tcl program, you can create
windows and paths through the stream on the fly. A major example of the
hypertext widget is Joseph Wang's World Wide Web Hypertext browser.
\end{description}
\chapter {String Handling}
\section {Emacs Lisp}
Strong. Many good string handling functions for operation on buffers as
well as string. Search replace backward and forward with regexps. Many
good string handling functions are found in tree-dired.el in gmhist*.el.
As well as in ange-ftp.el.
\section {Perl}
Very strong.
String-handling is one of Perl's strongest features: they are quite
powerful and extensive. Strings can be as long as you want, and contain
binary data and nulls. This works:
\begin{verbatim}
$kernel = `cat /vmunix`;
\end{verbatim}
Perl has a wealth of string-accessing functions, including matching,
substitution, transliteration, splitting, and direct substring accessing.
Strings and numbers are interchangeable. The regexps are a superset of
other regexp syntaxes, with extensions. Parsing is very easy:
\begin{verbatim}
($name, $number, $host) = /(\w+)=(\d+)( from @(\w+))?/;
\end{verbatim}
Subexpressions can nest, and be arbitrarily deep: you don't have
to stop with \\9, but can keep going.
Perl's substitution operator works like sed's:
\begin{verbatim}
s/foo/bar;
\end{verbatim}
or
\begin{verbatim}
$a =~ s/foo/bar/g;
\end{verbatim}
but can do much more, like:
\begin{verbatim}
s/(\d+)/sprintf("0x%08x", $1)/ge;
\end{verbatim}
to find all the numbers in the pattern space and replace them
with the hex representation of the same. It has other powerful
features I don't have time or space to go into.
Perl also lets you treat strings as raw bitwise data, so
\begin{verbatim}
substr($a,0,3) &= "\177\177\177";
\end{verbatim}
would clear the high bits on the first 3 bytes of \$a. You
can also access strings bitwise, say, to check the $2456$th bit
of a string.
\section {Python}
It has a string module, regexp module, and regsub module. It has all the string
search and replace capabilities of Emacs.
\section {Tcl}
Everything in Tcl is a string. It is very easy to map certain
string-intensive applications to Tcl. For example, I wrote a program to
do parallel library database searches in Tcl in about two weeks. Ranking
the 4 languages in terms of how easy it would have been: Tcl, Python,
Emacs, and I cant say about Perl because I gave up on Perl quickly after
buying the book and seeing all those registers and the confusing
context-intensive syntax.
\chapter {Unix / Internet Programming}
\section {Emacs Lisp}
Has specialized modes for controlling Common Lisp and other lisps to
facilitate debugging, execution, and programming. Has shell modes with
command history. Has an excellent ftp program (ange-ftp). Can
asynchronously or synchronously call the shell and store the output in a
buffer or string. Can filter output from a process. However, the
filtering is somewhat hairy because you cannot be sure of the packet
size that the data will arrive in. In other words, it is easy to open a
pipe with Perl/Python/Tcl and just read lines at a time but you have to
write an accumulator function to do this in Emacs Lisp. However, the
interactor mode for GNU Smalltalk has an excellent accumulator function
that you could use in your own code.
Dan LaLiberte disagrees with the difficulty of accumulating input from a
process that Emacs has spawned. He says: ``An accumulator of whole lines
could be written in Emacs Lisp with not much problem. I'd be surprised if
no one has done so yet.'' However, until I see it, I stand by my above
statement.
\subsection {Significant Extensions}
\begin {description}
\item[VM] A mail reader that does everything that I need.
\item[Gnus] A Usenet reader that can save articles to mail folders for
later recall. I often save articles in Gnus and later read them using VM.
\item[Ange-FTP] An excellent ftp utility which allows transparent
file access/modification with the ease of a few keystrokes.
\item[Tree Dired] Allows you to scroll through directories and copy, edit,
remove, view files. And more
\end {description}
\section {Perl}
Perl has all the process control primitives available to you from C, plus
higher level constructs as well. It's easy to open a pipe to or from
another process. You can even open a pipe to an implicitly forked version
of yourself. Standard Perl library routines allow bidirectional pipes
and running things over a pty via a package that works much like Don
Libes's Expect, save that it uses Perl instead of tcl as an extension
language. Perl can also access all the socket and ipc functions on your
system without calling a program to do it.
\subsection {Significant Extensions}
??**??
\section {Python}
Python's process control is at least as strong as Perl's.
In addition, it supports threads (!), so that some of the operations
you have to do in another process, using Tcl or Perl, you can do
in another thread, in Python.
Python has a Posix and a generic OS module to handle this type of thing.
\subsection {Significant Extensions}
\begin {description}
\item[ftplib.py]
\item[nntplib.py]
\end {description}
\section {Tcl}
\subsection {Significant Extensions}
\begin {description}
\item[Expect] Due to an extension added to Tcl, process control in Tcl is a
snap. A Tcl package by Don Libes called Expect allows
the programmer to specify a set of expected regexps from the process and
what to do upon the receipt of the process output. Several of his papers
including "expect: Curing Those Uncontrollable Fits of Interaction"
available in postscript format for anonymous ftp from durer.cme.nist.giv
in pub/expect.
\item[Artcls] A graphic Usenet newsreader.
\item[TkWWW] A Tk world-wide web browser.
\end {description}
\chapter {Other}
\section {Emacs Lisp}
\begin{description}
\item[Folding Mode] Allows for hierarchical editing of structured text
files. I use it all the time. You can move through and edit any document
(program, LaTeX file, whatever) much faster using folding mode.
\item[EDB] full featured database
\item[AUC-TeX] Allows you to do anything you would want to do with
TeX/LaTeX from an Emacs buffer quickly and easily.
\item[Calc] The poor man's Mathematica. Includes rewrite rules and
functionality on the order of the HP-28.
\item[VIP] vi emulation for emacs
\item[Calendar/Diary] Calendar and appointment manager within Emacs
\item[Hyperbole] Extensible hypertext management system within Emacs.
\end{description}
\section {Perl}
Having been publicly available for six years now, Perl has a truly huge
body of code already written for it. I couldn't begin to document all of
them. More than any other language listed herein, it is the tool of
choice for Unix system administrators. Perl comes with a symbolic
debugger, a bunch of libraries, various tools, and and numerous example
programs, but that's just the start.
\section {Python}
\begin {description}
\item[CMIFed] An authoring environment for transportable, distributed
hypermedia presentations. It consists of at least 20,000 lines of
Python and 4,000 lines of C extensions. (A paper by Guido von Rossum and
others about it has appeared in the proceedings of the ACM Multimedia
'93 conference.)
\item[MCC] A teleconferencing tool written in Python. Still under
development.
\end {description}
\section {Tcl}
\begin {description}
\item[Objectify] Turns C++ classes into Tcl objects.
\end {description}
\chapter {Sample Programs}
\section {User Interface Design}
\subsection {Hello, world}
Write a program to run under X-Windows which opens a
window and prints {\tt "Hello, World"} in it. Those interested in
highly portable graphic/user interface software should note that the only
language capable of doing this program on a graphic windowing system beyond
X-Windows is Python.
%%%4.1. \subsection {Emacs Lisp}
\subsubsection {Emacs Lisp}
\begin{verbatim}
(defun hello-world () ; FSF Emacs 19 only.
``Open new frame with a friendly greeting.''
(switch-to-buffer-other-frame ``*hello world*'')
(insert ``Hello, World''))
\end{verbatim}
%%%4.2. \subsection {Perl}
\subsubsection {Perl}
\begin{verbatim}
I'd just talk to Wafe or Stdwin. Or call xterm. :-)
\end{verbatim}
\subsubsection {Tcl}
\begin{verbatim}
button .hello -text {Hello, World} -command {exit}
pack append . .hello {top}
\end{verbatim}
\section {String Handling}
\subsection {String Test}
Given a file with 4 occurrences of the string "Hello Bob" find the file,
replace the last 3 occurrences of "Hello Bob" with "Hi James" and save
the file. The double quotation marks are for delineation purposes only.
\subsubsection {Emacs Lisp}
\begin{verbatim}
(defun Bob-meet-James (file)
``Replace all `Hello Bob' with `Hi James' in FILE except the first.''
(save-excursion
(find-file file)
(goto-char (point-min)) ; We might already be editing it...
(search-forward ``Hello Bob'')
(while (search-forward ``Hello Bob'' nil t)
(replace-match ``Hi James''))
(save-buffer)))
\end{verbatim}
\subsubsection {Perl}
\begin{verbatim}
# the orig file will be in file.BAK -- if you don't want a backup,
# use just -i.
# remember that s//foo/ will match the last match
perl -i.BAK -p -e '/Hello Bob/ && $seen++ && s//Hi James/g'
or
perl thisprog < file.in > file.out
#!/usr/bin/perl
while (<>) {
if (/Hello Bob/ && $seen++) {
s//Hi James/g;
}
print;
}
\end{verbatim}
\subsubsection {Python}
\begin{verbatim}
#! /usr/local/bin/python
import strop
fp = open('testFile','r')
lines = fp.readlines() # read all lines in and seperate on \n's
fp.close()
fp = open('testFile','w')
for indx in range(0,len(lines)-4,4):
fp.write('\n'+lines[indx]+'::'+linex[indx+1]+'::'+lines[indx+2])
fp.close()
\end{verbatim}
OR
\begin{verbatim}
Hello, Bob (I think; I didn't actually try it):
#!/usr/bin/python
def sub_in_file(file):
import regsub
import string
seen = None
fp = open(file, 'r+')
lines = fp.readlines()
fp.seek(0, 0)
for line in lines:
if seen:
regsub.gsub('Hello Bob', 'Hi James', line)
else:
seen = (string.find (line, 'Hello Bob') >=
0)
fp.write(line)
import sys
sub_in_file(sys.argv[1])
\end{verbatim}
\subsubsection {Tcl}
\begin{verbatim}
set fdIn [open testFile r]
set contents [read $fdIn]
regexp -indices "Hello Bob" $contents matches
regsub -all "Hello Bob" \
[string range $contents [expr [lindex $matches 1]+1] end] \
"Hi James" result
close $fdIn
set fdOut [open testFile w]
puts $fdOut [string range $contents 0 [lindex $matches 1]]$result \
nonewline
close $fdOut
exit
\end{verbatim}
\subsection {String Test 2}
A lengthy file has been entered with records of the form:
\begin{verbatim}
<\n>NAME<\n>ADDRESS<\n>PHONE<\n>----------
\end{verbatim}
where \begin{verbatim}<\n>\end{verbatim} represents a line feed and the
\begin{verbatim}----------- \end{verbatim} is used to
separate records. Convert all entries in the file to a new format of
the form:
\begin{verbatim}<\n>NAME::ADDRESS::PHONE}
\end{verbatim}
\subsubsection {Emacs Lisp}
\begin{verbatim}
(defun newline-to-double-colon ()
``Convert current buffer from old style to new style address book
format.''
(goto-char (point-min))
(while (re-search-forward
``\n\\([^\n]*\\)\n\\([^\n]*\\)\n\\([^\n]*\\)\n----------'' nil t)
(replace-match ``\n\\1::\\2::\\3'')))
\end{verbatim}
\subsubsection {Perl}
\begin{verbatim}
#!/usr/bin/perl
$/ = "\n----------"; # set record separator
while (<>) { # read a record
s!$/$!!; # remove record terminator
s/^\n//; # trim first line feed
s/\n/::/g; # turn rest into double dolon
print "\n"; # new record starts with \n
print; # output current pattern space
}
# Did you know that the last record in the file will no longer
# have a terminating newline? Make sure the others get this right.
\end{verbatim}
\subsubsection {Tcl}
\begin{verbatim}
set fdIn [open testFile r]
set contents [read $fdIn]
regsub -all "^\n" $contents "" contents
regsub -all "\n" $contents "::" contents
regsub -all "::----------::" $contents "\n" contents
close $fdIn
set fdOut [open testFile w]
puts $fdOut $contents nonewline
close $fdOut
exit
\end{verbatim}
\subsection {Parsing a Prolog Structure for Logical Variables}
A Prolog structure consists of a {\it functor,} open parenthesis, a series of
comma-separated {\it terms,} which may be either constants or logical
variables and a close parenthesis. Here is an example of a structure with a
constant named {\tt baker} and two logical variables named {\tt CHARLIE}
and {\it FRANCE}.
\begin {verbatim}
able(baker,CHARLIE,FRANCE)
\end{verbatim}
Write a procedure that when given a list of structures (structures separated by
whitespace or tabs) will print out all of the logical variables in each
structure, also printing out each corresponding functor. For example, given
the above structure the output would be:
\begin {verbatim}
functor: able logical variables: CHARLIE FRANCE
\end{verbatim}
\subsubsection {Emacs Lisp}
\subsubsection {Perl}
\subsubsection {Python}
\subsubsection {Tcl}
\begin {verbatim}
proc datalog_logical_variables_in_clause {clause} {
foreach structure $clause {
set S [string trimright $structure ")"]
set F [lrange [split $S "("] 1 end]
set S [split $F ","]
puts "functor: [lindex $F 0] logical variables: $S"
}
}
\end{verbatim}
\subsection {Hofstadter's MIU Formal System}
Basically this is a test of string concatenation. We start with one initial
string and drop it in a bucket (any appropriate datatype from your language
is fine). Then we apply each applicable rule of the system to all strings
in the bucket and add the results of each application to the bucket. We
perform the rule application five times.
The only characters in a string are M, I, and U (just the letters not the
commas).
Here are the rules:
\begin {enumerate}
\item If a string S has I as its last letter, you can add on a U at the end
of S, creating a new string. Example: $ S == MII. S_{new} == MIIU. $
\item Suppose string S is of the form Mx. Then you may create a string of
the form Mxx from S. Example: $ S == MIU. S_{new} == MIUIU. $
\item If the substring III appears in S, then III may be replaced by U.
Multiple occurrences of III result in multiple new strings. Example: $
S == MIIII. S_{new1} == MIU. S_{new2} == MUI $
\item If the substring UU occurs inside S, then the first occurence may be
deleted. Example: $ S == MUU. S_{new} == M. $
\end {enumerate}
\subsection {Filtering a Printerleaf File}
I once had a dump of a file of Interleaf which looked like this:
\begin {verbatim}
\\377Parallelized\\266the\\266expectation
\\266maximization\\266algorithm.\\266This\\266algorithm\\266is\\266used
\end{verbatim}
I wanted to do the following:
\begin {itemize}
\item Simply output alphanumeric characters
\item Simply output linefeeds
\item Otherwise output a space
\end {itemize}
So I wrote the following C program:
\begin {verbatim}
#include <stdio.h>
main (int argc , char *argv[]) {
FILE
* fp ;
char
c ;
fp = fopen (argv[1],"r") ;
printf ("argv[1]: %s \n", argv[1]) ;
while ((c = getc (fp)) != EOF)
{
if (isalnum(c))
{
putchar (c) ;
}
else
{
if (c == 10)
{
putchar (c) ;
}
else
{
putchar (32) ;
}
}
}
}
\end{verbatim}
\section {Unix/Internet Programming}
\subsection {Count files in a Directory}
Write a program to count the number of files in the current directory.
\subsubsection {Emacs Lisp}
\begin{verbatim}
(defun current-directory-size ()
``Number of files in the current directory.''
(length (directory-files ``.''))
\end{verbatim}
\subsubsection {Perl}
\begin{verbatim}
#!/usr/bin/perl
$count = @files = <*>;
print "Directory file count: $count\n";
#!/usr/bin/perl
$count++ while <*>;
print "Directory file count: $count\n";
#!/usr/bin/perl
print "Directory file count:", `ls | wc -l`;
# those didn't have dot files. if you want dot files,
# use <* .*> instead.
#!/usr/bin/perl
opendir(DOT, '.');
$count = @files = readdir(DOT);
print "Directory file count: $count\n";
#!/usr/bin/perl
opendir(DOT, '.');
$count++ while readdir(DOT);
print "Directory file count: $count\n";
\end{verbatim}
\subsubsection {Python}
\begin {verbatim}
def current_directory_size():
import os
return len(os.listdir('.'))
\end{verbatim}
\subsubsection{Tcl}
\begin{verbatim}
set count [ls | wc -l]
\end{verbatim}
\subsection {Automated FTP file transfer}
Transfer the file {\tt tension.tex} from the internet host
{\tt lambda.barnes.edu} in your home directory to the internet host {\tt
calculus.au} to the directory {\tt pub/public} with the file
having the new name {\tt noneed.tex}.
\subsubsection {Emacs Lisp}
\begin {verbatim}
(copy-file
"/anonymous@lambda.barnes.edu:tension.tex"
"/anonymous@calculus.au:pub/public/noneed.tex")
\end{verbatim}
\subsubsection {Perl}
\subsubsection {Python}
\begin {verbatim}
path = 'lambda.barnes.edu:tesion.tex:tension.tex'
fetch (path)
\end{verbatim}
\subsection {Significant Extensions}
\begin {description}
\item[nntplib.py]
\item[ftplib.py]
\item[rsa/md5] encryption
\item[xdr.py] Sun's ONC XDR interface
\item[rpc.py] Sun's ONC, portmapper, TCP/IP interface (NFS, etc examples)
\item[mimetools] Tools used for MIME reading/writing of messages
\item[jpeg.py] JPEG/JFIF compression/decompression routines
\end {description}
\subsubsection {Tcl}
\section {Other}
\subsection {Count lines in a File}
Open up a file named {\tt bozak.foo} and print the number of lines in it to
stdout.
\chapter {Programmer Support}
\section {Learning Curve for Language}
\subsection{Emacs Lisp}
The best. Has a debugger. Since you are in Emacs, you can immediately
test whatever you are writing. Documentation on every function and
variable in memory is available in 2 keypresses. The tags system allows
you to jump to functions and global variable declarations without
knowing which file they are in. The Usenet group {\tt gnu.emacs.help} exists.
The GNU Emacs Lisp manual exists.
\subsection{Perl}
I would say strong. To use Perl, you only need to know a little bit to
start to use it. The interactive debugger allows you to type any kind of
Perl code you want and get an immediate answer, as well as providing
standard sym debugger capabilities such as breakpoints, single-stepping,
and stack tracebacks. Other tools available but not included with the
Perl src kit include profilers, tags generators, cross referencers, and
tools to assemble large Perl programs using makefiles and a lintlike
checker. Other tools provide perl-mode for vi as well as tightly coupling
the debugger with a slave vi session that autopositions by file and line.
The newsgroup {\tt comp.lang.perl} exists. The Perl book by Larry Wall is
out.
\subsection{Python}
Good. The language is VERY regular and very powerful. You have seperate
name spaces that allow reuse and an OO design of your applications/scripts.
There are HUNDREDS of support modules you can import. There is a mailing
list that you may join by mailing {\tt guido@cwi.nl}. Several manuals for
using Python exist.
Note that there is a GNU Emacs mode for Python, as well as a
special subprocess mode for it. There are a couple of debuggers
shipped with the Python library, one windowing and one
command-line-like.
\subsection{Tcl}
The language is very consistent --- every line is
started with a command which is the name of a Tcl or C function. The
rest of the line is arguments to the Tcl or C function. The newsgroup {\tt
comp.lang.tcl} exists. The Tcl books is due out soon. A version is
currently available via anonymous ftp from
{\tt /anonymous@harbor.ecn.purdue.edu:pub/tcl/sprite-mirror}.
\section {Test Suite}
\subsection{Emacs Lisp}
Well, if you compile Emacs then all core source code that Emacs needs will
run. However one of its several hundred functions and commands that Emacs
itself does not depend on might fail when a user tries to use it and no
test suite exists for these non-core commands.
\subsection{Perl}
Exhaustive test suite.
\subsection{Python}
Exhaustive test suite
\subsection{Tcl}
Exhaustive test suite
\chapter{Extensibility}
Extensibility is the ability to add a new keyword or data type to the
language in BOTH the language and C language.
\section {Emacs Lisp}
Extending Emacs with new Lisp code is very easy. Writing additional C code
to be added to Emacs is tedious for several reasons:
\begin {enumerate}
\item The GNU Emacs Manual does not attempt to give comprehensive
information on how to extend Emacs in C.
\item You must guess at the correct size of a variable called
{\tt PURESIZE} in order to be sure that Emacs allocates enough memory for
itself when it dumps itself with the additional source code.
\item The {\tt GCPRO} macros are only able to protect a maximum of 4
variables.
\end {enumerate}
\section {Perl}
I am not a Perl programmer and really have no right to say anything here,
but having bought the Perl book, I noticed that the language is very
context-sensitive and has a grammar covering several pages. In contrast,
the relation of syntax to semantics for these other languages is simple and
learnable in about 5 minutes.
You can extend Perl through linking with C routines. The example
with the perl kit explains how to do this for the curses library,
but can be done for many other applications as well. This is adding
new function calls.
What you would probably do is define a package and use acccessor
functions. I did this to allow perl user's to get at C struct and union
types to interract with C programs. A package is semi-reminiscent of a
C++ class, perhaps best described as a protected namespace with private
and public data declarations and initialization code, as well as both
private and public functions. I wonder how the other languages stack up
on this kind of thing.
\section {Python}
It is very easy to add new types (Lance Ellinghouse has added about 20 new
types of objects to Python both at the C code level as well as in Python
code.
Note that unlike Perl, new Python
modules written in C can be dynamically loaded into a running
interpreter. You don't need to relink the image. Adding a new
datatype is very easy. Modifying the syntax (``adding a new keyword'')
doesn't seem very easy. There could be a macro package...
\section {Tcl}
Its possible and well-documented and has been down well by many
people in C.
\chapter {Other}
\section {Useful Extras}
\subsection {Compilation Mechanisms}
\subsection {Threads}
\end {document}