Live data from Hacker News

The Liberating Experience of Common Lisp

ds9soft.com

121–126 of 126 posts

Re: The Liberating Experience of Common Lisp

#121
post #93

Earlier quoted context omitted.

The Meta-Object Protocol is optional and not a part of the standard.

It would be far more consistent than the Scala in the example, if everyone used SBCL with the same implementation, right?

I would think that Scala is slightly more object-oriented than Common Lisp, given that one can mostly ignore OOP in some Common Lisp applications. Thus that part already (macros !) makes CL very flexible in expressing different ways of programming. CLOS without MOP has a range of possible use. I haven't thought about how consistent typical code actually is, using CLOS without MOP. My intuition would say that there is some common CLOS style, but maybe that's wrong. It would be an interesting question to look at, how CLOS code bases make use of its features and if they share common architecture principles. Actually there is not that many literature on software engineering principles for CLOS. For example see: "CLOS in Context: The Shape of the Design Space" by Bobrow&Gabriel&White.

https://www.dreamsongs.com/Files/clos-book.pdf

The MOP itself was thought to make CLOS programmable and thus to support a wide range of different object-oriented styles in a single language framework. In practice there is use of that, but it's not that common and actually also a bit complicated/tricky/challenging to program the object system in itself for different behavior.

Re: The Liberating Experience of Common Lisp

#124
post #92

Earlier quoted context omitted.

IMO inheritance is more syntactical QoL than core. That’s just code DRY stuff and composition is fine for that too. The architectural elements of OO are state machine modeling (encapsulation) and message passing.

The Common Lisp Object System does not use message passing .

It does have method dispatching, which is the same beast with a different name.

Re: The Liberating Experience of Common Lisp

#125
post #92

Earlier quoted context omitted.

The Common Lisp Object System does not use message passing .

It does have method dispatching, which is the same beast with a different name.

Message passing means that objects communicate only via messages with some payload. There is a sender and a receiver. Possibly there are many receivers in a broadcast message. Messages will run synchronous or asynchronous. The receiver decides what to do with the message and how to interpret it. If it does not understand the message, it can forward the message via inheritance, delegation or similar. The message implementation belongs to the class and/or object. There is a syntax for sending messages. The mental model of a developer is based on communicating objects.

In Common Lisp the object system uses generic functions, which assemble several related methods. Generic Functions are defined outside (!) of classes and objects. Generic Functions are both CLOS objects and functions. Generic functions are called with one or more arguments. The Generic Function decides which methods are run and in what combination. There is no equivalent to a receiver: CLOS generic functions dispatch over its arguments, all primary arguments. There is no equivalent of a privileged receiver object or a self. There is no special syntax for calling a generic function and they are themselves first class objects, which can be stored and passed around. The mental model of a developer is based on function calling of runtime assembled functions.

Re: The Liberating Experience of Common Lisp

#126
post #52

Lisp really is an eye-opening experience when learning to structure programs and computations. Stumbling on Lisp in college was a fascinating experience for me in particular because I had been raised around C++ and Java, and my programming life up to that point had been a struggle understanding how to abstract a program into objects and how to build those objects' interfaces. Once I started down the path of functiona…

A big piece of OO development is state management. If you're modeling a system having several interacting entities whose interactions may vary based off that entity's current state - then OO is most likely the way to go. You can encapsulate that state management in one place rather than having it strewn throughout the entire codebase. If you're doing information-oriented processing, whether it be a traditional batch…

The classic mistake most programmers made with OO is to translate the business domain objects to classes with behavior. While this allowed for some interesting cases like with Naked Objects, it was usually not the most useful way to analyze a system and encapsulate application functionality.

The better way to employ OOA&D was to divide the system functions up into classes. You have an object that manages connection pools and an object that serializes data, and an object that manages tasks... These were the more useful abstractions, because for business systems we're generally not doing simulation.

The state of the system encapsulated in these objects was the operational state of the stack, not the user state which was just more data to throw around. Abstracted this way, however, you get roughly the same kind of system over and over again. How boring! That way leads to frameworks... Which is also what you saw in the late 90s and early 2000s. It's because for most business applications the abstractions of the system, as opposed to the business domain, are so very close to the same that you can, in fact, codify those into cookie-cutter apps where only the domain data being passed around differs.

Functional programming starts you in this state of abstraction, which is why it tends to be simpler for business systems.

Post reply on HN