Path: utzoo!utgpu!jarvis.csri.toronto.edu!rutgers!apple!ames!eos!shelby!csli!gandalf From: gandalf@csli.Stanford.EDU (Juergen Wagner) Newsgroups: comp.lang.lisp Subject: Re: Re: Code as data (replies to comments). Message-ID: <9402@csli.Stanford.EDU> Date: 14 Jun 89 03:07:39 GMT References: <1057@syma.sussex.ac.uk> <1350021@otter.hpl.hp.com> Sender: gandalf@csli.Stanford.EDU (Juergen Wagner) Reply-To: gandalf@csli.stanford.edu (Juergen Wagner) Organization: Center for the Study of Language and Information, Stanford U. Lines: 160 In article <1350021@otter.hpl.hp.com> sfk@otter.hpl.hp.com (Stephen Knight) writes: >> Meanwhile, Lisp also has the >> advantage that nobody has to learn a bunch of arbitrary "precedence >> rules"; everything just works in the obvious way. > >At the expense of inflexible and rather odd-looking expressions. Again, I was >trying to establish the notion that a compromise has taken place. I would >certainly agree that the over-use of infix syntax is poor style. Most of this discussion seems to be about syntactic issues. Syntax can be changed, and if a particular user doesn't like the typical list LISP syntax, he/she is free to write a different reader (what has been done: take CGOL as an example). However, there you use different representations for the same structures: why should I have to read foo(a,b) in one place, and [foo,a,b] in another? Essentially, what I am dealing with is a list of three elements, i.e. (foo a b). Pretty-printing (and `pretty-reading') may take care of cases where the syntax is somewhat counterintuitive to users but again, in my point of view, that's something application- or user-specific. I think, every LISP user agrees that twelve or more closing parens at the end of a function definition are terrible. However, this phenomenon is due to the fact that LISP doesn't have a large number of syntactically different styles to present objects. There is exactly one syntactic form, and that is the LISP concept. As new data types have been added, several LISP dialects and also CommonLISP made the attempt to again unify them into a uniform scheme. The result was the #-macro, which is nowadays used to represent structs, vectors, ... A little further down in your response, you mention readability. Readability of LISP programs is comparable to those of conventional programming languages. In the case of LISP, readability is directly dependent on programming style and code formatting. Also, the question is "readability for which type of reader?" Clearly, COBOL programs are readable :-) :-) ... On the issue of quoting characters: in LISP, everything may be a quoting character. If I should define '&' as a read macro which takes one argument, and represents this (unevaluated) argument in a list, i.e. &foo => (foo) this would be an arbitrary convention which serves the purpose it is used for. Quoting characters such as string quotes "..." and symbol quotes |...| are arbitrary. But what is not? I think, we have to make clear distinction between features introduced as conventions, and those introduced as necessities. The question "why there is no closing quote" is not meaningful, given the semantics of the 'quote' readmacro in LISP. Do NOT view "'" as a necessity. It is merely a shorthand for (QUOTE ...) for those who want it (you notice that we have open/close parens again). You may define <...> to quote literal objects but that's an individual matter. >Rather than raising any more hackles, I'd like to propose my 'vision' >of Lisp with Pascal-like syntax, and an introduction route that hopefully >wouldn't have too many Lisp hackers hanging themselves in the morning. >In case you haven't guessed, much of this vision derives from Prolog. (I'm >not a great Prolog fan, by the way, so don't bother knocking it :-)) Have you heard of POPLOG? (no typo) >Firstly, I suggest representing the parse-tree in s-expression format with >the head of each s-expression being one of a fixed set of atoms denoting >special forms. Thus where one would have written > (f E1 ... En) >the 'raw' syntax requires > (APPLY f E1 ... En) >All and *only* literals would be quoted. Thus where one would have written > (f 'a 'b 7) >one now has > (APPLY f (QUOTE a) (QUOTE b) (QUOTE 7)) >[So far, this should be familiar to anyone who has bumped into Lispkit Lisp.] This requires a read-time decision as to whether something is interpreted as a function call or as a list. The user may not want to make this decision because he/she would like to defer this until the respective expression is actually used. In the case of macros, the user of those macros may have no clue as to whether some or all of the macro's arguments are going to be used as code or as data. >It is a matter of taste, whether to go to the next stage and insist that >even variables are tagged with an appropriate atom. > (APPLY (VAR f) (QUOTE a) (QUOTE b) (QUOTE 7)) >As you can see, the correspondance between form and function has been made >excruciatingly obvious. There is no *need* to tag "variables" as such. This is the subtle difference which distingushes e.g. TurboProlog from *REAL* Prolog, and FORTRAN from LISP. LISP objects know what type they are of. QUOTE has a different function: it is a language construct which control evaluation, i.e. something which cannot be inferred from the symbol itself. >... >The vital stage is that Lisp is then defined in terms of this canonical >form. The alternative syntaxes are going to be defined in terms of READ >functions (parsers) that generate s-expressions in this format. This will >imply the need for two types of READ -- one that reads in a literal and >one that reads in a program. Of course, the former is no more than a >component of the latter. How do you know when to use which reader? In the case of certain macros, this may be impossible (or you may need a general theorem prover to find that out). >* I also enjoy the use of infix syntax for operators such as assignment, > arithmetic, boolean operators, and a few other conventional cases. Although > user-definable syntax is attractive from the viewpoint of orthogonality > of syntax, my experience is that it needs strict limiting to be acceptable. > So I would limit user-defined operators to be of a single precedence level > and enforce bracketing where there is potential ambiguity. Why not. Any user may define new readmacros ('open-close' or just 'tag'). >* If the language is intended for functional programming then I prefer > function application to be denoted by expression juxtaposition. This > doesn't work so well in Lisp because functions can take multiple > arguments. So for this purpose, I think that the standard prefix form > that is familiar from mathematics and languages such as FORTRAN and Pascal > is appropriate. It is one possible alternative. How about postfix notation? How about a different model which uses stacks (a la Forth or PostScript)? >* In imperative languages, it's a good idea to permit each expression > context to contain a sequence of expression (separated by the ubiquitous > semicolon (which is optional at the end of sequences)) and to allow > declarations. What are declarations needed for? Why not use PROGN? LISP has the advantage that there is only one paradigm: that of functional application. This paradigm is used to implement functions in the conventional sense, macros, and special forms. I call this a uniform model. In my opinion, special constructs are not needed for sequences, conditional evaluation, etc. if all that can be embedded into the functional calculus of LISP. >* There are many occasions when monadic operators look best in postfix > format. I would borrow the postfix '.' of (C, Pascal, Ada, Pop11,...) > for this. Why not? >* I think it is a point of good syntax design for the formal parameter list > to mirror the actual parameter list. Thus I prefer DEFINE to DEFUN. Again: a matter of taste. (defmacro define (&rest args) `(defun ,@args)) Or how about Scheme? >* The list syntax of Prolog is admirable because it elegantly integrates > bracketing with list appending without the need for quoting (as in Lisp > and Pop11) and *also* works in a functional context, unlike other Prologian > ideas. The list syntax in Prolog can also be counterintuitive if the [...] notation has already different meaning in the domain of an application. In such cases, one may prefer <...> or (...) or {...} or .... There are more points I should mention but... well... -- Juergen Wagner gandalf@csli.stanford.edu wagner@arisia.xerox.com