home *** CD-ROM | disk | FTP | other *** search
- From: kers@hplb.hpl.hp.com (Chris Dollin)
- Date: Wed, 19 Aug 1992 11:02:13 GMT
- Subject: Re: New Language/Compiler (ideas wanted)
- Message-ID: <KERS.92Aug19120213@cdollin.hpl.hp.com>
- Organization: Hewlett-Packard Laboratories, Bristol, UK.
- Path: sparky!uunet!kithrup!stanford.edu!ames!sun-barr!cs.utexas.edu!sdd.hp.com!hpscdc!hplextra!otter.hpl.hp.com!hpltoad!cdollin!kers
- Newsgroups: comp.sys.acorn.tech
- References: <1195@grun.is> <1992Aug17.132929.10141@waikato.ac.nz> <KERS.92Aug17083517@cdollin.hpl.hp.com> <1992Aug18.114418.10160@waikato.a
- Sender: news@hplb.hpl.hp.com (Usenet News Administrator)
- Lines: 179
- In-Reply-To: bwc@waikato.ac.nz's message of 19 Aug 92 05:36:12 GMT
- Nntp-Posting-Host: cdollin.hpl.hp.com
-
- 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
-