Newsgroups: comp.sys.acorn.tech

In article ... bwc@waikato.ac.nz (Ug!) writes:

| Chris Dollin writes:
|>Ug! writes [responding to me]:
|>
|>    Beware: Lisp is essentially an interpreter, even when it's compiled.
|>
|> Would you like to explain the grounds on which you base this claim? [What do
|> you mean by ``essentially'' and ``interpreter''?]
|
| Not really - I think you know what I mean.  I qualify Lisp as an interpreter,
| since much lisp code actually writes lisp programs which are then executed at
| some stage.  I also qualify Smalltalk as an interpreter though, so maybe I'm
| wrong.

Well, it seems to me then that you regard a language as ``essentially
interpreted'' if the compiler happens to be available at run-time. OK, it's a
definition; I can live with it, but I don't like it.

[Agreement about having a rich library deleted.]

|> ``Trivial'' is the word I'd use. Lexical analysers clump up letters into
|> identifiers all the time; what's to stop them clumping up sign characters into
|> operator names? There is *no* problem here, despite what C++ language
|> designers may have tried to tell you. [They're stuck with supporting the
|> lexis of C, and wimped out on requiring whitespace for utterances such as
|> ``x+++y''.]
|
| Read what I said again.  Was I talking about lexical analysis?  No.  I was
| talking about parsing.  Perhaps you feel user defined operators are trivial
| to parse; I don't agree.

But there *is* no parsing problem. The lexical analyser recognises operator
symbols (such as ``++'', ``:-'', ``<>'', ``/=='', ``$!##!''), and says to the
parser ``operator symbol, precedence nnn''. The parser is using a grammar
like:

    Expr_nn ::= Expr_nn [Op_nn Expr_mm]		(mm < nn, say)

and just eats the operator symbol -- in just the same way as it does for
*existing* languages; it just so happens that the spellings allowed for
operator names have become more varied.

Now, the only difficulty I can see is that if you feel that user-defined
operators must necessarily have user-defined precedences. *Then* it gets
tricky to parse, because you need the precedences fed back to the lexer *while
the parse is happening*. Yukk. So you *disallow* it; it's not useful enough.
Give all non-standard operators the same precedence (I suggest just tighter
than assignment, if you have assignment).

Existance proofs: Algol 68 (but that had user-defined priorities), and HP-SL,
the specification language we did here at the Labs, which had user-defined
operators in almost the style I describe. There were no parsing problems due
to UDOs.

[More agreement on the utility of various library types.]

|> I'd put the object in the heap and return its address -- a perfectly good
|> handle for the object. I suspect we're at cross-purposes here; what do ADTs
|> gain you in reusability that module scoping does not?
|
| When you have to pass back some sort of handle to the user of a module: not
| internally to a module.  Like C's and Basic's file handles, for example.

No, that wasn't what I meant. If you represent an object by its address,
export the object type, but *not* any of the representation-based operations,
(all of which is what you get from what I call a ``module''), then you're just
as abstract as an ADT. Hence the abstractness is nothing to do with the
data-type, it's just to do with name-hiding.

|> Ug! responds to my ``GARBAGE COLLECTION'':
|>
|>    Ooo.  Garbage Collection.  Nice.  Still, a big hit in speed/performace,
|>    etc.  See Modula-3 (also has freely available ftp'able descriptions).
|>
|> What big hit did you have in mind?
|
| Garbage collection is fine, but it really does need hardware to support it.
| There has been a lot of work done on stopping the 'sudden hit' (i.e. the
| machine freezes while garbage collection takes place), which early versions
| of Lisp and Smalltalk suffered from.  Most of them however now require a
| steady percentage of the processors time in which to perform garbage
| collection.  Without hardware, this can be quite noticeable, especially as
| memory fills.  (from experience with Smalltalk)

My experience with garbage collection is with Poplog (on VAXes and HP
68K-based workstations), where the ``sudden freeze'' was never long enough to
be a nusiance (until X arrived in the system. Sigh.), and with my own language
Pepper, where the GC time is noticable but the code could be improved no end.
So, unless real-time is an issue, I don't believe the performance hit is
particularly important.

|> For simplicitys sake, I'd put it in. I've written too much C, and handled
|> my own store allocation too often, to want to force the poor programmer to
|> do it themselves.
|
| Oh come on!  This is probably the first time this guy has implemented a
| programming language and you want him to put in grabage collection?!!!  Be
| reasonable!  Better to implement a language without garbage collection than
| get bogged down and not manage to implement it at all!

Now *that* is a good argument. Just so long as we agree that it's a practical
matter of someone implementing their first language, rather than a desirable
property of languages.

|> What does it buy you? Use modules and put up with the fact that B can see X.
|> If necessary have the compiler tell you. The idea is nice, but in practice
|> it's just make-work for the programmer.
|
| Data hiding gains you quite a bit.  Read some stuff on software engineering.
| Essentially its a quality assurance measure.

I *know* what data-hiding buys you. I am strongly in favour of data-hiding.
Block structure is one form of such (inner is hidden from outer). But the
requirement of making procedures declare all they import is *too onerous*; it
was tried in Euclid, for example, and they ended up (so I hear) with the
compiler constructing the import lists for the programmer.

Modules allow you to do data-hiding (rather, name-hiding). Within a module, it
doesn't seem worth it to require that all names ``falling'' into a procedure
be declared as such. Who are you hiding from? If it's *really* important, use
more modules -- that's what they're there for.

[Agreement -- broadly -- on initialised declarations and typed constants,
deleted.]

|> incremental compilation;
|
| Maybe.

Well, it's harder to do. But it's a good design goal (I think).

|> first-class procedures; first-class everything; full lexical scoping.
|
| Can you explain these a little more?  I'm not that familiar with Common Lisp
| or Scheme, I'm afraid.

Tale this little example written in Pepper (the current compiler can't handle
it, but that's just laziness on my part; I can tell you how it *will* be
implemented if you want):

	define adder( n ) as
		define add_n( m ) as n + m enddefine;
		add_n
	enddefine;

	val add1 = adder( 1 );
	val add2 = adder( 2 );

	add1( 41 ) =>

	** 42

``adder'' is a procedure which, when called with some value ``n'', returns a
procedure which, when applied to some argument ``m'', delivers the sum of
``n'' and ``m''. ``add1'' and ``add2'' are procedures delivered by ``adder''
for different n's -- they have a variable ``n'' *each*.

Lexical scoping means that ``n'' is in scope in the region of text in which it
is declared, including in any nested procedures (here, ``add_n''). (Even
Pascal can do this, although C cannot.) *Full* lexical scoping means that the
variable ``n'' will persist for as long as necessary -- in this case, it
cannot be allocated on the stack, as it needs to survive ``adder'' so that it
remains available to (some instance of) ``add_n''.

``First-class everything'' means that all objects (values) have (in some
sense) equal rights; being passed as parameters, returned as results, stored
in data-structures, or assigned. This applies particularly to procedures,
which are often short-changed (C only admits them with the locution
``pointer-to-function'', and doesn't permit them to be declared nested; see
``full lexical scoping'').

As a language design rule, it says you should make the distinction between
an object (value) and its name clear. Unfortunately, first-class-ness usually
needs garbage collection to make it possible ...
--

Regards,    | ``In fingers of trees, and valleys of gold    | Judy Tzuke
Kers.       | I watch as you outshine the charlatan foe.''  | Higher & Higher
Newsgroups: comp.sys.acorn.tech