From: burley@geech.gnu.ai.mit.edu (Craig Burley)
Subject: Re: Why is compiled basic slower than C? (Basic is the future)
Reply-To: burley@geech.gnu.ai.mit.edu (Craig Burley)
Organization: Free Software Foundation 545 Tech Square Cambridge, MA 02139
Date: Fri, 14 Aug 1992 19:14:18 GMT
Keywords: Basic, performance

scott@bbx.basis.com (Scott Amspoker) writes:

   I just don't think interpreted languages compile well.  If they do then
   they really aren't exploiting the special strengths of interpretation.
   You end up with the worst of both worlds.

I think interpreted languages _could_ compile well if _lots_ of effort
were expended.  However, that kind of effort probably isn't worth it --
the performance gains compared to the effort, that is -- when contrasted
to the effort expended in buying new, faster processors, making the
interpreters run faster (often quite easy), translating programs to
maintenable code in a language designed for compilation, and so on.

I remember a discussion with rms (GNU EMACS author) regarding TECO, the
language in which he first wrote EMACS.  TECO was (and still is,
primarily) an interpreted language (well, it's an editor, kind of like the
MS-DOS DEBUG program is a partition editor :-).  He told me about how
someone we both knew had developed (or help develop) a compiler for TECO
and was prepared to demonstrate its superiority in benchmarks.  But
submitting one simple case (something like deleting every other line in
the file) proved the opposite.  (Of course, TECO is probably like APL in
that the time it takes to read in source code and figure out what it means
is minimal, as compared to C, FORTRAN, and COBOL.  So the penalty for
being an interpreter could be seen as significantly lower for terse
languages like TECO and APL, higher for verbose languages like BASIC,
FORTRAN, and COBOL.)

As already mentioned, the way a language is _expected_ by a program to be
implemented has a noticable effect on how code is written for that
language.  So do language features, of course.

C has facilities for easily denoting static and automatic storage, but not
for heap storage or automatically readjustable storage.  C can't even have
functions that return strings without requiring the programmer to impose
one method or another for managing the strings (contrasted to PL/I, which
has the facility and leaves imposition of the technique to the compiler
designers).  Thus, C programmers are acutely aware of what techniques are
likely to be expensive -- if it's easy to do in the raw C language, it's
likely to be fast, otherwise....  Add to that the awareness that C is a
compiled language, and C programmers realize that it's often better to
have lots of _written_ code that expresses a complicated implementation in
an optimal manner using fundamental features of the language.

BASIC has facilities for easily denoting readjustable storage such as
strings, arrays, and so on, and it tends to be implemented as an
interpreter.  (The Dartmouth implementation has never been an interpreter,
I understand, nor was the implementation whose internals I hacked as a
teenager -- but the latter offered an interpretive environment yet no
compiled environment, e.g. you couldn't really get the output of the
compiler, just execute it by typing RUN.)  Thus, programmers naturally
tend to use the more concise notations for higher-level constructs offered
by BASIC rather than try and reengineer them using what they think will be
faster (but more verbose) low-level operations, especially given that an
interpreter tends to "dislike" verbosity.  (On the other hand, I often
wrote utility programs in BASIC and consciously chose to use integer
variables to manipulate characters in critical areas of the code since I
knew that the string operations were much slower.  But then I knew my
particular processor compiled, rather than interpreted, my programs --
once per RUN command.)

Of course, what we are discussing generally applies to one or two "slices"
of the compiled vs. interpreted issue.  One such slice is whether there is
a separate compilation phase.  Another is the way in which the user
interacts with the processor when developing code.  There is another major
issue regarding interpretation which puts both BASIC and C in the
"compiled" camp: whether the running program has a means to modify itself
at run time.  LISP, for example, belongs in the "interpreted" camp.
Looked at in this light, it would seem that a good BASIC compiler would be
easier to build than a good LISP compiler, since the latter has to worry
about the running program, in effect, changing itself.  Yet, from what
little I know of LISP, there apparently are a number of quite good LISP
compilers out there.  This suggests that perhaps the effort needed to make
a really good BASIC compiler isn't quite so high.  Some of the techniques
I've learned about in doing a good job of compiling FORTRAN programs
(especially dusty decks that use no formal loop control but GOTO instead),
plus others I've dreamt up that aren't needed (generally) in compilers for
languages like C, wouldn't be hard to implement in this day and age and
would probably make lots of BASIC programs run quite fast.

Hmm, anyone want to fund me to develop GNU BASIC now that I'm winding up
doing GNU FORTRAN?  I might as well reach even earlier into my childhood!
(Heck, I'm even open to doing GNU AID [by JOSS] or a GNU simulator for the
PDP-8. :-)
--
James Craig Burley, Software Craftsperson    burley@gnu.ai.mit.edu
-- 
Send compilers articles to compilers@iecc.cambridge.ma.us or
{ima | spdcc | world}!iecc!compilers.  Meta-mail to compilers-request.
Newsgroups: comp.compilers,comp.lang.basic