21 ms·
Not Lisp again (2009)
- kleopullin 8y agoI thought it would be a down with Lisp article, but it was like my experience with the language, omg, how cool. From that ancient introduction to Lisp all I learned was that Lisp was as close to perfection and beauty as I would get in a programming language.
- kamaal 8y agoLisp is basically writing a program as abstract syntax tree, with facilities to modify the abstract syntax tree.
- wycy 8y agoSerious question: what is it about the "beauty" of Lisp that the HN community seems to like so much? To me, how Lisp looks is its worst quality--the number of parentheses is just mind boggling. I want to understand why it is so loved.
- kamaal 8y ago1. You write everything as a List. So there is syntax, but not exactly. 2. The data is also list, and your program is also a list. 3. Algorithm are basically List Manipulation(Stacks, Queues, Trees, Adjacency lists). So its easy to write complex algorithms in Lisp. 4. Tail call recursion. This part amplifies 3. further. 5. Functional programming features. 6. REPL. I mean like a real REPL. 7. Macros. 1 - 7 helps you to express problems and their solutions with code which represents exactly that. The boiler plate and other assisting code is largely non existent. Another reason is if a thing has been there around for the longest, more people have thought about it. Both quality and quantity of literature of it are higher than others.
- blowski 8y ago> Another reason is if a thing has been there around for the longest, more people have thought about it. Both quality and quantity of literature of it are higher than others. Being older doesn’t necessarily mean either quantity or quality of literature will be greater. MUMPS has been around for much longer than Go, for example.
- Insanity 8y agoI think because it is a powerfull language - and once you learn to look past the parentheses it actually has some pretty cool features. For example, it is a homoiconic language, so any piece of data can be evaluated as if it is code. The only way to really understand it is probably to learn it :)
- pjc50 8y agoI would like to make the controversial claim that homoiconicity counts against adoption; the single representation carries little structural information and the meaning of a symbol is highly dependent on its containing context. Whereas the ALGOL-derived languages use different types of bracket or other means to indicate visually what the semantics are. Ironically modern Javascript often replicates the bracket pileup, just with "})" instead. Python does away with it by having "nonindented newline" as an invisible semantic character that closes any number of scopes.
- AnimalMuppet 8y agoHmm. I've been thinking for a while now that Lisp (and also FP) matches how some peoples' minds work, and doesn't match how other peoples' minds work. For those who match Lisp and/or FP, it's like a revelation, and it's very freeing. For others, not so much - it's a new way of programming, and you can do it that way, but why would you want to? You said: > ... the single representation carries little structural information and the meaning of a symbol is highly dependent on its containing context. That makes me wonder if the difference is abstract vs. concrete thinking - those who by nature prefer abstract thinking will find Lisp more natural, and those who prefer concrete thinking will find it clumsy and unsettling. Choosing the "right" programming language is not just finding the right language for the task (though it is that). It's also finding the right language that fits our minds - and our minds are not identical.
- lispm 8y agoI think it can be learned - but one needs to have an open mind. If one has learned how a specific program look like in something like PASCAL and then later learns Lisp, there are a bunch of concepts which need to be adjusted... I started with BASIC, various Assembler variants, PASCAL, UCSD PASCAL, MODULA 2, ... and then learned Lisp variants and Scheme - and also learned basics of some other languages like ObjectPascal, SAIL, Prolog, Postscript, Smalltalk, ...
- plasticchris 8y agoCode is data. So you can write a program to write parts of your program, on the fly
- collyw 8y agoTo be fair you can do that in most modern languages. (I don't know lisp) but sometimes this approach just makes the code really difficult to understand afterwards. Does Lisp have something that makes it easier or better?
- AnimalMuppet 8y agoYou can, but it's like picking your nose with boxing gloves on[1] - it's really clumsy. In Lisp, it's natural and easy. It's maybe the same in result, but it's really different in ease of use. [1] Credit where due - I stole that phrase from my friend Michael Pavlinch.
- int_19h 8y agoOne could argue that it's made "natural and easy" by making Lisp itself much more difficult to write. So, in other languages, the macro authors pay the tax, but their users do not. In Lisp, everyone pays the tax. This is, perhaps, why writing macros is far more common in Lisp than in other languages with them - if you pay the tax either way, you might as well fully utilize what it buys you. Whereas in another language, you weigh the benefit that a macro will give you, against the tax you will pay if and only if you write a macro.
- insertcredit 8y agoMost "other" languages don't have Lisp-like macros, so I'm not sure what you are talking about here. I don't think Lisp is much more difficult to like, on the contrary, out of all the languages I know well (C, C++, Python, Java, Common Lisp) not only do I find CL _by far_ the easiest to write but also that it puts me in a state of flow (= unparalleled mental clarity, focus and productivity) which doesn't easily happen with the others. Credentials: I spent close to 10 years writing C++ at Google. I certainly think that Lisp is very different to most popular programming languages today and that difference is immediately obvious. This makes it very easy for people who do not like leaving their comfort zone to dismiss Lisp simply because it "feels" too strange to what they're already familiar with.
- jjnoakes 8y agoThe beauty of lisp-like languages isn't in the visual appearance of the code as text (the parenthesis and layout), but in the structure of the code as trees, the uniformity, and the homoiconicity.
- kazagistar 8y ago- Different from what you are used to does not mean worse. - Structural simplicity. Instead of having a huge mess of syntax to keep track of, it has only a very small number of constructs. Simplicity is beautiful.
- deleted 8y ago[deleted]
- tannhaeuser 8y agoI guess "ycombinator" (a LISP idiom/macro) as subdomain, and the fact that the site code was originally written in LISP, attracts lots of LISPers. I'm personally not a big fan of LISP, much less of the frequent hijacking of threads to degenerate into discussions about sexprs supremacy and other holier-than-though topics.
- fnordsensei 8y agoPresumably, this is because you've looked at Lisp code, but you probably haven't understood Lisp. Criticizing it on the basis of parenthesis would be roughly equivalent to criticizing someone talking about the beauty of mathematics on the basis of the color of the piece of chalk they're using. It's true that it's criticism about aesthetics, but it's not criticism about the aesthetics that the mathematician was talking about. Once you've understood in what sense people mean that Lisp is beautiful, you can disagree, but this disagreement will not concern parentheses. As an aside: I have a similarly shallow aesthetic aversion to JS syntax for the same reason. When I encounter a 12-line ragged cascade of curly brackets, square brackets and parentheses, sprinkled with semicolons, I wonder how that can be considered OK. Aside 2: with Lisp, you edit programs structurally, meaning that their position is essentially managed for you. This is what people refer to when they mean that "the brackets disappear after a while." You're not focusing on them; they're handled by something else. In my editor, I have the closing brackets faded nearly into the background, which reflects how concerned I am about their existence.
- krapp 8y ago>When I encounter a 12-line ragged cascade of curly brackets, square brackets and parentheses, sprinkled with semicolons, I wonder how that can be considered OK. It's considered OK because the extra syntax carries semantic weight, and the semicolons disambiguate intent for the interpreter (because while semicolons are optional in javascript, leaving them out can lead to errors.) And as someone just beginning to play around with (Arc) Lisp, I still can appreciate both paradigms. Neither is objectively wrong.
- deleted 8y ago[deleted]
- 3b9cd7355317f55 8y ago> It's considered OK because the extra syntax carries semantic weight, and the semicolons disambiguate intent for the interpreter (because while semicolons are optional in javascript, leaving them out can lead to errors.) Which is a very roundabout way of saying that JavaScript has a very complicated grammar. Is it necessary? No, it isn't. People use and love languages with much simpler grammars, such as FORTH (reverse Polish notation), APL (monadic and dyadic algebraic notation), and Lisp (fully parenthesized Polish notation).
- taeric 8y agoIn many ways it is the parsimony that is beautiful. There is a ton of syntax in lisp, but there are not as many punctuation requirements. And you get to play with the grammar and many parts of syntax yourself. Contrast this with most other languages, where there are many things the language does that you can not do. At least, not easily.
- lisper 8y ago> the number of parentheses is just mind boggling There aren't actually more parens in a Lisp program than a program written in a C-like syntax (which is really an algol-like syntax). They just stand out more for two reasons: 1. There is less punctuation in general, so the parens are more obvious. Instead of f(x, y, z) you write (f x y z). Without the commas, the parens stand out because that's all that is left. 2. There is only one kind of parens in Lisp whereas C-like languages use at least three: (), [], and {}, so that makes any particular kind of paren less prominent.
- samatman 8y ago3. Lisps optimize tail calls, leading to easier and more efficient recursion. This does tend to increase depth of code. 4. The lisp punctuation style closes all levels on a single line, where most C code guidelines close one level per line. This leads to a "thick" chunk of close parens that students of lisp find harder to read at first.
- beders 8y ago> There is less punctuation in general, so the parens are more obvious. Instead of f(x, y, z) you write (f x y z). Without the commas, the parens stand out because that's all that is left. Well put, Madam/Sir.
- dxhdr 8y agoI believe it's purely seeing lines that end with )))))))) that leads the OP's observation ("To me, how Lisp looks is its worst quality--the number of parentheses is just mind boggling"). You don't get that in a C-like syntax. In practice you don't read each individual closing paren to understand the code so it doesn't matter. But it sure looks "scary."
- lisper 8y ago> You don't get that in a C-like syntax. No, instead you get something like );}]);) except that that's usually split up over several lines. BTW, it's pretty easy to tweak Lisp's syntax so that your parens don't get so deeply nested. See https://github.com/rongarret/tweetnacl/blob/master/ratchet.lisp https://github.com/rongarret/tweetnacl/blob/master/ratchet.l... for an example.
- gmfawcett 8y agoThere's also a historical componenent in all of this. Modern languages have adopted many features from the old Lisps that were quite unique back then. The same is true with the ML language family: between the two, ML and Lisp seeded a new generation of languages that are, on average, much more powerful than the languages in common use in the 1970s and 80s. (Smalltalk deserves a special mention, but it came later.) I'm still fond of Lisp, but languages like Python, D, Nim (and increasingly, Rust) offer a lot of the Lisp affordances that I really valued -- in particular, easy compile-time metaprogramming. The biggest missing bits are Lisp's deeply integrated REPL-driven programming, and the use of program images -- which have many drawbacks but also some benefits. IMO, everyone should write and maintain a medium-sized program in a modern Lisp (SBCL, CCL) at least once, just to get an appreciation for how different the programming / debugging experience is. So many well-integrated tools at your disposal, even at runtime.
- Jach 8y agoYou really just have to dive into it. This image is of Scheme, but the sentiment holds for Common Lisp too: https://www.thejach.com/imgs/lisp_parens.png https://www.thejach.com/imgs/lisp_parens.png
- mcguire 8y agoIf the worst thing you can say about a programming language is that you don't like it's syntax, then it is a pretty damn good language. Lisp (or Scheme, in this case) is a very simple language that gets essentially everything right.
- fasquoika 8y ago>Lisp (or Scheme, in this case) is a very simple language that gets essentially everything right. I have to wonder if you actually know all that much about Scheme. Undelimited continuations, for example, are pretty much strictly broken. I like Scheme, but to claim it's flawless is kinda ridiculous.
- int_19h 8y agoIt's not the only thing people complain about ; merely the first one. And I don't think anyone can seriously claim that Common Lisp is a simple language. Powerful pragmatic languages never are. As far as syntax goes, the proof is in the pudding. All languages have people gripe about some part of their syntax or another, but it's clear from experience that "OMG parentheses" is exceptionally prevalent. Hand-waving it away as something that people just don't get because of lack of prior exposure is not really sound - somehow other languages don't get similar complaints (at least, not as universally, and not to the same magnitude) with first-time users. Besides, why is there a lack of exposure? Why, because everything else is different. But why is it different? Isn't the obvious conclusion that Algol syntax family is vastly more prevalent for the simple reason that people prefer it, and simple homoiconicity is not sufficiently enticing? All arguments in favor of Lisp syntax feel like they ultimately boil down to "you're holding it wrong". And that may well be so - but if so many people are finding it so awkward to hold, isn't that prima facie evidence of ergonomic deficiency? I don't claim to understand why Algol-style is easier. Maybe the way our visual processing works is just better with more varied punctuation? That's something for psychologists and brain scientists and maybe linguists to figure out. But in the meantime, we could at least acknowledge the way things are. I really like Lisp as a collection of ideas (not just the usual ones like HOF and macros, but also stuff like e.g. symbol-based namespacing, or the sheer flexibility of CLOS). But lispers have to ask themselves why, instead of Lisp seeing wider adoption, other languages - that came literally decades later, so "upstart" would be a very polite way to describe them in this context! - become vastly more successful than Lisp by appropriating its cherry-picked features.
- drbojingle 8y agoFrom my short study, I would guess the uniformity and simplicity of it the syntax and the ability to extend it (thanks in part to the uniformity and simplicity of its syntax).
- gumby 8y agoOnce you start using it you don't really see the parentheses, you simply see the atoms and structure. OTOH distinctions like expressions vs statements don't apply -- my years as a lisp developer were the most productive of my life.
- thisiszilff 8y agoThe biggest benefit is that you can keep a very clear model of everything that's going on in the language (well, most things), from parsing to evaluation to application. The parenthesize represent very important things about how the language works and the regularity of the language emphasizes that it's a few basic principles replicated again and again. Also, the "beautiful" lisp variants tend to be in the scheme family. Common lisp is wart and pragmatic by comparison.
- insertcredit 8y agoThere is no difference between Scheme and Common Lisp when it comes to parentheses and beauty. Everything you mention (simplicity, regularity, few basic principles) apply just the same to Common Lisp. The differences between the two are mostly standard library related (irrelevant to matters of beauty) and lisp-1 vs lisp-2 (no clear winner in terms of beauty I would say).
- deleted 8y ago[deleted]
- lixtra 8y agoI’m too young (or studied in the wrong time or place) so my CS teachers failed to impress me to such an extent. However, I very well remember reading the Compilerbau book by N. Wirth and the awe I felt. It’s just a few pages but it was a revelation.
- sures 8y agoCan you share the name of the book? Is it "Compiler Construction" by Niklaus Wirth?
- phoe-krk 8y agoYes - "Compilerbau" from German is literally "building compilers".
- tralarpa 8y agoCheck also his other books: Algorithms and Data Structures, Programming in Oberon, Project Oberon, etc. They are all available on the ETH website and his homepage (in various revisions). Basically everything you need to know about imperative programming on CS bachelor level for free.
- lixtra 8y agoIndeed, a small search yields: https://www.inf.ethz.ch/personal/wirth/ https://www.inf.ethz.ch/personal/wirth/ Also: https://news.ycombinator.com/item?id=10764672 https://news.ycombinator.com/item?id=10764672
- gnulinux 8y agoI'm young too (21), I was taught programming in scheme. In UC Berkeley the very first CS class (called "SICP" lol) is in Python and Scheme. https://cs61a.org/ https://cs61a.org/
- Insanity 8y agoLisp is a fun language to program in. I learned Lisp after already being familiar with Java / Python and some other languages, which maybe made it even more beautiful. One of my favourite pieces of code is a Lisp REPL in Lisp: (defun repl() (loop (print (eval (read)))))
- keymone 8y agolooks even better with threading in imaginary lisp dialect: (-> read eval print loop)
- earenndil 8y agoI think clojure has that; I could be wrong, though, I've never used clojure.
- intertextuality 8y agoClojure does indeed have -> (thread-first), ->> (thread-last), some->, some->>, cond->, and as->. [0] (->) inserts each form's value between the function name & the first argument in the next form. (->>) inserts each form's value as the last argument in the next form. The latter forms are much more niche and I haven't found need for them yet. [0]: https://clojure.org/guides/threading_macros https://clojure.org/guides/threading_macros
- iterati 8y agoas-> is great for when you have to mix thread-first and thread-last. cond-> is great for building maps where some keys might not be needed: (cond-> {:k1 v1} v2 (assoc :k2 v2) ...) some-> and some->> I don't use as often, but when mixing in some java code that could throw an NPE, these will avoid that and just return nil early (they short-circuit when getting a nil value).
- dustingetz 8y ago
- dharmon 8y agoIf this presentation of Lisp and model of computation clicks with you, you owe it to yourself to read Structures and Interpretations of Computer Programs (SICP). The Abelson from the OP's lecture is the co-author, and the presentation described exactly follows the structure of the book (including the derivative example). It opened my eyes to a new way of thinking about coding when I first read it (and worked through the exercises) many years ago.
- krallja 8y agoThere are also SICP video lectures available, from the 80s.
- dmix 8y agoThere's also some newer SICP videos online but the 1980s one is the best and still highly relevant to a programmer from todays era (or any era). I'm self-taught and it's what made me fully "grasp" programming and the power of abstraction.
- avinassh 8y agoDo you have any link to the newer SICP videos
- JJMcJ 8y agoThat book is a miracle of clear presentation. Worth looking at even if you never write a line of Lisp/Scheme in your life.
- justaj 8y agoI've always wondered if recommending SICP would also be applicable to a person who has never programmed before. Perhaps pragmatism aside, would you?
- xyzzyz 8y agoSICP is literally a textbook for programming 101 class. It's whole purpose is to teach programming to people who might have never programmed before.
- GlenTheMachine 8y agoWhen I was in high school I had access to three programming tools: Commodore BASIC, 6502 assembly, and Turbo Pascal. I spent years hand coding 6502 assembly because BASIC was clearly for amateurs and I could only get at the Pascal system at school. At one point I wrote my own Pascal interpreter for the C64. In BASIC, because I wasn't good enough to do it in assembly. It was a little slow. I desperately wish someone had introduced me to lisp. The entire course of my life would have been different. The most frustrating thing is that I probably could have written a naive lisp interpreter in assembly.
- colomon 8y agoI got a Forth for my C64, and it was the PERFECT language for the machine: fast, compact, structured, extensible. Generally much easier to understand the code than C64 Basic, but you could also easily call into assembly language if you needed a bit more speed.
- phoe-krk 8y agoI was impressed first by the fact that whoever designed this particular Lisp system cared about efficiency. This isn't a particularly unusual approach. Common Lisp, a contemporary Lisp dialect, was designed with efficiency in mind. The approach of "Lisp = slow + inefficient + spending 80% of time on garbage collection" is a myth.
- SolarNet 8y agoThis article is set about 20 years prior to common lisp's standardization. It was a reasonable belief then.
- dasmoth 8y agoIt’s set in 1983. “Common LISP The Language” was published in 1984. (The ANSI standard was 1994. Still nowhere near 20 years).
- coldtea 8y agoWell, 10 years is the same order of magnitude as 20.
- lispm 8y agoNot really. If you were at MIT in 1983 then one would have probably access to Maclisp, whose compiler had seen some work by then. The first Scheme implementation was also written in Maclisp.
- ken 8y agoThis comment was regarding TCO, which Common Lisp (unlike Scheme) doesn't guarantee. Many CL compilers today offer it, but IIRC that was rare in the 1980's.
- deckard1 8y agoThere was also a lot of consternation when TCO was formalized as part of R*RS. It's a fundamental part of how Scheme works, so it was obviously necessary. But from a compiler writer point-of-view, it was a rather exotic demand at the time. Though we've moved from a period of languages as defined by a spec to languages defined by implementation. Such as Perl, PHP, Ruby and Python. So what is "normal" has changed a lot.
- n4r9 8y agoIsn't the derivate relatively easy in C? #include <stdio.h> const double delta = 1.0e-6; double cube(double x) { return x * x * x; } double deriv(double (*f)(double), double x) { return (f(x+delta) - f(x)) / delta; } int main() { printf("%f", deriv(&cube, 2)); return 0; } Am I missing something?
- petermcneeley 8y agoI was about to suggest the same thing. This is simply computational finite difference and almost follows directly from the equation https://en.wikipedia.org/wiki/Difference_quotient https://en.wikipedia.org/wiki/Difference_quotient
- mishac 8y agoI think it's that you can calculate the value, but you can't (or can't as easily) create a new function that is the derivative of another function, and pass that around.
- n4r9 8y agoThat makes sense, thanks. And as others have mentioned it's therefore not easy to compose higher order derivatives.
- deleted 8y ago[deleted]
- gameswithgo 8y agoyeah you can return a new function, but it is less easy than in lisp, or F# but in general a lot of that stuff in the article seems mundane today, you have to imagine seeing it in 1983
- omaranto 8y ago> yeah you can return a new function How?
- pweissbrod 8y agoSo the author was excited about the concept of function composition? I'm a fan of lisp but I'm not seeing what's particularly novel about lisp here.
- michaelcampbell 8y agoIt was novel to you when you first saw it, which is what he's describing.
- rpeden 8y agoWell, it was 1983. So seeing something like this in a programming language was more novel than it is now. Also, up to that point the author has only programmed in a couple of different assembly languages, plus Basic. Coming at it from that perspective, there's plenty of novelty to be found in Lisp family languages.
- reikonomusha 8y agoContext is also helpful. “I’m not sure what’s novel about function composition” is a little bit of a smug take on a language and concept that was pretty cutting edge back in the early 80s. Now we Meat-and-Potatoes Programmers know the composition is useful, but I’d be hard pressed to find first-class composition in 1980 in any popular language that wasn’t {academic, Lisp}.
- int_19h 8y agoWas it, though? If I remember correctly, Algol 68 had facilities sufficient to do everything the author describes, and just as neatly.
- aaaaaaaaaab 8y agoNot function composition, but higher-order functions.
- draw_down 8y agoI don’t really agree that doing calculus refutes the idea that lisp programs can be hard to follow, the syntax is kind of a nightmare imo, but a fun read.
- chris_mc 8y agoScheme was my favorite language in school back in 2006, but the only class I ever used it in was a class where we learned search algorithms and the like (it was either AI or Robotics). I was dismayed to find out there isn't a lot of software written in LISP dialects, because I would love to write LISP code all day, it's so much fun.
- void_starer 8y ago> Hal went on to explain how the substitution model of evaluation worked in this example and I carefully watched. It seemed simple. It couldn't be that simple, though, could it? Something must be missing. I had to find out. Well, not that simple... as the author hasn't taken the potential problem of free variable capture into account.
- lunchladydoris 8y agoFor anyone who wants to feel what this might have felt like (and you've yet to watch them), MIT posted videos of Abelson and Sussman presenting the course on YouTube [0]. I felt a similar sense of magic the first time I saw the derivative section. [0] https://www.youtube.com/watch?v=2Op3QLzMgSY https://www.youtube.com/watch?v=2Op3QLzMgSY
- okket 8y agoPrevious discussions: 2017: https://news.ycombinator.com/item?id=14247269 https://news.ycombinator.com/item?id=14247269 (261 comments) 2013: https://news.ycombinator.com/item?id=5375735 https://news.ycombinator.com/item?id=5375735 (176 comments) 2009: https://news.ycombinator.com/item?id=504667 https://news.ycombinator.com/item?id=504667 (39 comments)
- lisper 8y agoThe classics are worth revisiting on a regular basis.
- proaralyst 8y agoI don't think the grandparent is complaining about reposts, merely linking to previous discussions for the curious.
- bruth 8y agoIts a matter of time before there is a "bot" that auto-posts this kind response for historical reference.
- dieterrams 8y agoThere used to be. Not sure what happened to it.
- FPGAhacker 8y agoThere is a link at the top called “past” that does exactly what all these “helpful” posts do. And it’s been there for a long time.
- deleted 8y ago[deleted]
- frozenport 8y agoNot this article again
- moocowtruck 8y agomy question is yes, lisp.. but what is beyond lisp?
- ska 8y agomore lisp :) Joking aside, I think lisp is nearly fundamental in the same way that c is.
- mruts 8y agoMaybe higher kinded types? Monads, Monoids, Functors, etc etc
- gizmo385 8y agoLISP is more akin to a class of languages rather than a single language in isolation, so it is kind of trick to ask what's "beyond" LISP.
- moocowtruck 8y agoif we can solidly say what lisp is, then i'd assume there's beyond the horizon...if we can't say what lisp is.. then whats the point? is it just anything? i mean, if i have a lisp with static types vs not static types, why is the lisp part important at all? and you just have two different languages one with static types and one without? seems very unimportant? i dunno could someone enlighten me
- calebm 8y agoBehind lisp is its creator, behind which is pure truth/mathematics, behind which is the divine creator, who is the ultimate base case: "I am that I am".
- johan_larson 8y agoLisp: gnosticism for programmers.
- QuadrupleA 8y agoAll this could be done easily in C (function pointers, factorial for loop etc.). And sampling a function twice at 0.0001 dx's apart and calling it "doing calculus" is a stretch. The author seems to be making the case that, contrary to his original skepticism, Lisp is indeed some magical higher-order language, but I honestly don't see it. Lisp's ratio of philosophizing to noteworthy projects seems to tend toward infinity.
- jimhefferon 8y agoIt can all be done on a Turing machine. It is a question of tools, and the cultures that build and use those tools, and the interactions between those two things. Like others writing here and like the author of the post I, too, had my imagination fired by SICP and the culture it fits in. When I pick up a Learn to Program book and the examples are managing a used car dealer's inventory, I can only say "Thanks" to Abelson and Sussman. They turned me on to something exciting.
- gameswithgo 8y agomodern c compilers will turn the first example iterative too. but in 1983 this would have seemed magic.;
- pflanze 8y agoMaybe worth noting: when I tested a few years ago at least gcc (don't remember whether I tested clang) only applied TCO to small subprograms. As soon as the iterations were multiply nested and/or across multiple top-level functions (even if all of them in the same compilation unit) it would leave parts of the code still eating stack.
- Jach 8y ago'Peaker pointed out that the GCC optimization involved in the factorial example is actually quite brittle: https://news.ycombinator.com/item?id=15698924 https://news.ycombinator.com/item?id=15698924
- divs1210 8y agoDifferentiation/Integration implementation in Clojure: https://gist.github.com/divs1210/4ca74577711eb996a89a36d86a38ea78 https://gist.github.com/divs1210/4ca74577711eb996a89a36d86a3...
- tombert 8y agoThis isn't identical, but I remember when I first learned first-class functions and partial application in Haskell about ten years ago, it was a "the world is different now" moment. I had reinvented partial-application approximately thirty billion times by using overloading or with elaborate if-elseif-else chains. When I learned Haskell, and saw that I could magically make my non-lists function automatically lift across a list, and how I could define things like this myself, I was immediately convinced that I would never go back to C again (I didn't know about function pointers). I learned Clojure about a year ago (which was my first introduction to Lisp outside of reading SICP), and it gave me a similar feeling. I felt like Clojure was a "better Java than Java", and now its my go-to JVM language. I think McCarthy was really onto something with Lisp :).
- joekunin 8y agoCould you give an example of partial application with Haskell in the way you mention? I've had similar feelings with Clojure.
- QuadrupleA 8y agoMy previous, somewhat-cranky comment got downvoted away, but I do think Lisp's "higher-order magic" and "ability to do calculus" is being a bit exaggerated here. From below - evaluating an Nth derivative in 80s-era C is not so atrocious: #define DX 0.0001 typedef double (*func)(double); double NthDeriv(int n, func f, double x) { if (n == 1) { return (f(x + DX) - f(x)) / DX; } else { return (NthDeriv(n - 1, f, x + DX) - NthDeriv(n - 1, f, x)) / DX; } } double Cube(double x) { return x * x * x; } double result = NthDeriv(3, &Cube, 5.0); As mentioned in previous discussions of this article, the equivalent in Python is pretty elegant: >>> def deriv(f): ... dx = 0.0001 ... def fp(x): ... return (f(x + dx) - f(x)) / dx ... return fp ... >>> cube = lambda x: x**3 >>> deriv(cube)(2.0) 12.000600010022566
- taeric 8y agoSeeing the symbolic derivative is the amazing thing to me. Really highlights the blurring of the lines between data and code. You are correct that the analytic derivative isn't that hard to do in any language. Edit: Should have said "many languages" not just "any"
- taeric 8y agoI put up https://news.ycombinator.com/item?id=18343652 https://news.ycombinator.com/item?id=18343652 to explore a little more of the symbolic derivative fun you can do in lisp. Would love to get feedback on that post.
- omaranto 8y agoThe Scheme and Python versions both return the derivative function. The C version is significantly less cool. I'd want to do something like: func cube_3rd_deriv = NthDeriv(3, &Cube); /* returns a function */ double result = cube_3rd_derive(5.0);
- QuadrupleA 8y agoMaybe not as theoretically cool (doesn't happen at runtime) but isn't this pretty much the same in practice? double Cube3rdDeriv(double x) { return NthDeriv(3, &Cube, x); } &Cube3rdDeriv can now be passed around in a higher-order way.
- ilovecaching 8y agoAny computer scientist worth his salt has read SICP. I had similar reactions as the author of the post to the expressiveness of Lisp, and it set me on a journey towards functional programming that has been so rewarding to my career. I also got a chance to meet some of the people who worked on Lisp machines at MIT, who interacted with Stallman back in the day. The Lisp machines were truly ahead of their time, and Lisp is still as beautiful in its homoiconic glory today as it was back in the 60s. I now focus primarily on Rust, which has given me a lot of the same feelings as when I first encountered Lisp. It's truly a language ahead of its time, and I hope it will continue to grow beyond what even Lisp was able to accomplish.
- rifung 8y agoI feel like I am missing something here but are the things mentioned in the article (tail call recursion, first class functions) unique to LISP? They seem available in other functional languages. I was under the impression LISP was unique due to its macros.
- cnasc 8y agoWhere do you think those languages got those features from? This story appears to take place in the 80s, incidentally.
- Rezhe 8y agoI was working on a webpage for translating SICP lecture, it is always something worth to split out. https://learningsicp.github.io https://learningsicp.github.io
- bribri 8y agoI wish so much that I had known about lisp in college. I only knew Java, C++, Javascript, and Python.