7 ms·
The real elegance of Lisp is that malloc() has been renamed to (cons) and everyone feels smarter about it. I jest a little bit, but that's really the fundament
by dragontamer 4y ago
The real elegance of Lisp is that malloc() has been renamed to (cons) and everyone feels smarter about it.
I jest a little bit, but that's really the fundamental thing about list-processing. For most code, you don't really care about runtime, and you really just need "a data structure that probably can solve the problem", and the (cons) based list of car and cdr solves it.
List processing itself is an elegant technique: a garbage collector tuned for exactly (cons) (2-element "items" that have a car-and-cdr, and the cdr is usually a pointer to another cons), is small, simple, elegant to implement, and works for almost any problem imaginable.
Maybe not as fast as a properly designed specific data-structure, but it will work. On top of that, Lisp has all kinds of shortcuts to make list processing easier to type.
---------
Getting a basic implementation of whatever project you're doing in cars-and-cdrs in (cons) is more important anyway for learning about your problem. Choosing a data-structure too early can hamper your understanding and bias you towards a possibly inefficient solution.
Knuth tries to explain the topic in his "binary trees representation of trees" subject, and notes that pointers to (two pointers) elegantly solves a wide variety of problems. Whether you wanna see them as binary trees, Lisp-lists, or graphs or even collections of malloc'd() nodes, it doesn't really matter. Its the flexibility of this data-structure that is incredible.
EX: the "left" child is "down a level", and the "right" child is "next sibling". Therefore, binary trees can represent any tree, and if allowed to loop, I'm sure the cons / binary tree node can be forced into working with graphs.
- terminalcommand 4y agoNah, I don't agree with this. Lisp is inherently dynamic, there is much more going on than just automatic garbage collection. To achieve the same-level of expressiveness in C you need to craft an interpreter, dynamic memory allocation doesn't cut it. I once wrote a simple linked list library in C to achieve lisp like functions, things got complex very quickly. I still dream of writing a garbage collector for it and evolve it to a lisp like state. Like Greenspun said, I believe any sufficiently complicated C or Fortran program contains an ad hoc, informally-specified, bug-ridden, slow implementation of half of Common Lisp.
- pyinstallwoes 4y agoForth solves this.
- terminalcommand 4y agoForth is still interpreted. Forth's genius is that it's interpreter is so tiny that it fits as a runtime.
- dragontamer 4y agoThere are many lisps that are not interpreted, but are instead compiled. The beauty of the lisp language is that it doesn't care about interpreted vs compiled vs whatever. Its just the true elegance of "everything is a (lisp) list" (which is probably the wrong word. The truth of the matter is that "everything is a graph" and lisp-lists are really just a universal building block that can represent arbitrary graphs). The important gadgets are: 1. Universal garbage collection (allowing you to ignore free() issues and simplify code) 2. Pointer to (two pointers). That is, car-and-cdr. That's it. Everything else flows from these two things.
- terminalcommand 4y agoThat is true, but some sort of a runtime bordering on being an interpreter needs to exist doesn't it. Because my brain cannot comprehend how you can do metaprogramming with macros etc. with static code. My opinion was that the compiled lisps precompile as much as possible (calculations etc.) into assembly and leave bits they can't compile intact, that's what make them fast.
- dragontamer 4y agoMacros just is code that transform a (list) data structure into (another different list), and then feeds (another different list) into the compiler (rather than the original (list) going into the compiler: how things happen without macros). You can see how these things happen in like, Chicken Scheme (R5RS Scheme to C compiler).
- dkarl 4y agoI think building everything out of conses held Lisp back. It was possible, and it was deemed to be elegant, so people went too far with it. YMMV since my adventures with Lisp were around twenty years ago, but reading code, you'd see somebody constructing a list with a bunch of nested lists inside it, or some other complicated structure with conses, and you'd have no idea what it was or how they intended to use it, and you'd just have to read the code until you figured it out. It's much easier to read code that uses named data structures. Of course in Lisp your code can and should have clearly named functions that encapsulate your use of conses to build data structures, but casually violating that encapsulation, or better yet doing without encapsulation at all, just playing with conses, was the cool way to do it, the way you programmed if you had even a little bit of swagger. That was fun as long as feeling smart about the fact that I could do it outweighed feeling annoyed at everyone else doing it, but in the end, the feeling of smartness faded and the feeling of annoyance remained.
- TheMagicHorsey 4y agoI haven't used Lisp in years, but isn't it very easy to just name the list members by defining a structure ... thus making your use/purpose of the list elements quite transparent?
- dragontamer 4y agoIn a lot of Lisp code, people don't bother to use that feature, and instead do a lot of (undocumented (sets of ((lists) that ) have some unknown) undefined structure) I never wrote Lisp code professionally, mostly just as a hobby for myself. It was all just dirty cons/cdr/car code. Given how generic lisp-lists are, they're really free form and could be anything. They are probably "too generic" for a lot of applications, much like XML or JSON is overkill. There's something to be said about writing configuration as .ini files by Python's ConfigParser, for example. Or other simpler files (even .csv files) and working off of that. But Lisp gives you that "power" to have a true hierarchy / language built into your lists. With that power, comes great confusion 3 months later when you forget the structure. ------- A good, professional programmer probably should: 1. Start with the Lisp-lists as a prototype 2. Simplify down to a simpler structure, like vector, or dictionary/HashMap, if possible.