Object Oriented Programming really an Advantage

1) May be it is a SLAC report?
No, it's a book: small, bound, available in book stores. But you made me look in the high energy physics search engine (now known as INSPIRE, it used to be SPIRES), and while I find lots of publications about related topics (SPEAR, SSRL, accelerator control, control system programming ...), none about objects, and none with a name that rings a bell. And I know that I was never a co-author on any paper with the author of the book ... one of the things that ended my career at SLAC was that I had no interest in what is called "machine physics", the art and science of building and operating accelerators. I was always an instrumentation and data analysis person.

I'll keep looking.
 
That’s what Ivan Čukić is preaching 😉
At the lowest level, isn't OOP functional? Object methods that implement something like read a register, increment a value, I think is fundamentally "functional".
I've found thinking in OOP lets me deconstruct/derive the overall requirements, regardless of how the code is actually written.
 
I’m such a dinosaur.
I use a class for encapsulation but never used inheritance. No need.
I've found it depends highly on the problem you are solving.
Having the knowledge to know when "not to" do something is as important as knowing "when to".

I've seen stuff at $JOB where a class needed a timer but someone wrote it as "inheriting from a timer". Ok, not so bad, but then "class needs timer of type A and timer of type B so multiple inheritance from A and B. Oh and since the timer classes have the same method names like start, stop, how do I make sure which inherited start I am calling or overriding"
Yeah stupid stuff.
 
There are interfaces to avoid mulitple inherintance.
Same problem. Timer X is an interface that uses methods start() and stop(). Timer Y uses methods start() and stop(). If class A wants to "implement interfaces" X and Y, the resulting code will be difficult to read, since every time start() or stop() are used it needs to be disambiguated.

In this case, it's just easier for class A to contain two timer objects, instead of inheriting from them, or implementing them.
 
I always got lost in stuff like 'inheritance polymorphism' and when it's possible to override a method or variable that was inherited from a parent class and when it's not. Sometimes I'd get compiler errors because I tried to override a variable that was declared 'private static void'... 🤪
 
Same problem. Timer X is an interface that uses methods start() and stop(). Timer Y uses methods start() and stop(). If class A wants to "implement interfaces" X and Y, the resulting code will be difficult to read, since every time start() or stop() are used it needs to be disambiguated.

In this case, it's just easier for class A to contain two timer objects, instead of inheriting from them, or implementing them.

When to subclass vs when to instantiate traits is a major field of discussion in OO programming. Never let either path become your religious dogma. I've been on the fence for years about whether multiple inheritence should be allowed. I rarely end up using it, and some languages don't allow it at all.

But yes, some classes scream "inherit me" but the practicality of doing so leads one down the rabbit hole. Timers and Threads are such beasts.
 
NOTE: I haven't gotten a chance to read all the messages in this thread just yet.
For fun, object orientation with sbcl,

Interesting!

Although not good at reading Lisp and all the dialects (I did do quite a bit in a CAD lisp dialect and some Scheme) it looks as though 'balance' is accessible by any procedure. The typical OOP bank account operations are "withdraw" and "deposit", whereas 'balance' is a local state to the account object itself and not an object (this is where the fun begins). If you start coding up a way for the account to keep track of the 'balance', management of the account becomes easier and more "black-box-ish" and you may see what I mean.

Also, note; what I find interesting with the "message passing" aspect of OOP is how easy it is to NOT account for unknown methods (aside from the obvious design implications--how functions are implemented--in a 'message passing' methodology). -i.e. In the typical "function" method you typically just don't code up the unsupported methods. However, I think the "functions as return" method is a bit more elegant because you can just create a wrapper function (with the use of a simple COND in this lisp case) which acts an API of sorts for your object -i.e. ship the wrapper function and another programmer knows how to use your object.

The object (account) is shown below as a list:
Code:
;; functions returned as messages
(define w1 100)
> (w1 . 100)
((w1 'withdraw) 50)
> (w1 . 50)
((w1 'withdraw) 75)
> "Insufficient funds"

;; functions only
(define w2 100)
> (w2 . 100)
(make-deposit 20 w2)
> (w2 . 120)
(make-withdraw 150 w2)
> "Insufficient funds"
 
When to subclass vs when to instantiate traits is a major field of discussion in OO programming. Never let either path become your religious dogma.
Totally agree with your second sentence. I would even like to generalize it to become the single most important religious dogma in software engineering: #0 THERE ARE NOT RELIGIOUS DOGMAS IN SOFTWARE ENGINEERING. Always do what is appropriate for the situation. That means the problem domain, the performance characteristics (speeds and feeds), the deployment situation (quick prototype versus architecture that needs to survive for decades), the strength, size and weaknesses of the team, and so on. And all of these decisions are tradeoffs, in which different people (of different experiences, different ways to looking at questions, different strengths) can disagree on.

Probably the single most important thing in software engineering is the ability for humans to communicate, to argue, to illuminate all sides of a problem or question, and to come to a conclusion and synthesis. This is much more important than which language to use, or whether to inherit or include.

I've been on the fence for years about whether multiple inheritence should be allowed.
On that question, I happen to sit on the comfortable and wide railing on top of the fence. I find many situations where MI is useful. But the tradeoff is that MI adds complexity, in how to think about the source code. Say class X has two base classes, A and B. What if both A and B define a method foo(), which one will be called? What if both A and B derive eventually from a common origin class O, and perhaps O also has foo(), now which one will be called? If EVERYONE involved in the team that implements AND MAINTAINS the source code knows how to answer the question, and understands why we (together, after consultation) chose to implement X to inherit from both A and B, then none of this is a problem. In the real world, it is difficult to maintain that invariant. I would love to put into the source code the following lines:
Code:
assert(programer is skilled);
assert(programmer understands OO A&D);
assert(programmer has learned how MI works);
test_score = perform(give programmer quiz on MI);
assert(test_score > 0.8);
class X: public A, public B (
...
 
ralphbsz
My only two comments that deviate would be:
1) to me the most important thing in engineering is elegance of solution.
2) there are too many people in software engineering that should not be...I'm of the crap or get off the pot school. I cannot stand dumbing down paradigms so that those who "got into SE to make money" instead of "got into SE because I'm a gifted nerd" can understand it.

If your team standards are dumbing things down then you need a new team. LOL My dream is to manage a skunkworks R&D group where I encourage each team member to become a subject matter expert in at least one discipline, and there is cross training and information sharing to raise the group capabilities above the sum of our individual contributions. But always keeping in mind the common principle that you and I both share: that the system goals dicate the paradigms and conventions use. You don't make the task fit the programming paradigm you use, you use the paradigm that fits the task.

One of my pet peaves in C++ was lambdas (anonymous functions). When they were added to the standard the kiddies went ape $h1te trying to figure out how to leverage them into EVERYTHING...and I saw red, very quickly.
 
If you are interested in Lisp and OO, I recommend reading or at least scanning through "The Art of the Metaobject Protocol". If not that, at least read this review of the book (more a meditation on OO and many other things) by Richard Gabriel: https://www.dreamsongs.com/Files/amop-review.pdf

From the above:
Though object-oriented programming was developed outside the world of AI, Lisp and AI-influenced researchers added some of the more interesting recent concepts to object-oriented programming: multiple inheritance, method combination, metaclasses, and now the metaobject protocol.
 
If you are interested in Lisp and OO, I recommend reading or at least scanning through "The Art of the Metaobject Protocol". If not that, at least read this review of the book (more a meditation on OO and many other things) by Richard Gabriel: https://www.dreamsongs.com/Files/amop-review.pdf

From the above:

Also worth noting that Lisp, the programmable programming language, was able to implement the equivalent step from C to C++ without compiler changes. The existing flexible syntax was sufficient for CLOS and several other OO extensions.
 
An alternative to clos , ie racket,

Code:
#lang racket
(define counter%
    (class object%
        (super-new)
        (init-field x)
        (define/public (setx x2)
            (new this% [x x2]))
        (define/public (add1)
            (new this% [x (+ x 1)]))
        (define/public (getx)
            x )))
(define c (new counter% (x 3)))
(set! c (send c setx 5))
(set! c (send c add1))
(define res (send c getx))
(print res)
 
Back
Top