\c tcl.tex			-*-LaTeX-*-
\c Geoffrey Furnish
\c 11 October 1994
\c
\c Document the PLplot Tcl API, and related programming issues.
\c
\c $Id: tcl.tex,v 1.2 1995/07/26 21:31:55 furnish Exp $
\c %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\node Tcl Interface, Extended WISH, C++ Interface, Top
\chapter{Using PLplot from Tcl}
\cindex{script language access}

PLplot has historically had C and Fortran language bindings.  PLplot
version 5.0 introduces a plethora of new programming options including
C++ (described earlier) and several script language bindings.  The Tcl
interface to PLplot (which the PLplot maintainers regard as the
``primary'' script language binding) is described in this chapter,
with further discussion of Tcl related issues following in additional
chapters.  But Tcl is certainly not the only script language option.
Bindings to Perl, Python, and Scheme (which is actually another
compiled language, but still has some of the flavor of a VHLL) are in
various stages of completion, and are described in seperate chapters.
Use the one that suits you best--or try them all!

\begin{menu}
* Tcl Motivation::	Why we want to use PLplot from Tcl.
* Tcl Basic Usage::	Overview/general statement of how to use the Tcl API.
* Tcl Matrix::		All about the Tcl Matrix extension.
* Tcl 2-d API::		Contouring and Shading from Tcl.
* Tcl Performance::	Understanding performance implications.
\end{menu}

\node Tcl Motivation, Tcl Basic Usage, Tcl Interface, Tcl Interface
\section{Motivation for the Tcl Interface to PLplot}
\cindex{script level programming}

The recent emergence of several high quality VHLL script languages
such as Tcl, Perl, Python and arguably even some Lisp variants, is
having a profound effect upon the art of computer programming.  Tasks
which have traditionally been handled by C or Fortran, are beginning
to be seen in a new light.  With relatively fast processors now widely
available, many programming jobs are no longer bound by execution
time, but by ``human time''.  Rapidity of initial development and
continued maintenance, for a surprisingly wide class of applications,
is far more important than execution time.  Result: in a very short
period of time, say from 1993 to 1995, script languages have exploded
onto the scene, becoming essential tools for any serious programmer.

Moreover, the entire concept of ``speed of execution'' needs revising
in the face of the gains made in computer hardware in recent years.
Saying that script language processing is slower than compiled
language processing may be undeniable and simultaneously irrelevant.
If the script language processing is fast enough, then it is fast
enough.  Increasingly, computational researchers are finding that
script based tools are indeed fast enough.  And if their run time is
fast enough, and their development and maintenance time is much much
better, then why indeed should they not be used?

Even in a field with several high visibility players, Tcl has
distinguished itself as a leading contendor.  There are many reasons
for this, but perhaps the most important, at least as it relates to
the PLplot user community, is that Tcl was designed to be extensible
and embeddable.  The whole purpose of Tcl, as it name (Tool Command
Language) indicates, is to be a command language for other tools.  In
other words, the fact that Tcl is capable of being a standalone shell
is interesting, even useful, but nonetheless incidental.  The real
attraction of Tcl is that it can be the shell language for \emph{your}
code.  Tcl can easily be embedded into your code, endowing it
immediately with a full featured, consistent and well documented
script programming language, providing all the core features you need
in a programming language: variables, procedures, control structures,
error trapping and recovery, tracing, etc.  But that is only the
beginning!  After that, you can easily extend Tcl by adding commands
to the core language, which invoke the capabilities of your tool.  It
is in this sense that Tcl is a tool command language.  It is a command
language which you can augment to provide access to the facilities of
your tool.

But Tcl is more than just an embeddable, extensible script language
for personal use.  Tcl is an industry, an internet phenomenon.  There
are currently at least two high quality books, with more on the way.
There is an industry of service providers and educators.  Furthermore,
literally hundreds of Tcl extensions exist, and are readily available
over the net.  Perhaps the most notable extension, Tk, provides a
fantastic interface to X Windows widget programming, permitting the
construction of Motif like user interfaces, with none of the hassles
of actually using Motif.  Some of these extensions endow Tcl with
object oriented facilities philosophically similar to C++ or other
object oriented languages.  Other extensions provide script level
access to system services.  Others provide a script interface to
sockets, RPC, and other network programming protocols.  The list goes
on and on.  Dive into the Tcl archive, and see what it has for you!

So, the answer to the question ``Why do we want a Tcl interface to
PLplot?'' is very simple.  ``Because we we are using Tcl anyway, as
the command language for our project, and would like to be able to do
plotting in the command language just as we do so many other things.''

But there is more than just the aesthetics of integration to consider.
There are also significant paragmatic considerations.  If you generate
your PLplot output via function calls from a compiled language, then
in order to add new diagnostics to your code, or to refine or
embellish existing ones, you have to edit the source, recompile,
relink, and rerun the code.  If many iterations are required to get
the plot right, significant time can be wasted.  This can be
especially true in the case of C++ code making heavy use of templates,
for which many C++ compilers will have program link times measured in
minutes rather than seconds, even for trivial program changes.

In contrast, if the diagnostic plot is generated from Tcl, the
development cycle looks more like: start the shell (command line or
windowing), source a Tcl script, issue the command to generate the
plot, notice a bug, edit the Tcl script, resource the script, and
regenerate the plot.   Notice that compiling, linking, and restarting
the program, have all been dropped from the development cycle.  The
time savings from such a development cycle can be amazing!


\node Tcl Basic Usage, Tcl Matrix, Tcl Motivation, Tcl Interface
\section{Overview of the Tcl Language Binding}

Each of the PLplot calls available to the C or Fortran programmer are
also available from Tcl, with the same name and generally the same
arguments.  Thus for instance, whereas in C you can write:
\c Insert a few more calls to make this a more realistic example.
\begin{example}
plenv( 0., 1., 0., 1., 0, 0 );
pllab( "(x)", "(y)", "The title of the graph" );
\end{example}
you can now write in Tcl:
\begin{example}
plenv 0 1 0 1 0 0
pllab "(x)" "(y)" "The title of the graph"
\end{example}
All the normal Tcl rules apply, there is nothing special about the
PLplot extension commands.  So, you could write the above as:
\begin{example}
set xmin 0; set xmax 1; set ymin 0; set ymax 1
set just 0; set axis 0
set xlab (x)
set ylab (y)
set title "The title of the graph"
plenv $xmin $xmax $ymin $ymax $just $axis
pllab $xlab $ylab $title
\end{example}
for example.  Not that there is any reason to be loquacious for its
own sake, of course.  The point is that you might have things like the
plot bounds or axis labels stored in Tcl variables for some other
reason (tied to a Tk entry widget maybe, or provided as the result of
one of your application specific Tcl extension commands, etc), and
just want to use standard Tcl substitution to make the PLplot calls.

Go ahead and try it!  Enter \code{pltcl} to start up the PLplot
extended Tcl shell, and type (or paste) in the commands.  Or put them
in a file and source it.  By this point it should be clear how
incredibly easy it is to use the PLplot Tcl language binding.

In order to accomodate the ubiquitous requirement for matrix oriented
data in scientific applications, and in the PLplot API in particular,
PLPlot 5.0 includes a Tcl extension for manipulating matricies in Tcl.
This Tcl Matrix Extension provides a straightforward and direct means
of representing one and two dimensional matricies in Tcl.  The Tcl
Matrix Extension is described in detail in the next section, but we
mention its existence now just so that we can show how the PLplot Tcl
API works.  Many of the PLplot Tcl API functions accept Tcl matricies
as arguments.  For insance, in C you might write:
\begin{example}
float x[100], y[100];

/* code to initialize x and y */

plline( 100, x, y );
\end{example}
In Tcl you can write:
\begin{example}
matrix x f 100
matrix y f 100

# code to initialize x and y

plline 100 x y
\end{example}

Some of the PLplot C function calls use pointer arguments to allow
retrieval of PLplot settings.  These are implemented in Tcl by
changing the value of the variable whose name you provide.  For
example:
\begin{example}
pltcl> plgxax
wrong # args: should be "plgxax digmax digits  "
pltcl> set digmax 0
0
pltcl> set digits 0
0
pltcl> plgxax digmax digits
pltcl> puts "digmax=$digmax digits=$digits"
digmax=4 digits=0
\end{example}
This example shows that each PLplot Tcl command is designed to issue
an error if you invoke it incorrectly, which in this case was used to
remind us of the correct arguments.  We then create two Tcl variables
to hold the results.  Then we invoke the PLplot \code{plgxax} function
to obtain the label formatting information for the x axis.  And
finally we print the results.

People familiar with Tcl culture may wonder why the \code{plg*} series
functions don't just pack their results into the standard Tcl result
string.  The reason is that the user would then have to extract the
desired field with either \code{lindex} or \code{regexp}, which seems
messy.  So instead, we designed the PLplot Tcl API to look and feel as
much like the C API as could reasonably be managed.

In general then, you can assume that each C function is provided in
Tcl with the same name and same arguments (and one or two dimensional
arrays in C are replaced by Tcl matricies).  There are only a few
exceptions to this rule, generally resulting from the complexity of
the argument types which are passed to some functions in the C API.
Those exceptional functions are described below, all others work in
the obvious way (analogous to the examples above).  

See the Tcl example programs for extensive demonstrations of the usage
of the PLplot Tcl API.  To run the Tcl demos:
\begin{example}
% pltcl
pltcl> source tcldemos.tcl
pltcl> 1
pltcl> 2
\end{example}
Alternatively, you can run \code{plserver} and source \file{tkdemos.tcl}.

In any event, the Tcl demos provide very good coverage of the Tcl API,
and consequently serve as excellent examples of usage.  For the most
part they draw the same plots as their C counterpart.  Moreover, many
of theem were constructed by litterally inserting the C code into the
Tcl source file, and performing fairly mechanical transformations on
the source.  This should provide encouragement to anyone used to using
PLplot through one of the compiled interfaces, that they can easily
and rapidly become productive with PLplot in Tcl.

\input{tclmatrix}

\node Tcl 2-d API, Tcl Performance, Tcl Matrix, Tcl Interface
\section{Contouring and Shading from Tcl}

Contouring and shading has traditionally been one of the
messier things to do in PLplot.  The C API has many parameters, with
complex setup and teardown properties.  Of special concern is that
some of the parameters do not have a natural representation in script
languages like Tcl.  In this section we describe how the Tcl
interface to these facilities is provided, and how to use it.

\begin{menu}
* Tcl Contouring::	Drawing contour plots from Tcl.
* Tcl Shading::		Drawing shaded plots from Tcl.
\end{menu}

\node Tcl Contouring, Tcl Shading, Tcl 2-d API, Tcl 2-d API
\subsection{Drawing a Coutour Plot from Tcl}

By way of reference, the primary C function call for contouring is:
\begin{example}
void plcont( PLFLT **f, PLINT nx, PLINT ny, PLINT kx, PLINT lx,
             PLINT ky, PLINT ly, PLFLT *clevel, PLINT nlevel,
             void (*pltr) (PLFLT, PLFLT, PLFLT *, PLFLT *, PLPointer),
             PLPointer pltr_data);
\end{example}

This is a fairly complex argument list, and so for this function (and
for plshade, described below) we dispense with trying to exactly
mirror the C API, and just concentrate on capturing the functionality
within a Tcl context.  To begin with, the data is provided through a
2-d Tcl matrix.  The Tcl matrix carries along its size information
with it, so \code{nx} and \code{ny} are no longer needed.  The
\code{kx}, \code{lx}, \code{ky} and \code{ly} variables are
potentially still  useful for plotting a subdomain of the full data
set, so they may be specified in the natural way, but we make this
optional since they are frequently not used to convey anything more
than what could be inferred from \code{nx} and \code{ny}.  However, to
simplify processing, they must be supplied or omitted as a set (all of
them, or none of them).  \code{clevel} is supplied as a 1-d Tcl
matrix, and so \code{nlevel} can be omitted.  

Finally, we have no way to support function pointers from Tcl, so
instead we provide token based support for accessing the three
coordinate transformation routines which are provided by PLplot, and
which many PLplot users use.  There are thus three courses of action:
\begin{itemize}
\item Provide no pltr specification.  In this case, \code{pltr0} is
used by default.

\item Specify \code{pltr1 x y} where x and y are 1-d Tcl matricies.
In this case \ocde{pltr1} will be used, and the 1-d arrays which it
needs will be supplied from the Tcl matricies \code{x} and \code{y}.

\item Specify \code{pltr2 x y} where x and y are 2-d Tcl matricies.
In this case \ocde{pltr2} will be used, and the 2-d arrays which it
needs will be supplied from the Tcl matricies \code{x} and \code{y}.
\end{itemize}

Now, there can be no question that this is both more concise and less
powerful than what you could get in C.  The loss of the ability to
provide a user specified transformation function is regrettable.  If
you really do need that functionality, you will have to implement your
own Tcl extension command to do pretty much the same thing as the
provided Tcl extension command \code{plcont} (which is in
\file{tclAPI.c} in function \code{plcontCmd()}), except specify the C
transformation function of your choice.

However, that having been said, we recognize that one common use for
this capability is to provide a special version of \code{pltr2} which
knows how to implement a periodic boundary condition, so that polar
plots, for example, can be implemented cleanly.  That is, if you want
to draw contours of a polar data set defined on a 64 x 64 grid,
ensuring that contour lines would actually go all the way around the
origin rather than breaking off like a silly pacman figure, then you
had basically two choices in C.  You could copy the data to a 65 x 64
grid, and replicate one row of data into the spare slot, and then plot
the larger data set (taking care to replicate the coordinate arrays
you passed to pltr2 in the same way), \emph{or} you could make a
special version of \code{pltr2} which would understand that one of the
coordinates was wrapped, and perform transformations accordingly
without actually making you replicate the data.

Since the former option is ugly in general, and hard to do in Tcl in
particular, and since the second option is even more difficult to do
in Tcl (requiring you do make a special Tcl extension command as
described above), we provide special, explicit support for this common
activity.  This is provided through the use of a new, optional
paramater \code{wrap} which may be specified as the last parameter to
the Tcl command, only if you are using \code{pltr2}.  Supplying
\code{1} will wrap in the first coordinate, \code{2} will wrap in the
second coordinate.

The resultant Tcl command is:
\begin{example}
plcont f [kx lx ky ly] clev [pltr x y] [wrap]
\end{example}
Note that the brackets here are used to signify optional arguments,
\emph{NOT} to represent Tcl command substitution!

The Tcl demo \file{x09.tcl} provides examples of all the capabilities
of this interface to contouring from Tcl.  Note in particular,
\code{x09_polar} which does a polar contour without doing anything
complicated in the way of setup, and without getting a pacman as the
output. 

\node Tcl Shading, , Contouring, Tcl 2-d API
\subsection{Drawing a Shaded Plot from Tcl}

The Tcl interface to shading works very much like the one for
contouring.  The command is:
\begin{example}
plshade z xmin xmax ymin ymax \
    sh_min sh_max sh_cmap sh_color sh_width \
    min_col min_wid max_col max_wid \
    rect [pltr x y] [wrap]
\end{example}
where \code{nx} and \code{ny} were dropped since they are inferred
from the Tcl matrix \code{z}, \code{defined} was dropped since it
isn't supported anyway, and \code{plfill} was dropped since it was the
only valid choice anyway.  The \code{pltr} spec and \code{wrap} work
exactly as described for the Tcl \code{plcont} described above.

The Tcl demo \file{x16.tcl} contains extensive demonstrations of use,
including a shaded polar plot which connects in the desirable way
without requiring special data preparation, again just like for
\code{plcont} described previously.

\node Tcl Performance, , Tcl 2-d API, Tcl Interface
\section{Understanding the Performance Characteristics of Tcl}

Newcomers to Tcl, and detractors (read, ``proponents of other
paradigms'') often do not have a clear (newcomers) or truthfull
(detractors) perspective on Tcl performance.  In this section we try
to convey a little orientation which may be helpful in working with
the PLplot Tcl interface.

``Tcl is slow!''  ``Yeah, so what?''

Debates of this form frequently completely miss the point.  Yes, Tcl
is definitely slow.  It is fundamentally a string processing language,
is interpretted, and must perform substitutions and so forth on a
continual basis.  All of that takes time.  Think milliseconds instead
of microseconds for comparing Tcl code to equivalent C code.  On the
other hand, this does not have to be problematic, even for time
critical (interactive) applications, if the division of labor is done
correctly.  Even in an interactive program, you can use Tcl fairly
extensively for high level control type operations, as long as you do
the real work in a compiled Tcl command procedure.  If the high level
control code is slow, so what?  So it takes 100 milliseconds over the
life the process, as compared to the 100 microseconds it could have
taken if it were in C.  Big deal.  On an absolute timescale, measured
in units meaninful to humans, it's just not a lot of time.

The problem comes when you try to do too mcuh in Tcl.  For instance,
an interactive process should not be trying to evaluate a
mathetmatical expression inside a doubly nested loop structure, if
perfromance is going to be a concern.

Case in point:  Compare x16.tcl to x16c.c.  The code looks very
similar, and the output looks very similar.  What is not so similar is
the execution time.  The Tcl code, which sets up the data entirely in
Tcl, takes a while to do so.  On the other hand, the actual plotting
of the data proceeds at a rate which is effectively indistinguishable
from that of the compiled example.  On human timescales, the
difference is not meaningful.  Conclusion:  If the computation of the
data arrays could be moved to compiled code, the two programs would
have performance close enough to identical that it really wouldn't be
an issue.  We left the Tcl demos coded in Tcl for two reasons.  First
because they provide some examples and tests of the use of the Tcl
Matrix extension, and secondly because they allow the Tcl demos to be
coded entirely in Tcl, without requiring special customized extended
shells for each one of them.  They are not, however, a good example of
you should do things in practice.

Now look at \file{tk04} and \file{xtk04.c}, you will see
that if the data is computed in compiled code, and shuffled into the
Tcl matrix and then plotted from Tcl, the performance is fine.  Almost
all the time is spent in plshade, in compiled code.  The time taken to
do the small amount of Tcl processing involved with plotting is
dwarfed by the time spent doing the actual drawing in C.  So using Tcl
cost almost nothing in this case.

So, the point is, do your heavy numerics in a compiled language, and
feel free to use Tcl for the plotting, if you want to.  You can of
course mix it up so that some plotting is done from Tcl and some from
a compiled language.  