Overview and Introduction to Lisp (1986) [video]
youtube.com
youtube.com
"A computational process is indeed much like a sorcerer's idea of a spirit. It cannot be seen or touched. It is not composed of matter at all. However, it is very real. It can perform intellectual work. It can answer questions. It can affect the world by disbursing money at a bank or by controlling a robot arm in a factory. The programs we use to conjure processes are like a sorcerer's spells. They are carefully composed from symbolic expressions in arcane and esoteric programming languages that prescribe the tasks we want our processes to perform."
I used to read and re-read that paragraph. I read it aloud to my parents and to girlfriends, trying to find somebody to share my awe.
Sometimes it is hard to find others who share an appreciation of the beauty of mathemtics or computing. People look at me funny when I say programming is every bit as much an art as writing a poem. Almost any human activity can be an art.
On that analogy, Lisp is like French. Other languages are like German.
(And before you downvote me please note: I am a native German speaker.)
Please note that I am nowhere near fluent in German. It just feels great, especially the way words can agglutinate to form comically long words, while still transporting meaning.
It has an conceptual interpretation of what it's doing; what it represents. That is what is intangible.
Posted on a site running on MzScheme.
>Posted on a site running on MzScheme.
Posted on a site running MzScheme, that probably tens, if not hundreds of thousands of people, read often, get useful info from, that is of help to them in the real world, and that many people get jobs from.
Computer science education isn't just vocational training for software development gruntwork, though.
54. Beware of the Turing tar-pit
in which everything is possible
but nothing of interest is easy.
Unlike Scheme, Python requires extensive research of the documentation in order to get the correct syntax and semantics even for the simple code in SICP. It's not just simple facts like operator precedence, it's the conceptual baggage of statements versus expressions. It's the one true way of iteration rather than recursion. It's the arbitrary distinctions of a core language, built in functions, a standard library and PiP. And Python has objects just because. But everything isn't an object.SICP was an introductory programming class (though obviously being used at MIT allowed certain assumptions).
But programming now isn't so much like that, said Sussman. Nowadays you muck around with incomprehensible or nonexistent man pages for software you don't know who wrote. You have to do basic science on your libraries to see how they work, trying out different inputs and seeing how the code reacts. This is a fundamentally different job, and it needed a different course. [...]"
(From http://wingolog.org/archives/2009/03/24/international-lisp-c...)
Everything else is pretty much programmed like this. I've seen things you'd likely describe as "deeply embedded" running a CORBA server so that Java written by one company can communicate with C++ written by another company, integrated by a third company that doesn't have the source to either.
Some automotive software is starting to show some trends towards the airplane approach, but the big exception among safety-critical parts is self-driving cars. Many of them even use ML algorithms for which it is non-trivial to even determine why a particular error was made.
Cost is a big driver of this. Given equally competent programmers, creating formally correct software is 1-2 orders of magnitude at low levels of complexity. Current software-engineering indicates that the difference increases as complexity increases. You can easily end up spending 100x as much for software that has 1% as much complexity.
Much of the time, features drive sales, and sales drive revenue, so the less rigorous software ends up with both higher budget and lower costs.
Does anyone know why they did that? I did read about it around the time, but do not remember reading about the reasons. As a Pythonista, and one interested in Lisp, I'd like to know.
Update: Okay, I was going sequentially and did not at first see a few answers (sibling comments) below. Still, if anyone else has any insights, interested to know more.
Don't get me wrong, this is in no way an argument against what you said. I'm just offering up a possible answer.
After that they apparently switched the class to python.
My professor was Brian Harvey whose doctoral advisor at MIT was one of the authors of the SICP book we used for the class.
It was a good book. One of the few CS textbooks I actually read. Many CS books are pretty badly written imo.
But there are a few that I consider very well written. This book was one of them.
Scheme and parenthesis hell when writing code on the midterms....
Also car caar cdr cddr etc etc (you can theoretically nest as deeply as needed)
hahaha that class...
Writing code on paper sucks in many (all?) languages. At least the ones I have tried. Python might actually have an advantage on that front, Haskell, too.
But scheme especially when you have code like this:
(letrec ((even? (lambda (n) (if (zero? n) #t (odd? (- n 1))))) (odd? (lambda (n) (if (zero? n) #f (even? (- n 1)))))) (even? 88))
The level of nesting can get rediculous.
Writing that on a midterm is harder than Python or java.
I’d say Python is nicest when writing out code.
Could you maybe break it all down for us ? thanks
When you want the design to be fixed and predictable and easy to develop for the developer, before the program runs, pick Haskell.
If you like Lisp for specific tasks then exactly this would be a good reason to do so.
1: https://www.destroyallsoftware.com/talks/wat (45 seconds in)
Lisp has a macro called setf, which takes any call which gets a value -- whether from a local function variable, or a class, to an array or hash table entry -- and converts it to the corresponding setter call. (If you define your own value places/types, there are also functions to make setf aware of how they work, so this isn't restricted to just some defined set of features in the language. Anything that holds a value in Lisp can be "setf" to a new value.)
There are a couple of other "big" Lisp macros in the language standard like with-open-file (which ensures a file is closed once control flow exits the body), loop (does pretty much what it says on the tin: provides whatever looping method you might want), or handler-case (try-catch style error handling; yes, Lisp allows for other methods).
Or how about the example I recently saw in a cryptography library. Since a lot of cryptographic algorithms use integer math modulo some giant number, this library defined a macro "mod-n" which took a base and some Lisp code, and re-wrote the code so the common integer math functions (addition, multiplication, etc.) would only return values "modulo {base}" --that is, return only values between 0 (inclusive) and base (exclusive). This meant their modulo math code looked (nearly) the same as normal, just standard arithmetic functions. This wasn't a very large macro either: only around 10 lines long (and about half of that being the list of operator replacements).
Interactive Development let you iterate ideas really fast, and allows an ease of exploration that's refreshing and can really help to learn how to use a library, an API, etc.
Metaprogramming lets you add whatever functionality you want. It can help reduce boilerplate code down to a minimum.
Those are the two features where I think it distinguishes itself.
I think Lisp is interesting, but I doubt you will find many parts that are "better" (more powerful or succinct) than Haskell.
Lisp is primarily about freedom that macros give you. However, the two huge use cases for macros, selective evaluation, and representing code as data (different interpretations of the same code), can be naturally done in Haskell. There are some other minority use cases for macros, but in my current view they do not justify the cost of losing the type system.
I now think that macros are an evolutionary dead end. They are powerful, but they are hard to integrate with the type system. It's kind of surprising that progress (IMHO) in programming comes from (selective) restriction of freedom. And that's why Lispers will probably strongly disagree with me...
Anyway, if you like Python, you might like Lisp. The core language is more elegant, and much more powerful, but the libraries are generally less polished.
Somebody recommended Let Over Lambda to show what macros can do, I don't disagree but I would recommend reading On Lisp first, it covers more traditional uses of macros.
Many of the ideas presented by Bret Victor can be seen on those environments
Allegro Common Lisp and LispWorks are the surviving examples how they used to be.
Common Lisp has found a very high local-maxima for macros. If you knew all of common lisp except defmacro, I could explain how it works to you in about 3 sentences. This is an absurd lever for how much power it gives you. This is also where many "lisp-in-foo" implementations fall down.
They (rarely) use the scheme macro system (which has a very complicated algorithm behind it) or more commonly implement the common lisp system, but without the features of common lisp that make it reliable. A major exception to this rule is Clojure.
I'm not a huge clojure fan, but every single place in which it differs from common lisp, it is immediately apparent that Rich understood why it was done in common lisp, and has very good reasons for doing it differently. It's one of the very few lisp branches that I can't find Chesterton's fences[1] in. I don't think this is because there's anything wrong with lisp, but rather that it's very very easy to write a any lisp dialect, which means you get a lot more bad ones. You need to do a lot more work to write a bad
1: https://en.wikipedia.org/wiki/G._K._Chesterton#Chesterton's_...
Anything that takes work required some form of motivation. It is very likely that the person that did the thing you think to be wrongheaded was a lot more like you than different from you.
The times when experience gets in the way is when the reasons for decisions are no longer true, but you fail to revisit those decisions. My favorite example for this is the Jet engine:
Radial-flow compressors create far too much drag to create efficient engines. Axial flow compressors generate too little compression in each stage to create lightweight engines. Therefore jet engines are not practicable.
The above paragraph was true around 1930. Improvements in metallurgy, machining, and compressor design eventually made axial-flow compressors much lighter and more efficient. I can easily imagine a more experienced engineer telling a less experienced one something like "I looked into that and the math just doesn't work out."
One can't fault the more experience engineer because one doesn't have time to reexamine all of the underpinnings for all of the knowledge one has about the world on a regular basis. Though I do recall hearing a few people (including Feynman) who would keep a journal of problems they failed to solve. Any time they would learn a new technique or about a new technology they would flip through and see if there was anything in it that could be solved with the new information.
[1] https://ocw.mit.edu/courses/electrical-engineering-and-compu...
Nitpicking aside, I would have loved to have this sorcerer among my CS professors!
(defun average (x y)
(/ (+ x y) 2))
(defun iterate (start)
(loop repeat 3
for val = start then (average val (/ 2 val))
collect (list val (float val))))
(iterate 4/3)
((4/3 1.3333334) (17/12 1.4166666) (577/408 1.4142157))
(iterate 3/2)
((3/2 1.5) (17/12 1.4166666) (577/408 1.4142157))
Not sure if this is really a software bug, maybe a slide preparation bug.It was quite some "fun" doing the printouts, and playing around to get them to display properly.
>It was quite some "fun" doing the printouts, and playing around to get them to display properly.
Ha ha, good one. I never had to do it (or had the privilege of doing it, depending on one's point of view), but saw it being done some (as a junior), for internal or client presentations at companies where I worked earlier. Another name for it was "transparencies", IIRC. Ugh. Fiddly stuff. Something like the difference between writing articles or books on paper (or typewriter) versus using a wordprocessor or text editor, with all the attendant slowness and rework in the former cases.
And then the same comment by another MIT professor 22 years later at 00:45:12 https://www.youtube.com/watch?v=SXR9CDof7qw&t=45m12s