Live data from Hacker News

Marvin Minsky – The beauty of the Lisp language

webofstories.com

41–50 of 50 posts

Re: Marvin Minsky – The beauty of the Lisp language

#41
post #15
post #10

What does he mean when he says that it's not possible to write a C program that can write other C programs? Seems like there are counterexamples here: http://www.nyx.net/~gthompso/quine.htm Furthermore, it's possible to encode another programs' code into a single print statement, thereby writing one piece of code with another. As that's trivial, I suspect he meant something else. What was it? :).

I suspect "possible" here is not used in the absolute sense, but more just "it would be a total pain in the ass in C, whereas Lisp excels at it". After all, anything is "possible" with hand-written assembly code, too, but realistically speaking, it's not practical.

I couldn't post this last night, but yeah:

My ears perked up at the dual statement that although you can write a Lisp program that writes Lisp programs, nobody does it (um, macros?); and that you can't write a C program that writes a C programs (okay, maybe nobody does this, but you certainly can). I guess he means that C is not "aware" of its own constructs the way that Lisp is.

Also, he said that the algebraic languages were "dying out", but that because of this self-generating ability (which nobody uses), that the future of Lisp was "open".

Huh?

Re: Marvin Minsky – The beauty of the Lisp language

#42
post #33
post #10

What does he mean when he says that it's not possible to write a C program that can write other C programs? Seems like there are counterexamples here: http://www.nyx.net/~gthompso/quine.htm Furthermore, it's possible to encode another programs' code into a single print statement, thereby writing one piece of code with another. As that's trivial, I suspect he meant something else. What was it? :).

Quines are not quite the same thing. Reasonably simple illustration: in Common Lisp, it is possible to write a function that takes a mathematical expression as an argument and returns another expression, as its derivative. So basically I can write (pseudo-lisp-ish): (defun diff (f) ... ) then call it like this: (diff '(+ (pow x 2) x) and I'd get the expression (+ (* 2 x) 1) as a result. The point is, however, that th…

And then there is this whole other category of self-modifying programs - programs that know about their own structure and can change themselves at runtime. This is (almost) in the "unthinkable" category for non-homoiconic languages.

Re: Marvin Minsky – The beauty of the Lisp language

#43
post #33

Earlier quoted context omitted.

Quines are not quite the same thing. Reasonably simple illustration: in Common Lisp, it is possible to write a function that takes a mathematical expression as an argument and returns another expression, as its derivative. So basically I can write (pseudo-lisp-ish): (defun diff (f) ... ) then call it like this: (diff '(+ (pow x 2) x) and I'd get the expression (+ (* 2 x) 1) as a result. The point is, however, that th…

And then there is this whole other category of self-modifying programs - programs that know about their own structure and can change themselves at runtime. This is (almost) in the "unthinkable" category for non-homoiconic languages.

This was, in fact, more or less pioneered in languages that aren't homoiconic in the same manner as Lisp is (code that used self-modification for reasons like time or space optimization was, if not common, at least known of in the early days of electronic computers). Arguably, machine code is very much homoiconic; what is beautiful about Lisp is that the underlying structure of program/data is regular and nicely-abstracted.

Re: Marvin Minsky – The beauty of the Lisp language

#44
post #33

Earlier quoted context omitted.

Quines are not quite the same thing. Reasonably simple illustration: in Common Lisp, it is possible to write a function that takes a mathematical expression as an argument and returns another expression, as its derivative. So basically I can write (pseudo-lisp-ish): (defun diff (f) ... ) then call it like this: (diff '(+ (pow x 2) x) and I'd get the expression (+ (* 2 x) 1) as a result. The point is, however, that th…

And then there is this whole other category of self-modifying programs - programs that know about their own structure and can change themselves at runtime. This is (almost) in the "unthinkable" category for non-homoiconic languages.

I think you could solve most of the problems that you'd need this property for with closures. If the bulk of the execution is defined with them, and you have closures defining which other closures to run, you can have them swap each other out.

Re: Marvin Minsky – The beauty of the Lisp language

#45
post #5

Earlier quoted context omitted.

Strange. I never learned it in college, just on my own for fun, but I've found it to be quite elegant (if impractical compared to better modern languages). The fact that everything is an expression and you can use any expression anywhere makes it very easy to learn, and powerful. I personally find it more enjoyable to use than things like C. Then again, for one historical reason or another, C-type languages won, and…

>> impractical compared to better modern languages How much did 'they' pay you to say that? :D But seriously Lisps are by far the most advanced programming languages. They just take a huge amount of effort to learn.

> How much did 'they' pay you to say that? :D

I wish.

Seriously though, most modern languages have Lisp features. Even Java 8 will get Lambdas. Quite a few languages have macros. Many languages have eval and REPLs.

Right now I'm playing around quite a bit with Haxe. Cool language, static typing (w/ type inference), pattern matching, closures, macros, and compiles to half a dozen languages and nearly every platform known to mankind...

Re: Marvin Minsky – The beauty of the Lisp language

#46

Earlier quoted context omitted.

And then there is this whole other category of self-modifying programs - programs that know about their own structure and can change themselves at runtime. This is (almost) in the "unthinkable" category for non-homoiconic languages.

I think you could solve most of the problems that you'd need this property for with closures. If the bulk of the execution is defined with them, and you have closures defining which other closures to run, you can have them swap each other out.

I'm not sure I understand what you have in mind. Assuming I have something like this:

int foo(void) { return bar(1) + 2; }

is there any way in which I could arbitrarily modify this function? E.g. to dynamically turn it into

int foo(void) { return bar(2) * 4 }

using closures?

I get how you could do that, assuming you had a function defined for each of the possible operations you needed. But what about arbitrary modifications?

Re: Marvin Minsky – The beauty of the Lisp language

#47
post #41
post #15

Earlier quoted context omitted.

I suspect "possible" here is not used in the absolute sense, but more just "it would be a total pain in the ass in C, whereas Lisp excels at it". After all, anything is "possible" with hand-written assembly code, too, but realistically speaking, it's not practical.

I couldn't post this last night, but yeah: My ears perked up at the dual statement that although you can write a Lisp program that writes Lisp programs, nobody does it (um, macros?); and that you can't write a C program that writes a C programs (okay, maybe nobody does this, but you certainly can). I guess he means that C is not "aware" of its own constructs the way that Lisp is. Also, he said that the algebraic lang…

I understood the "open" comment to mean "open to modification and extension", independent of whether it is dying out.

Re: Marvin Minsky – The beauty of the Lisp language

#48
post #46

Earlier quoted context omitted.

I think you could solve most of the problems that you'd need this property for with closures. If the bulk of the execution is defined with them, and you have closures defining which other closures to run, you can have them swap each other out.

I'm not sure I understand what you have in mind. Assuming I have something like this: int foo(void) { return bar(1) + 2; } is there any way in which I could arbitrarily modify this function? E.g. to dynamically turn it into int foo(void) { return bar(2) * 4 } using closures? I get how you could do that, assuming you had a function defined for each of the possible operations you needed. But what about arbitrary modifi…

You wouldn't want to modify the function in-place, that would violate immutability of data. Each of these closures would themselves be generated, by a factory method. When you're ready to modify, you'd invoke the factory to generate another closure, then you'd use whatever infrastructure you built to assign them in the first place to re-assign them to the new closures.

Re: Marvin Minsky – The beauty of the Lisp language

#49
post #46

Earlier quoted context omitted.

I'm not sure I understand what you have in mind. Assuming I have something like this: int foo(void) { return bar(1) + 2; } is there any way in which I could arbitrarily modify this function? E.g. to dynamically turn it into int foo(void) { return bar(2) * 4 } using closures? I get how you could do that, assuming you had a function defined for each of the possible operations you needed. But what about arbitrary modifi…

You wouldn't want to modify the function in-place, that would violate immutability of data. Each of these closures would themselves be generated, by a factory method. When you're ready to modify, you'd invoke the factory to generate another closure, then you'd use whatever infrastructure you built to assign them in the first place to re-assign them to the new closures.

Ah, got it. Thanks!

Re: Marvin Minsky – The beauty of the Lisp language

#50
post #49

Earlier quoted context omitted.

You wouldn't want to modify the function in-place, that would violate immutability of data. Each of these closures would themselves be generated, by a factory method. When you're ready to modify, you'd invoke the factory to generate another closure, then you'd use whatever infrastructure you built to assign them in the first place to re-assign them to the new closures.

Ah, got it. Thanks!

If you wanted to get really sophisticated, you could generate the factory methods, too.
Post reply on HN