5 ms·
Meh.. I code in Common Lisp at home and Java professionally and I've never understood why people praise the CLOS so much. Like the author says, 99% of the time
by dj_mc_merlin 4y ago
Meh.. I code in Common Lisp at home and Java professionally and I've never understood why people praise the CLOS so much. Like the author says, 99% of the time you don't have a reason to use OOP, and the few times you do you'd prefer to use as little as possible to keep everything sane. It's also one of the few parts of CL which are not optimized well by default, using structs or other basic data structures instead of objects has visible performance benefits in SBCL if you care about that for some reason.
Yes I'm aware of the things you get in CL you don't get in Java: multiple inheritance, defmethod works on arbitrary types by default rather than having to create interfaces, better introspection.. but I don't care. If you're using these features so much there's probably something overly complex with your code to need to do so. Or you're working in such a complex domain you need to, in which case go ahead..
- rosebay 4y agoAgreed. I program in CL and other languages too. I find Java developers tend to have a stronger understanding of OOP and that might be behind your insight. For all its benefits, it feels like at times many CL users miss the point of OOP. CLOS itself is great, however the decoupling of data and methods is something at times I find leads to harder to understand code.
- aidenn0 4y ago> CLOS itself is great, however the decoupling of data and methods is something at times I find leads to harder to understand code. I think that might be familiarity rather than anything fundamental. I often find the coupling of data and methods to lead to harder to understand code; if I want to define a new method on an object in Java, I have to either subclass it or modify the class itself. Even if the method is ancillary to the core functionality of the class. That seems strange to me.
- andrekandre 4y ago> I want to define a new method on an object in Java, I have to either subclass it or modify the class itself. maybe what you are looking for is extension methods? objective-c/swift/kotlin/c# all support them to varying degrees (but sadly not java afaik)
- aidenn0 4y agoYes, those are a huge improvement over the Java/C++ way. I cant tell if in a typical implementation all extension methods share the same namespace though (i.e. if the language has the concept of a "namespace" can one safely define two different extension methods on the same object in two different namespaces; this is trivial in CLOS since methods are not namesepaced to objects in any manner). A quick read of the wikipedia article makes it look like in C# you can do this, but not in Ruby.
- fhd2 4y agoSame. I have quite a bit of OOP background, and I use CLOS, but it's clunky enough (compared to Ruby e.g.) to be a tool of last resort. That said, I mostly work on CL code by myself, maybe CLOS is more useful to large teams, maybe that's where it really shines and why people praise it.
- orthoxerox 4y agoFrom what I know about CLOS, it's a great tool if you have a tight-knit team of seasoned devs, but it's a giant sack of footguns otherwise. You can redefine so much about the object system that your codebase will instantly become unmaintainable.
- pfdietz 4y agoRedefining things about the object system sounds more like MOP than CLOS. The MOP is an extension of CLOS, but it's not part of the Common Lisp standard like CLOS is. If you meant one part of the system redefining things defined in another part, this can be addressed with package locking, if your CL implementation supports that (sbcl does). This is a general problem of lisps, not something specific to CLOS.
- Koshkin 4y ago> rather than having to create interfaces I don’t know about that. To me, interfaces is the best thing since sliced bread, “OOP” or not. In particular, they bring some sanity to the design in the modern C++, where you would use templates in the lower level parts of the application, for performance, and interfaces at the higher level, for sanity.
- deleted 4y ago[deleted]
- deleted 4y ago[deleted]
- TurboHaskal 4y agoYou cannot use Common Lisp without the CLOS. The fact that you can delude yourself into thinking that most of the time you don't have a reason to use it is what makes it so great.
- headhasthoughts 4y agoYou absolutely can use it without CLOS. It was an afterthought poorly bolted on that was worse than its predecessor in most ways as to be portable. It didn't exist when CLtL1 was written and barely existed when CLtL2 was released.
- zasdffaa 4y agoThis "afterthought ... poorly bolted ... worse than its predecessor" is a type of HN comment that's too common. Not being a CLOS or Lisp user, I have no idea why you say this and can learn nothing from it. HN's really starting to put me off with suchlike rife blanket-damning posts that are uninformative and usually come from people who have little experience.
- headhasthoughts 4y agoIt wasn't elaborated on because it wasn't part of the core point of the comment, which was someone claiming falsely that to write Common Lisp you needed to use CLOS, which you absolutely don't. You wouldn't go into why JavaScript is bad to point out that you don't need to write JavaScript to make a web page. You would just note that JavaScript was a late addition to the web and wasn't the first language usable on it. Plenty of people were writing CL before CLOS existed.
- zasdffaa 4y agoThen "You absolutely can use it without CLOS" would have sufficed. You opined in addition on the quality of clos. That could have been very useful if you'd explained it.
- creepycrawler 4y ago
- mikelevins 4y agoI praise CLOS because I've used it quite a bit and I like it. CLOS is an object-system construction kit as much as it is an object system. I generally like to solve problems by building a language in which the solution is simple and straightforward to express, and CLOS provides handy tools for defining data structures and suites of operations on them that facilitate that approach. I also like to work by livecoding, and that sometimes means redefining types that have live instances. If my types are CLOS classes, the Lisp will automatically catch changed definitions and will update existing instances to conform to the new definition. That's awfully helpful in a livecoding context. CLOS has also come in handy when I needed to build novel systems of data types and function dispatch. For example, Ive worked on several knowledge-representation systems over the years, and it's been useful to have CLOS features for constructing novel inheritance schemes, access controls, truth-maintenance, persistence mechanisms, and so on. So I've used CLOS quite a bit over the years. Some tools vex me more every time I have to use them. Others are a greater pleasure to work with each time. In my experience, CLOS has been a tool of the second kind.
- pfdietz 4y agoCLOS is currently slower, but there are some cool ideas floating around to greatly speed it up. The roadblock has been CLOS's dynamism: everything needs to be redefinable at run time, even the classes. But it's possible for an implementation to get high efficiency even with that, using separate code snippets that are reached by a single branch (although I don't know if any CL implementation does this yet): http://metamodular.com/SICL/call-site-optimization.pdf http://metamodular.com/SICL/call-site-optimization.pdf (I think a modern version of Common Lisp would take this idea and run with it, making most or all built-in functions generic.) CLOS really shines when it comes to problems that benefit from method combination, which allows one to decompose computations into reusable nuggets that can be reassembled using multiple inheritance.
- taeric 4y agoI think you have to take the praise in perspective? Go into it with the idea that you want to do OOP, and CLOS is pretty amazing. I agree with you, though, OOP should be something you reach for purposely, not as a default. And, unfortunately, the waters have been so muddied, that I couldn't tell you the best purposes to reach for it. About the best I can see is that it does lend itself well to metaphor, and people communicate almost exclusively in metaphors, when it comes to programming?
- whartung 4y ago> using structs or other basic data structures instead of objects has visible performance benefits in SBCL if you care about that for some reason. Sure, but recall that CLOS really consists of two distinct components. The class/object system, and generic functions. Since CLOS is baked into the CL type system, generic functions will happily dispatch against DEFSTRUCT types (as well as all of the other types, not just objects). Add the ability to :include other DEFSTRUCTS, and the idea that when DEFSTRUCT B :includes DEFSTRUCT A, then the type-of of B is both as a B struct and an A struct, then you get back alley inheritance using structures. So, now (in theory) you get the efficiency of DEFSTRUCT, but all of the dynamic dispatch giddy goodness of DEFMETHOD, when and if you want to use it. It can be a really nice compromise.
- pfdietz 4y agoGeneric functions in Common Lisp dispatch against "all the other classes", not "all the other types". Every class in CL is a type, but not every type is a class.
- jlarocco 4y agoPersonally, I use CLOS all the time and think it's great. Even without defining my own classes, I use multiple dispatch and methods on arbitrary types quite a bit. Admittedly, I don't really use the advanced features like MOP, but I appreciate that they're there and that I can manipulate how the object system works if I ever need to. As far as performance goes, it just hasn't been a problem for me, even when doing graphics and image processing. A pattern that's worked really well is to use OOP to structure and organize everything, and then have the implementation details flushed out with functional or imperative code. It's the best of all worlds. And it's actually a good pattern in most OOP languages because it slows things down in most of them. The vtable in C++, extra GC in Java, object attributes vs. locals in Python, etc. Avoiding objects in performance critical code is just generally a good idea.