Newsgroups: alt.lang.design,comp.lang.c++,comp.lang.lisp
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!howland.reston.ans.net!pipex!dircon!rheged!simon
From: simon@rheged.dircon.co.uk (Simon Brooke)
Subject: Re: Interpreters (Re: Comparing productivity: LisP against C++ (was  Re: Reference Counting))
Message-ID: <D409vC.7r3@rheged.dircon.co.uk>
Organization: none. Disorganization: total.
References: <3gftki$26f@karlo.informatik.uni-kiel.de> <D36LA9.y4@cogsci.ed.ac.uk> <D3J8FB.11v@rheged.dircon.co.uk> <D3n2wK.4r7@cogsci.ed.ac.uk>
Date: Tue, 14 Feb 1995 19:52:21 GMT
Lines: 141
Xref: glinda.oz.cs.cmu.edu comp.lang.c++:113027 comp.lang.lisp:16821

In article <D3n2wK.4r7@cogsci.ed.ac.uk>,
Jeff Dalton <jeff@aiai.ed.ac.uk> wrote:
>In article <D3J8FB.11v@rheged.dircon.co.uk> simon@rheged.dircon.co.uk
>(Simon Brooke) writes:

>>Common LISP, as a standard language, does have and does have to have
>>an interpreter. 
>
>No, that's just not true.
>
>>How individual implementations implement that
>>interpreter is up to the authors; if they choose to implement the
>>interpreter by making a call to the compiler and then executing the
>>result, that's up to them, but it doesn't make the process any the
>>less one of interpreting language.
>
>Compilers interpret langauge.  Very true.  And that makes them
>interpreters in a sense (all things that interpret are interpreters).
>But the word "interpreter" has a technical meaning as well in which
>the word refers to a way of implementing a programming language.
>Compilers are not interpreters in that sense and Common Lisp
>implementations do not have to have interpreters in that sense.
>
>In short, your argument commits the fallacy of equivocation
>(on the word "interpreter").

OK, Jeff, I'll take up this fight, although I know you'll beat me on
both rhetorical or technical skill. LisP newbies please ignore my
arguments, they're pretty much bound to be wrong.

Your claim is that there is something in computer science called an
'interpreter', special technical meaning for a particular sort of
tool, and that a LisP which implements EVAL by precompiling does not
have one, but a LisP that implements EVAL by applying the s-expression
which is the value of the function cell of the car of the s-expression
just read does have one.

And my answer to you is 'no, that's just not true', to quote a learned
sage. Let us divide non-LisP like languages into two broad categories
for the time being.

There are languages such as (classic implementations of) Pascal, in
which the source text is scanned and compiled from a file on disk,
never being loaded in it's entirety into main memory. It is compiled
into the machine code of some processor, possibly virtual (as in P
Code), and the compiled code is later run. It is clear what is meant
by compiled in this case, and the language is clearly compiled.

There are languages such as (primitive implementations of) BASIC, in
which the source text is loaded into a continuous vector of memory
(more or less tokenised), and then a process scans the vector of text
interpreting each command as it is encountered. It is clear what is
meant by interpreted in this case, and the language is clearly
interpreted.

I have, in my collection, largely as a curiosity, a C language library
package called C Lisp, written by a chap called Frederick Drasch. This
works exactly like a primitive BASIC interpreter. It loads LisP source
text into a continuous vector of memory, and scans along it
interpreting it token by token as it goes. The weird thing is, it
works!

It is, however, a total aberration, -- It's LisP, Jeff, but not as we
know it <cue stirring music>. Almost any other LisP compiles source
code into an internal form as it is read -- i.e. into s-expressions,
linked lists of pointers, with symbols cached in hash arrays or other
curiosities. The source text of the LisP program does not exist
anywhere in memory. For example, although probably the two most common
characters in any LisP program are LPAR and RPAR respectively, a
memory dump of a running LisP program is unlikely to reveal more than
one instance of either.

In an 'interpreted' LisP, the s-expressions are then explored by a
depth first tree walking algorithm. That's nothing like what an
'interpreter', in the sense of a BASIC interpreter, does. It's very
much like what a P Code virtual processor does; except that the
instruction set of the Lisp virtual processor is user-extensible.

So, talking outside the LisP community, interpreted LisP looks very
much like compiled P Code. Now suppose we compile the LisP, and
suppose we compile it using abstract machine technology. You may argue
that this is just like P Code, but in fact it's not, because where P
Code would include an absolute jump instruction, the LisP abstract
machine will compile to an indirected jump via the value of a symbol.

Say again: the abstract machine interpreter will scan linearly along
the vector of abstract machine instructions (like tokenised BASIC)
until it comes to a jump indirected via a symbol. This is very like a
command in a BASIC program to CHAIN another program, and the
'compiled' LisP now looks much more like interpreted BASIC than it
does like compiled PASCAL (although of course the P Code virtual
processor and the BASIC interpreter look very much like one another).

My conclusion, then: there is no clear understanding in computer
science of what the difference between a compiler and an interpreter
is, or if there is, it does not fit a LisP interpreter. A LisP
interpreter is more different from a BASIC interpreter than it is from
a LisP compiler. To argue that something which interprets
s-expressions is not an interpreter because it does not work in the
way that things called by computer science 'interpreters' work is
simply to say that all LisPs (with the exception of the good Mr
Drasch's C Lisp) are compiled. Do you want to say that? Or shall we
invent a new word?

(discussion deleted)

>>...although it's fairly easy to write interpreters for
>>simple languages in AlgoL family languages, it isn't easy, for example
>>to write in C an interpreter for C source code.
>
>That's true.  But the reasons it's easier for Lisp don't have all
>that much to do with the sorts of eval-is-bad-for-your-compiled-code
>arguments we've seen here.  Some of the most important reasons why
>it's easier to write an interpreter for Lisp-family languages are 
>
>  * Read provides the lexical-analyzer/scanner and a bit more.
>  * The rest of the parsing task (e.g. to extract the variable
>    names in a "let") is usually pretty trivial (though some
>    things, such as handler-case and defstruct are harder).

Errhrrm. What I think you're saying is something I've long believed:
it's easy to interpret LisP because LisP has almost no syntax in any
conventional sense. That's why I deprecate this horrid modern Common
LISP stuff with keywords in lambda lists. Yech! Nasty!

:-} :-} :-} :-} :-} :-}:-} :-} :-} {-: {-: {-: {-: {-; {-; {-: {-: {-:
:-}                                                                {-:
:-}     guys, that's a deliberate windup, guys, I'm not trying     {-:
:-}     to refight old battles -- honest, guys... no, please...    )-:
:-}                                                                {-:
:-} :-} :-} :-} :-} :-}:-} :-} :-} {-: {-: {-: {-: {-; {-; {-: {-: {-:

Cheers, 

Simon

-- 
------- simon@rheged.dircon.co.uk (Simon Brooke)

	The trouble with Simon is that he only opens his mouth to change feet.
					;; of me, by a 'friend'
