![]()
![]()
|
| "I myself added another mistake to the list of those for which most probably John von Neumann has to be blamed. Flowcharts and the idea that programs must be able to modify their own instructions —a sickening pun!— were already on that list, the use of anthropomorphic terminology in computing science has now been added. I got more than once the distinct impression that that unfortunate use of language can be traced fairly directly to von Neumann's linguistic habits. I made this suggestion in my talk and no one denied it, on the contrary: afterwards I was even shown corroborating evidence. (EWD 572, Trip Report...) For many years it has been thought one of the essential virtues of the von Neumann type code that a program could modify its own instructions. In the mean time we have discovered that exactly this facility is to a great extent responsible for the lack of clarity in machine code programs. Simultaneously its indispensability has been questioned: all algebraic compilers I know produce an object program that remains constant during its entire execution phase. (EWD 517, Programming Considered as a Human Activity) | ![]() Edsger W. Dijkstra |
![]() John McCarthy | It seems to me that LISP will probably be superseded for many purposes by a language that does to LISP what LISP does to machine language. Namely it will be a higher level language than LISP that, like LISP and machine language, can refer to its own programs. (However, a higher level language than LISP might have such a large declarative component that its texts may not correspond to programs. If what replaces the interpreter is smart enough, then the text written by a user will be more like a declarative description of the facts about a goal and the means available for attaining it than a program per se.) (John McCarthy, Lisp -- Notes on its past and future, 1980.) |
If you want more texts, you can check EWD 692 and EWD 123, as well as mentioned chapter in Dijkstra's "Discipline...", but as said, there is no detailed discussion there.
References
- What Dijkstra wrote about Lisp, post on this blog
- McCarthy-Dijkstra short polemics, post on this blog
--



I don't think these views are in contradiction at all. Dijkstra is talking about self-modifying code, which is difficult to reason about. McCarthy is talking about LISP being superseded by languages with higher levels of abstraction, languages wherein a programmer encodes more and more of the semantics of the program in a higher level specification. Both of them were right.
ReplyDeleteWhat's the context of this quote?
ReplyDeleteLisp has jokingly been called "the most intelligent way to misuse a
computer". I think that description is a great compliment because it
transmits the full flavor of liberation: it has assisted a number of
our most gifted fellow humans in thinking previously impossible
thoughts.
— Edsger Dijkstra, CACM, 15:10
Luke, it was "A Humble Programmer", Dijkstra's Turing Award speech 1972 (EWD340), where he discussed his favorite topic: need for disciplined, bug free programming and developing related techniques.
ReplyDeleteIn introduction he shortly mentioned few software projects: ESDAC (the project at Cambridge University Math Lab, for the notion of subroutines), Fortran, Lisp, Algol and PL/I, as the most important ones. Not necessarily as the best ones, because he especially vigorously criticised PL/I on that occasion.
It was all he said about Lisp in that speech.
Lisp is not a high level language, Lisp is one of the more influential programming languages because it is based in a computing formalism, Primitive Recursive Functions, not lambda calculus as many people think.
ReplyDeleteMcCarthy did not understood lambda calculus at the time he wrote his famous paper on lisp and that was the source of the mistake of dynamic scope.
Low level, does not necessarily mean obscure, lisp is not obscure at all.
Is a very elegant language, despite of having Lots of InSipid Parenthesis ;).
Although the quotations from Dijkstra that you mention say that Algol 69 was the first formal description of a language, I do not agree with that. Lisp was based in a formal system, although it had a mistake in its design, on other side it also shows its semantics in a circular description, but formal. The syntax is very simple to need BNF, But was described in the inductive way.
I think that Dijkstra was more concerned about non determinism and concurrency, For that reason he was not an enthusiast of Lisp, But I do not think that he really considered Lisp a bad language,
Scheme is a good dialect of Lisp, but others are not very elegant, maybe that was the source of his critics.
Thanx on nice comment. But why do you think that lambda-calculus is closer to lexical scope?
ReplyDeleteI'm glad that you like my comment.
ReplyDeleteMcCarthy said in a paper in the CACM circa 1980 more or less that the only thing that he would change if he can make the time back, is use lexical scoping instead of dynamic scoping. In the same paper he said that at that time he did not understood lambda-calculus, that was the reason for the lambda expression and Label that was eliminated later.
Lisp was introduced in
"Recursive functions of symbolic expressions and their computation by machine, Part I" CACM Vol 3 Issue 4, April 1960. which is available from McCarthy's page also in the ACM.
In that seminal paper he presented a system equivalent to recursive functions a theoretical system equivalent to a Turing machine.
Some familiarity with primitive recursive functions adds more enjoyment of that paper, then one really understands why lisp was a landmark in computing history.
Nil corresponds to 0, cons to Successor, car and cdr are used to define projections, Lambda and Label were introduced to define functions, but lambda-calculus does not have recursive definitions, names are not part of the system, functions are anonymous. In lambda-calculus recursion is obtained using a fixed point combinator, there are many Y, theta (Turing), Klop's, etc.
Lambda-expressions in lambda-calculus are
i) variables, x,y,z,...
ii) function application (MN) (defined by juxtaposition), and
iii) abstraction, lambda x.M
where M,N are lambda expressions.
Lambda abstraction is like quantification, it follows the syntax of forall and exists in first order logic, also the notation lambda x(M) is used.
That correspond to lexical scope, variables are local to the scope of the lambda abstractor. There is a version of the calculus without variables in the abstractor, instead a number of nestings is used this notation was proposed by De Brujin.
The lambda-calculus bible is Barendregt 1980 book. In a later paper circa 2000, Barendregt tells the anecdote of the origin of lambda notation.
At the beginning Church used \hat{x}.M (in LaTeX syntax that means an x with hat followed by a dot and a lambda expression M, but the typesetter (there was no LaTeX in 1930 :) ) due to technical limitations wrote ^x.M, his supervisor changed the ^ for a lambda letter, then the lambda notation was born. That is a nice story.
But you are right, there are no names in lambda-calculus, but that was what McCarthy said.
Hey, Mexican - I see you're returning frequently to this post; one of the most intriguing problems in Lisp is, from my point of view, disappearance of alpha-conversion from Lisp, and its later resurrection in form of macros, particularly hygienic macros.
ReplyDeleteTake a look on other pages of this site.
You do not need alpha conversion to write a program.
ReplyDeletemodern dialects like Scheme with lexical scope, does not suffer of variables confusion. Their implementation uses closures.
try this in DrScheme with R5RS language
(define x (lambda (t) (list (list 'free 'var 'x) t)))
(define M (lambda (z)(z x)))
(define N (lambda (y)(lambda (x)(y x))))
(define test (M N))
(test 'w)
The first definition of x is needed because in DrScheme you can not print the a compiled procedure. It is just shown as #procedure.
M=(lambda z.z x)
N=(lambda y.(lambda x.y x))
MN => (lambda y.(lambda x.y x) x) => (lambda x. x x) oops!
MN => (lambda y.(lambda x.y x) x) =alpha=>
(lambda y.(lambda w.y w) x) => (lambda w.x w) OK!
You just need to write an alpha conversion function if you want to implement a lisp compiler using lambda calculus in order to implement substitution. Also eta conversion is needed to write a fixed point combinator in an eager (strict or non lazy) language.
See: Essentials of Programming languages, Dan Friedman, et al. (black cover edition, before 2000) that chapter was eliminated from the blue and white cover edition 2000/2001.
A naive macro expansion may use dynamic binding.
But Scheme's syntax macros, do alpha conversion. See DrScheme help syntax-macros. Languages like TeX use dynemic binding. I do not know hygienic macros. Is just another way to call this alpha conversion in other lisp dialects?
I have this tab open in my browser, but I do not read every day.