[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: "Python for Lisp Programmers"

   Date: Sun, 9 Dec 2001 15:25:40 -0500 (Eastern Standard Time)
   From: "S. Alexander Jacobson" <alex@shop.com>
   On Sun, 9 Dec 2001, Michael Vanier wrote:
   > Even though I love python and use it all the time, I'll second Shriram
   > here.  I spent some of the last term teaching scheme to undergrads, and
   > none of them had a problem with the parenthesized syntax after about the
   > first two weeks.  I think the problem is that most people have a knee-jerk
   > negative gut reaction to seeing all those parentheses, and they never make
   > it past that stage.
   Historical question: Ergonomically, Parentheses are annoying because they
   require constant use of the SHIFT key.  Square brackets would have been a
   better choice.  Who chose parentheses and why?

Here is what John McCarthy had to say about it:

  The programs to be hand-compiled were written in an informal notation
  called M-expressions intended to resemble FORTRAN as much as possible.
  Besides FORTRAN-like assignment statements and go tos, the language
  allowed conditional expressions and the basic functions of LISP.
  Allowing recursive function definitions required no new notation from
  the function definitions allowed in Fortran I - only the removal of the
  restriction - as I recall, unstated in the FORTRAN manual - forbidding
  recursive definitions.  Tye M-notation also used brackets instead of
  parentheses to enclose the arguments of functions in order to reserve
  parentheses for list-structure constants.  It was intended to compile
  from some approximation to the M-notation, but the M-notation was
  never fully defined, because representing LISP functions by LISP lists
  became the dominant programming language when the interpreter later
  became available.  A machine readable M-notation would have required
  redefinition, because the pencil-and-paper M-notation used characters
  unavailable on the IBM 026 key punch.
  Another way to show that LISP was neater than Turing machines was to
  write a universal LISP function and show that it is briefer and more
  comprehensible than the description of a universal Turing machine.
  This was the LISP function eval ... Writing eval required inventing
  a notation representing LISP functions as LISP data, and such a notation
  was devised for the purposes of the paper with no thought that it would
  be used to express LISP programs in practice. ...
  S. R. Russell noticed that eval could serve as an interpreter for LISP,
  promptly hand coded it, and we now had a programming language with an

  The unexpected appearance of an interpreter tended to freeze the form
  of the language, and some of the decisions made rather lightheartedly
  for the ... paper later proved unfortunate.

  Another reason for the initial acceptance of awkwardnesses in the
  internal form of LISP is that we still expected to switch to writing
  programs as M-expressions.  The project of defining M-expressions
  precisely and compiling them or at least translating them into
  S-expressions was neither finalized nor explicitly abandoned.  It just
  receded into the indefinite future, and a new generation of programmers
  appeared who preferred internal notation to any FORTRAN-like or
  ALGOL-like notation that could be devised.

  --McCarthy, John.  "History of LISP."  In Wexelblat, Richard L. (ed.),
    Preprints of the ACM SIGPLAN History of Programming Languages Conference.
    ACM SIGPLAN Notices 13, 8 (August 1978), 215-224.  Also published in
    Wexelblat, Richard L. (ed.), History of Programming Languages.
    ACM Monograph Series.  Academic Press (New York, 1981), 173-197.

So: (a) brackets were not used because they weren't on the keyboard
of the IBM 026 keypunch used to 80-column punch cards in those days,
and (b) the use of parenthesized S-expressions as a program notation
was something of an accident.

Here is the factorial function written in M-notation and the
now familiar S-notation:

 fact[n] = [ n = 0 -> 1; T -> n*fact[n-1]]

 (define fact (n) (cond ((= n 0) 1) (t (* n (fact (- n 1))))))

and here is the list-union function in both forms:

 union[x;y] = [null[x] -> y;
               member[car[x];y] -> union[cdr[x];y];
               T -> cons[car[x];union[cdr[x];y]]]

 (define union (x y)
   (cond ((null x) y)
         ((member (car x) y) (union (cdr x) y))
         (t (cons (car x) (union (cdr x) y)))))

Keep in mind that M-notation used an actual rightarrow character, not
the two-character digraph "->" that I have used here to approximate it.