4 ms·
I 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 advent
by dkarl 4y ago
I 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.
- kaveh808 4y agoMy gut feeling is that this hasn't been true for a long time, unless you're really implementing a small test. Even then, using CLOS is quicker than deciding that "CDDR" refers to attribute "X". Modern CL is referred to as a multi-paradigm language, and I almost always start a project by starting with "defclass" and "defmethod" like in any OO language.
- dragontamer 4y agoI think this was one of the big differences from Scheme vs CL. Scheme, especially R5RS which is what I played around with the most, was about purity and simplicity. It wasn't really a practical/pragmatic language (though practical Schemes existed, like Racket), it was almost a "group study" in functional programming and greater programming concepts. Common Lisp of course, was a practical/pragmatic language from the start. So of course you use vectors / hash maps / object-oriented programming. ------- That being said, I fondly remember a lot of my scheme code, even if it was a bit quick-and-dirty. Its a paradigm that clearly works for a ton of problems.
- lispm 4y ago> A good, professional programmer probably should: 1. Start with the Lisp-lists as a prototype Don't. Lisp since decades has a lot of different data types which are easy to use: vector/arrays, structures (-> records), classes, etc.
- dreamcompiler 4y agoIn a modern Common Lisp program, using conses for everything is serious code smell. It reeks of a very obsolete Lisp style and it makes code incredibly difficult to maintain. Doesn't matter if you give good names to deeply-nested list accessors; it's still a bad practice. That doesn't mean conses and lists should be prohibited, but any use of conses/lists instead of arrays, CLOS objects, hash tables, or structs needs to be justified. And a programmer's ignorance of those other data structures is not a good enough justification.
- nerdponx 4y agoWasn't this the Clojure approach? You don't need cons cells to have s-expressions and an elegant core set of operations and data structures.
- eyelidlessness 4y agoUnless you have reason to worry about the internals and how they’re implemented (which last I used Clojure is unavoidable for non-trivial code, but I don’t think that’s intended), the data structures should all conceptually desugar to s-expressions. And they certainly do at the reader level. All of the non-list literal types are semantically equivalent to some kind of list representing how their values are defined or generated as a [specialization of] `(seq . …)`.
- CSSer 4y agoI don't think you're alone in this sentiment. I found myself on the wikipedia article for cons and found this witty quip in the Usage in Conversation section[0]: > I sped up the code a bit by putting in side effects instead of having it cons ridiculously. [0]: https://en.wikipedia.org/wiki/Cons#Use_in_conversation https://en.wikipedia.org/wiki/Cons#Use_in_conversation
- eyelidlessness 4y agoIn my experience, this is far less common in Clojure and far from idiomatic. The language’s core data structures and abstractions around them are all[1] based around `seq`, which is conceptually list-like in some respects. But among other distinctions (eg seq is presumed lazy by most APIs), it’s used to back various higher-level data structures, with various map structures in common use. There is an actual list type/structure which more or less works like cons, but it’s generally only used for code structure. I’m sure there’s a lot more that’s not “lisp” about Clojure, but I think this divergence is one of its big strengths. From what I’ve seen, this also seems uncommon in Racket, but I haven’t actually written code in Racket or spent time in the ecosystem, so I can’t say nearly so much about what’s typical with much confidence. 1: Excepting reference types, which are all based around either transactional logic, “transients” which are scope-local mutables, or host VM interop.
- lispm 4y agoIn Clojure programs you'll see a lot more unidentified data (-> maps) than in object-oriented Lisp.
- eyelidlessness 4y agoAs long as it Seqs it doesn’t matter! (Just kidding, this is why I found greener pastures of static types.)
- lispm 4y ago> It's much easier to read code that uses named data structures. That's why a bunch of large Lisp software was written with named data structures in the 70s/80s. They were called class, flavor, structure, frame, ... One can find a lot about that in the literature. Common Lisp was literally the first officially standardized object-oriented language, providing named classes and generic functions as building blocks.