15 ms·
Whoever does not understand Lisp is doomed to reinvent it (2007)
- jfoutz 10y ago(2007) lisp (imho) pushed the limits of what it was possible for a language to do. It pushed in many directions. eval, macros, gc, the comments suggest many things. As computers got faster, it became worthwhile to incorporate more and more of those expensive ideas. Heck, go is billed as a systems language and it's GC'ed! That would be crazy 20 years ago. Perhaps still a little crazy today, but far more feasible. Lisp is like the Simpsons. Lisp did it. (maybe not first, but lisp did it) Of course later languages are going to pull some of that wonderful functionality. Other stuff, like reader macros gets left behind. it's even possible to do pretty explicit typing in lisp, but it never felt as natural as an ML/Miranda/Haskell kind of typing. The C# observation is amusing, the original garbage collector was written in lisp. [1] [1] https://blogs.msdn.microsoft.com/patrick_dussud/2006/11/21/how-it-all-startedaka-the-birth-of-the-clr/ https://blogs.msdn.microsoft.com/patrick_dussud/2006/11/21/h...
- lisper 10y ago> Perhaps still a little crazy today Why?
- jfoutz 10y agoDepends on how you build your application. Small focused processes work great. If you're not careful, and all the functionality gets stuck in one huge executable, it's possible to have long pauses. If that one huge executable winds up interacting with a serial device, like an old printer, or dumb terminal, well buffers are small. data gets lost. you have to resync and it sucks. FWIW, my experience with that stuff is with java perhaps a decade ago. It can all be made to work with smaller heaps, better partitioning, but you wind up introducing more, but bigger buffers. It almost never matters. Right up until you have to read the status from some old microscope, or something equally obscure.
- BinaryIdiot 10y agoRAII is an exceptionally well done memory management model that some languages, like C++ and Rust, use to handle memory and it works exceptionally well. Hell even reference counting in Objective-C is pretty good. Garbage Collection adds a lot of overhead but gives you a good amount of safety and speed in development but you certainly wouldn't want to use it in a scenario that requires something done in real time or many types of embedded systems. Honestly I wish more things embraced RAII. It seems like it would be a better thing to do, in the long run, but that's just my opinion.
- spriggan3 10y ago> go is billed as a systems language When people say "system" they mean "back end" servers and tools. They don't mean kernel programming.
- jfoutz 10y agoI can imagine a webserver that drives a little robot via bluetooth. Low consequence for failure. It's easy to imagine the webserver part of the functionality causing a long pause, and a "stop" message to the robot being late. golang would do a fantastic job at this, i think it would be far more enjoyable than C. Latency almost never matters. But sometimes it matters.
- vortico 10y agoMany people consider Go (and Rust) as a reasonable choice for developing a toy kernel, and some projects have turned out to be somewhat serious.
- vvanders 10y agoGo and Rust aren't in the same domain. Any time you have a GC then you need to talk about pinning, non-determinism and a whole host of other issues. FWIW last time I looked Go doesn't even specify heap vs stack which would be a non-starter for me.
- dualogy 10y ago"When possible, the Go compilers will allocate variables that are local to a function in that function's stack frame. However, if the compiler cannot prove that the variable is not referenced after the function returns, then the compiler must allocate the variable on the garbage-collected heap to avoid dangling pointer errors. Also, if a local variable is very large, it might make more sense to store it on the heap rather than the stack. In the current compilers, if a variable has its address taken, that variable is a candidate for allocation on the heap. However, a basic escape analysis recognizes some cases when such variables will not live past the return from the function and can reside on the stack." https://golang.org/doc/faq#stack_or_heap https://golang.org/doc/faq#stack_or_heap
- groovy2shoes 10y ago> Heck, go is billed as a systems language and it's GC'ed! That would be crazy 20 years ago. Modula-3 was a systems language with GC that was released in the late 80s. It could be disabled for applications that couldn't benefit from it, but in the long run it helped Modula-3 be a much safer language for systems programming than anything with manual memory management. After all, most "systems programs" aren't OS kernels anyway. Even if I were to write an OS in Modula-3, the first thing I'd do is write a real-time GC as an `unsafe` module (possibly mixed with some assembly), then write the rest of the OS such that it can make use of that. Hell, modern machines have so many cores that it might not be crazy to dedicate a core to a concurrent GC. There are also GCs that allow programmers to set a cap on latency, and the GC always ensures that it returns control before the cap is reached [1]. Given the considerable amount of research that has gone into writing operating systems in managed languages (Lisp, Oberon, Haskell, C#, ...), it doesn't seem particularly crazy to me today. Besides, there are plenty of other reasons to dis Go :p [1]: http://www.cesura17.net/~will/Professional/Research/Papers/boundedLatencyGC.pdf http://www.cesura17.net/~will/Professional/Research/Papers/b...
- wiml 10y ago20 years ago, perhaps. But 30 years ago, you could buy workstations that were programmed in Lisp all the way down to the metal: https://en.wikipedia.org/wiki/Symbolics https://en.wikipedia.org/wiki/Symbolics
- pjmlp 10y ago> Heck, go is billed as a systems language and it's GC'ed! That would be crazy 20 years ago. Perhaps still a little crazy today, but far more feasible. Not at all, I was introduced to Native Oberon around 20 years ago. It was a great OS used at ETHZ and many European universities. Specially the system 3 version with its gadgets framework. Around the same time DEC/Compaq had SPIN OS implemented in Modula-3, with POSIX API and a very interesting distributed objects framework. Xerox PARC had the Mesa/Cedar workstation in the early 80's. There were a few OSes implemented with Algol 68 variants that had GC at OS level in the early 70's. The craziness is that in the last 20 years, thanks to the rise of FOSS and its UNIX/C culture, younger generations seem not to bother with everything else that existed.
- lobster_johnson 10y agoJava came out 20 years ago, though.
- josteink 10y ago> Heck, go is billed as a systems language and it's GC'ed! That would be crazy 20 years ago. When your allow the term to mean anything, it's only natural that anything qualifies. The computing world uses the term to describe things you build operating systems and kernels and hardware interfaces with. Google redefined it to mean something you build web apps with ala NodeJS. By that definition, PHP is a systems language too. Basically Go as a systems language is a false claim.
- josteink 10y agoJust to clarify my comment in case it comes off overly negative: I don't think go is a bad language as such. I just think representing it as an alternative to C, a systems language, is misleading.
- wrong_variable 10y ago-- This is prolly the most arrogant opinion I have -- I think if every programmer started using LISP we would have a massive unemployment crisis - since many software engineers would lose their jobs - as most are forced ( due to the nature of capitalism ) to sell snake-oil solutions to problems already solved 50-60 years ago. -- I am not a Lisp programmer , so no accusation on smugness pls. I just ended up using Lisp concepts daily when programming terrible languages since that is what the market wants :) # Resume Driven Development
- biot 10y agoWhat are some examples of problems that are being snake-oiled that were already solved half a century ago?
- kuschku 10y agoA lot of things currently done in the javascript world are just people discovering that the "just copy all code into a file" world of things doesn’t work – and so they reinvented modules, after the "kik" debacle, now reinvent namespaces, they reinvent dependency management, etc. Just look at the javascript world, they have enough examples.
- jonathankoren 10y agoThis. JavaScript's engineering culture is a dumpster fire of 40 year old bad ideas that the rest of the software community abandoned 40 years ago.
- neoeldex 10y agoIt is a language in a constant changing environment. The web today has different requirements than 20 years ago. It's not right to criticize the reimplementation of things in different systems. That has to happen... Paradigms shift, so thus do implementations
- 10y ago
- tempodox 10y agoReminds me of Greenspun's Tenth Rule Of Programming: Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of CommonLisp.
- mamon 10y agoReverse is also true: Any sufficiently complicated Lisp program will contain an ad-hoc, bug-ridden and slow implementation of half of mainstream programming languages and their standard libraries.
- ryanackley 10y agoI only programmed in LISP for a semester of grad school for an AI class. My impression: it's a programming language with a unique perspective. Did I find it to be the programming language of the gods? No. Sometimes I find myself with a problem where I find myself wishing I was programming in LISP. Does this happen every day, every week, every month? No. More like once every couple of years.
- preordained 10y agoI know Haskell pretty well, having spent a cozy two or three years with it as my main squeeze for hobbyist programming. Now I'm doing more Prolog. I like stuff that makes me think differently. Anyhow...is there something I'm missing from Lisp? I've never Lisp'd, but people talk like it turns you into Neo in the matrix.
- rtpg 10y agoI think Lisp is kind of magical if you buy into the iterative nature of computing. Sure, it's functional in the sense that functions are cheap and easy to declare/use as values, but if you look at how things like macros end up working, it ends up being about having control of your runtime. If you're into Haskell/Prolog, you probably are much more on the mathematical side of things... honestly I can't think of much you can express easily in Lisp (CL for example) that you cannot transform into an almost equivalent solution in Haskell. It's good to try out a Lisp (and get up to macros or something), but my personal feeling is that Lisp is probably more of an advancement for people in the dynamic language universe (JS/Ruby) than it is for people in the ML-y languages.
- ACow_Adonis 10y agoThe "Neo in the matrix" thing, i think, is the "lisp enlightenment experience" under another name. Trying not to be some smug lisp weenie about it, I'm going to try to put my own experience into normal english. It happened for me somewhere around the 6-12 month mark of daily lisp study/coding. You usually start out learning lisp like other languages: you're just trying to learn the syntax of various commands and the quirks of how everything fits together of the concepts (if you've learnt another language) that you probably already know. And a big part of this is laying the foundation of a deep understanding of linked lists, cons cells, cars and cdrs. And after that, you start learning about the identation style available to you as well. And right now, its just another language. Then one day, you wake up, and you look at code, and some switch you weren't even aware of has flicked in your brain, and it all looks different. Mature lispers read/structure code subconsciously using both symbols and the indentation style to convey real information about the structure of a program, which is why you can really mess with their heads if you mess yours up too much. But there's a difference between being told you can do it this way, and the practice that actually makes you do it, because its not a conscious thing. Anyway, the reason lispers "think they're neo in the matrix" is because the mental effect this has on you is not unlike that scene towards the end of the matrix where Neo looks down the hallway and his perception of the thing he's been interacting with this entire time just fundamentally changes. Its no longer writing code, that is to say, strings of text. Its interacting with and perceiving the very structure of the programs themselves. And it is a real psychological phenomenon. It makes you really happy, and its why lispers talk about it. It makes you want to go and shake your neighbour and be all like "Oh my god, I get it, do you see this!"...and of course they don't. They see scribbles on the screen. The funny thing is, they always say they're Neo in the matrix, which i understand is cooler, partly because that final scene captures the phenomenon of what it feels like, but its arguably summed up in a more lackadaisical way by the character Cypher in one of his quotes from the same movie: "You get used to it, though. Your brain does the translating. I don't even see the code. All I see is blonde, brunette, redhead. Hey uh, you want a drink?"
- hacker_9 10y agoIt doesn't matter what you say about Lisp, there will always be people on HN who vigorously defend it to their last dying breathe it seems. The idea of a language not being (one(definition(after(another)))) seems foreign to these people, as if making everything a function call solves all problems (or maybe, that is what the HN crowd really believe?). If only programming problems could be solved by lots of functions calls!! The truth is the difficulty exists in the solving of problems, not how many functions you define. If someone thinks you re-invented Lisp at some point, then either they do not understand the problem or they fail to understand the solution.. or of course; they do not care what you have written and instead think you have not used enough parenthesis.
- noctuid 10y ago> as if making everything a function call solves all problems There are also special forms and macros. > not how many functions you define I've never seen anyone argue that this is what makes lisp good.
- NotRustAgain 10y agoThere are several things you could take away from Lisp. I don't think you caught the good parts yet though. My idiot instructor for comparative programming languages set me back years in understanding the cool parts of Lisp. He focused on "List Processing", which seemed pointless to me because lots of languages have lists... (I work with him now, so I'm allowed to call him an idiot) You seem to think it's about the function calls. Maybe you had a bad instructor too, and he focused on "functional programming", which is all the rage for the last decade. I dunno, maybe you came to that conclusion on your own. The thing I now think is wonderful about Lisp (Scheme for me), is that you can write your program however you want. If you want to use switch statements, and your language doesn't have one (Python), just make your own: (switch foo (case bar -> (do whatever you want)) (case hmm -> (do something else))) Some languages have backtracking: (backtrack (keep trying) (different things) (until it works)) You just can't add those kinds of features to most languages because most languages are not programmable...
- TeMPOraL 10y ago
- MrBra 10y agoCut me some slack!
- hasenj 10y agoThere's one thing severely lacking in lisp: compile time type checking! IMO Haskell has the best typing system I've seen in a language so far. TypeScript is probably a close second (it kinda has to be as flexible and powerful as possible, to accommodate as much existing javascript code as possible).
- Jach 10y agoCommon Lisp supports compile time type checking: https://news.ycombinator.com/item?id=11529039 https://news.ycombinator.com/item?id=11529039 Have you seen Shen? http://shenlanguage.org/ http://shenlanguage.org/
- wtbob 10y ago> There's one thing severely lacking in lisp: compile time type checking! Lisp does have compile-time type checking; see my comment: https://news.ycombinator.com/item?id=11699581 https://news.ycombinator.com/item?id=11699581
- TeMPOraL 10y agoBut (Common) Lisp does have compile-time type checking, and uses it to great success for both ensuring programming safety and generating optimized code comparable in efficiency to C! That said, I agree the CL's type system is nowhere near as good as Haskell's.
- maxpert 10y agoI don't get it. If LISP is such an EPIC language why are there no major pushes from LISP community, or just showcase a piece of software that proves it. I have been looking on internet about what makes LISP cool it's ideas about code is data, powerful macros and hell lot of bragging about being able to define your own syntactic sugar but can't find a single MUST HAVE piece of code that makes me say "I have to learn this". It's a ML age now and developers around the world are looking for such gems, but I don't see LISP picking up momentum (I did notice Erlang picking up momentum upto the point people feeling crappy about syntax invented Elixir).
- deleted 10y ago[deleted]
- dschiptsov 10y agoThe piece of code is called Open Genera and it is available from pirates. Some sources and excellent documentation are on the bitkeeper. There is also the MIT Scheme, as seen on TV in the Wizards Lectures (1986 Abelson & Sussman SICP lectures). BTW, the guys who designed and developed early lisps, up to 80s, were bright people heavily influenced by discoveries of "modern science" of the time, which were genome and protein structures, basics of cell biology, signaling pathways, early genome sequencing techniques etc. Their designs has been based on right principles. Erlang is another example. Another obviously successful project is called (surprise, surprise!) GNU Emacs. Non surprisingly it is a continuum of early emacses, such as Zmacs. Recently, Eitaro Fukamachi (a true hero, in my opinion) have bootstrapped a few remarkable projects, which should mark the beginning of the Common Lisp renaissance, but these projects also went unnoticed by packers. Why Clack when we have PHP or Java Server Faces? As for Erlang syntax - the pattern-matching on receive with variable binding for simple, terms-based protocols is, again, too good for mediocrity to grasp {ok, Val} | {error Why} etc.
- incepted 10y agoYou're doing some major revisionism with this post and claiming a lot of completely unsubstantiated (and in my opinion, completely made up) facts. I don't think Gosling, Stallman or Armstrong ever mentioned any basis in genetic science to justify their language. And seriously, think about it... It's completely absurd. I'm also not sure why you think that returning error codes is "too good for mediocrity to grasp", because in the 21st century, it's considered a very bad practice that leads to extremely unsafe coding practices, which is one of the many reasons why it's been deprecated in most modern languages invented in this century (except Go ;-)).
- jdmichal 10y agoSee also the Lisp Curse: http://www.winestockwebdesign.com/Essays/Lisp_Curse.html http://www.winestockwebdesign.com/Essays/Lisp_Curse.html https://news.ycombinator.com/item?id=11174946 https://news.ycombinator.com/item?id=11174946
- dschiptsov 10y agoEverything has been said by Richard Gabriel long ago - Lisp is too good, and "packers" don't need or even appreciate refinement and excellence, like most of folks don't appreciate beauty of DNA and related machinery. For them PHP or Java are tools for getting shit done. There are huge piles they have produced, like Hadoop or whatever it is. The last great Lisp was ZetaLisp from Symbolics (just read the docs!). Common Lisp is already a bloatware suffered from the kitchen sink syndrome, nevertheless it is way better than anything else (multi-paradigm, mostly functional, strongly-typed (type-safe enough) meta-language that compiles to native code with pattern-matching, OO and other fancies as DSLs). But who cares if one is satisfied with writing RepetitiveStupidityFactory myStupidityFactory = new RepetiriveStupidityFactory; for living.
- incepted 10y ago> For them PHP or Java are tools for getting shit done. ... as opposed to Lisp?
- dschiptsov 10y agoYes, Lisp is a distinct, different culture (think of Aryans versus tribes in ancient India). The difference is as it is between craftsmen (who are artists) and assembly-line workers. Look, read Gabriel or Graham or early Norvig (his Lisp style and anti-design-patterns essay), not me. There is something behind their insights.
- pka 10y agoYea, understanding macros and writing your own DSLs doesn't make you some sort of aryan ubermensch programming craftsman. Macros really aren't that hard to get, and mostly not necessary when you have more coherent constructs at your disposal.
- sklogic 10y agoYes, macros are not hard to get - they're far simpler than anything else imaginable. No, they are necessary. There is no better way of doing things than macros.
- pg_is_a_butt 10y ago(((((i((((('(((l)))l)((((((be(())l((((()))))ieve((((it)(w(((()))))))((()()he((()))))))))n(((()()))(urdum
- dkarapetyan 10y agoOne of the comments nails it on the head (paraphrasing a little bit): lisp is the executable implementation of lambda calculus. So of course you will re-invent it. As much as any domain at some point takes on a computational flavor the closer it gets to having primitives that can be used to build a turing machine the closer it gets to being a lisp. That and having your computation being representable as a data structure comes in handy pretty frequently so you end up emulating lisp even if you didn't intend to because the data/computation duality is ever-present. None of this is an endorsement of lisp though since there is a very deep and fundamental reason that it keeps being re-invented. Lisp is the manifestation of the primordial soup of computation.
- zaro 10y agoMy feeling when using lisp is I am writing an AST . And since most languages rely on generating AST it kind of makes sense to reinvent it.
- KayEss 10y agoAnd the rest of us are doomed to keep re-implementing it.
- lucidguppy 10y agoI think lisp adds mental overhead for figuring out the precedence of operations - while other languages have a default that people understand. Perhaps if a lisp editor was 3d instead of just parenthetically topographic (not just color coded) it may help people understand what is happening.
- ldjb 10y agoIt's perhaps a little confusing when first learning Lisp, but once you've got the hang of things, working out the precedence of operations is really easy. In most programming languages with infix operators, the precedence often depends on the operators themselves. For example, with: 5 + 3 * 10 ...You'd need to know that * has higher precedence than + to figure out the value of this expression is 35, not 80. But with the following Lisp expression: (+ 5 (* 3 10)) ...The syntax itself tells you the precedence, so there's no ambiguity. Even if you didn't know anything about the functions involved: (bar 5 (foo 3 10)) ...You don't need to worry about whether foo has precedence over bar or the other way round -- there's only one way to evaulate the expression.
- TeMPOraL 10y ago> I think lisp adds mental overhead for figuring out the precedence of operations - while other languages have a default that people understand. Wait what? Lisp removes the mental overhead by not needing the concept of "operation precedence" - prefix notation is unambiguous. The discomfort people have when looking at prefix math is because everyone here spent at least a decade being taught math in infix notation.
- awt 10y agoI implore everyone here to read Naggum: http://xach.com/naggum/articles/ http://xach.com/naggum/articles/ Also read Stanislav Datskovskiy: http://xach.com/naggum/articles/ http://xach.com/naggum/articles/ Also consider that the x86 hardware platform is terminally busted. For god's sake why isn't gc in hardware already?
- todd8 10y agoThe "Lisp" programming language covers a large territory, and often one needs to embed some sort of interpreter or language is a complex system. (Even our text editors contain sophisticated interpreters because we desire to customize them to such an extent.) Furthermore, a Lisp model is one of the simplest ways to build a powerful interpreter. Consider the problem of being locked in a room that has a computer and all the manuals you need to program it...in machine language. How would you build a system of any significance? Could you escape the evil genie that won't release you until you write a program that solves Sudoku puzzles? I know that I would escape the genie. I'd build a simple macro system and key it into the machine in binary (I've had to patch a machine's boot loader more than once from a panel of switches). Then I'd build a simple assembler from the macro system. After that, I'd build a simple lisp-like system because that's about the simplest language one can implement that does anything interesting, including writing a sudoku solver. So yes, I'd be reinventing Lisp. However, I don't want to spend my life programming in some shitty pathetic system I wrote to escape from an evil genie. Why does it matter that Lisp is so easy to implement that undergrads often build Lisp systems as programming assignments? That doesn't make it some language of the future invented in the past; it just a simple to implement language invented in the past. A thread I've seen here before is "well Algol 68 was a great language and we are not using it because ...<insert some conspiratorial reason>..." Well, Algol 68 is a great language from the past, but it's great not because it's a great language to program in--it's great because it manifested some of the earliest thinking about what features ought to drive the design of programming languages. Today, people aren't locked up and given terrible programming assignments with no real programming language to use (well...maybe I should say this doesn't happen all that often). So why not just embed Lua. Places that I would have used Lisp 40 years ago are now the places I'd use Python or Ruby. But what about the meta-object protocol? What about programs that need to write other programs? What about DSL's? Well, that's another subject. But the short answer is so what? These step up the power of the language one programs in, but not essentially the limits to what a program in your language is capable of doing. Yes, writing complex data structures in old FORTRAN is a big pain, but we aren't in that arena anymore. Writing complex data structures in C++ or Java or Go or Rust isn't a big pain anymore.
- todd8 10y agoOkay, well "What about homoiconicity?" you say? Well, I think it's a totally cool sounding word that all hipster programmers need to have ready to pull out, but it isn't a game changer for Lisp. Or I should say, that yes it has kept Lisp in the game, because without it Lisp would be like FORTRAN IV, a language that didn't have enough useful stuff (fixed size arrays of numbers was pretty much all there was to program with in early FORTRAN), but it doesn't make Lisp "better" than more modern languages. Homoiconicity means that the the abstract syntax of the language can be represented easily in the programming language itself. Just the fact that Python is written in text and can easily represent and manipulate text doesn't count. Because of homoiconicity Lisp can do amazing things to itself, see [1] and [2]. Python programs aren't commonly producing another python program to feed to the python interpreter. However, Python makes the the AST available as a python construct. Go does something similar. So yes, python and go could support the Metaobject protocol if they wanted to. The important thing observation is that Python and Go programmers don't want to and don't need to. These languages already provide powerful enough abstractions to support 99% of a programmer's needs: object, classes, interfaces, lambdas and so forth. "Well, yeah, but ithout homoiconicity how do you construct a good DSL?" I presume that you mean how can you implement something like CLOS? Really? I don't want to implement CLOS and I also don't want to write the Boost library for C++. Both are complex exercises in programming to extend the capabilities of the underlying language. Why wallow in macros (again see [2]) or templates (see Boost source)? I understand that C++ templates solve an essential problem that the language has: original compatibility with C and a desire to be able to operate as close to the metal as C. Likewise, Lisp originally lacked even a decent set of control constructs. High powered macros (and call/cc for Scheme) allowed the languages to build there own extensions just as templates have for C++. Other language just start with a good set of abstractions, control abstractions (like Java's enhanced for loop), data abstractions like interfaces, concurrency abstractions like go's channels. "Yeah, well like man, how can you anticipate exactly what the program needs?". Well, I've found higher level programming with functional languages and object oriented languages to provide almost all my needs. "Well, DSLs make programming so obvious. You end up programming so much closer to the problem domain?" Yes, that's true. I find that DSL's and even macros helpful in configuration files, for example in a 3000 line Emacs configuration file. I use John Wiggle's use-package macro extensively to simplify my Emacs init.el file. My problems with macros as a fundamental organizational abstraction for programming-in-the-large are worth a separate post (it has to do with hidden semantics and the difficulty in even informally reasoning about the correctness of programs written using macros). [1] https://en.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol https://en.wikipedia.org/wiki/The_Art_of_the_Metaobject_Prot... [2] http://letoverlambda.com http://letoverlambda.com