# Object Orientation

While Phix optionally supports object orientation in the form of structs and classes, I have personally never been a fan, but struggled to pinpoint exactly why. This mini-rant expresses my thoughts, but can safely be skipped on first reading. There are certainly some neat ideas in that paradigm, and it is possible to write beautiful object oriented code, just as it is in any other paradigm, but the reality often falls far short. The main reason is probably meaningless abstraction, but a far bigger issue arises from the one thing object orientation actually achieves: managing complexity. It sounds like a wonderful thing, but all too often it enables complexity, and actually actively encourages complexity.
Of course many things are complex, and it is the programmers job to break things down into small manageable pieces, and OO does a fine job of that, it is the reassembly into a comprehensible whole where things go askew. Delegation and redirection can be useful and powerful tools, but they can be taken too far. Should you want to royally confuse yourself, try downloading the IUP sources and figuring out how it implements something, so you can add it to xpGUI. Personally I simply prefer a single albeit slightly messy printme() that handles everything, rather than 243 scattered but trivial (or trivial but scattered) printme(), probably because it is all too easy to end up trying to debug or modify the wrong one, and/or having to make the exact same changes to all of them, but perhaps because properly documenting all 243 of them would at best be rather tedious, assuming the 242 copy/pasted heredocs don’t somehow magically update themselves.
One thing Phix quite beligerently prohibits is selectively overidding the builtins, making it quite difficult to write code that looks like it is doing something else entirely, which (imo) the unwashed oop-infected often seem so fond of. I guess I just don’t "get" any comfort at all from code looking familiar, and in fact get quite disturbed by it being deliberately misleading.
Don’t get me wrong: there are many good things anyone can learn from studying OO. The core idea of "encapsulate what varies" is a mighty fine one, but to me that is just a really good approach to sensible refactoring. Smaller more managable pieces are almost always much better (just not 243 near-duplicates). I would often even accept trusting your testing without always fully considering every detail. Conversely, there are times when you really should consider every tiny little detail, in my view OO is a serious hindrance in that regard. There are often some benefits in adopting some of the strategies advocated for the otherwise (having once endured a situation where fixing even a blatent bug was prohibited, I feel quite justified in saying this) absurd and pathetic open-closed principle, but (for instance) instance specific methods can be implemented even in raw assembly as function pointers, and quite trivially at that. My main objection to OCP is that it enforces a timidly terrified attitude to modifying code, presumably due to inadequate testing and more importantly it being too difficult to track down and fix bugs, and of course since OO is just so gosh darn wonderful, there will simply never be any reason or attempt to improve that.
Limiting potential damage to one (new) component might be reasonably sensible, but decreeing each bugfix be applied in a forever-increasing number of different places is nothing short of sheer stupidity. Just to be crystal clear, several highly respected sources actually advocate "regularly break OCP", but I am simply never going to have any respect for the "never ever violate OCP, no matter what" mob, even and perhaps especially when they happen to be paying my wages. The idea that OCP enables the use of buggy third party libraries without actually modifying them is a whimsical academic notion that, at least in my experience, in the real world and in any given calendar year manifests itself on average a round number of times, and to the best of my knowledge there has never been a documented instance where such a serendipitous event even had a chance to happen.
The SRP is just imo "divide and conquer" or "keep it simple" rephrased, and often over-applied to the point of ridiculous insanity.
Unit tests are of course a great idea, as is any form of testing up to and including system-wide, but not even slightly OO-only.
Refactoring is a pretty useful general skill to have, but of course with no connection to or dependency on OO whatsoever.
Polymorphism is very useful, but entirely independent of OO (and simply done better in Phix, imo).
Encapsulation is an absolute must-have in any paradigm, but again in no way whatsoever exclusive to OO.
According to Uncle Bob, plain C had perfect encapsulation, and every OO language weakens encapsulation. (no comment on that from me)
Inheritance in fact interferes with more explicit code re-use, and I proudly possess an absolutely unshakeable belief that Koenig lookup just makes maintenance much more difficult, especially when it conflicts with inheritance.
Thankfully there is just no need for that in Phix, as evidenced by it having just the one sq_add(), rather than ([u]short/[u]int/[u]long[long]/float/double,<ditto>) before even starting on sequence-variants.
Of course I know all about favor composition over inheritance, but apart from implicitly dragging in code as well as data, there is nothing remotely exclusive to the OO paradigm regarding composite data structures. Clearly intellisense is pretty nifty, and in many ways even more useful in an OO context, only cos that really needs it, but not in any way essentially tied to it either.
In fact, I rather suspect almost everyone actually actively dislikes object orientation, what they’re in love with is intellisense.
Some bits of advice are certainly worth keeping, especially some of these gems from Kent Beck (and I am sure there are more):

- First make the change easy (warning: this may be hard), then make the easy change.
- If I want to make my code cheap, I should make it easy to read.
- Designs without duplication tend to be easy to change.
- Then again, he also said: Actually this book is built on a rather fragile premise: that good code matters. I have seen too much ugly code make too much money to believe that quality of code is either necessary or sufficient for commercial success or widespread use.

I was once rather taken by All the Little Things by Sandi Metz and would (still) highly recommend investing 40 mins in watching that. I walked away from that feeling frankly rather relieved that I had finally found out why object orientation is a good idea, but that only lasted for all of about 17 minutes, before writing something simply better. The main message is "how to make it work", the not so subtle secondary message is "you are not supposed to understand how it works". The really arrogant part, not of that video, but the original "Gilded Rose Kata", is the blatently dismissive "no, you figure out how to prove it works". Given that you have to do the latter anyway, any and all benefits of object orientation (at least in my opinion) immediately just fly straight out the window. One deeply ironic thing is the way Sandi shows how easy it is to modify/break/fix things, so that you never again have to be utterly terrified of breaking things, in other words making that aspect of OOP a complete non-goal (imo). Perhaps even more galling, she explains how difficult this would be to fix in an imperative style (which I swallowed hook, line, and sinker) then inadvertenty shows the exact same first step you w/should use for both OOP and imperative refactoring - but it did not escape my attention that I genuinely learnt something very useful from that.
The file demo\GildedRoseKata.exw contains three trivial refactorings that perfectly address all of the concerns, without resorting to object orientation, plus for completeness one that does. The file GildedRiseKataN.exw is my ideal take, and specifically the 14 line update_quality() in that my replacement for the original 43 line mess or the 7 classes Sandi created, and I would certainly baulk at needing seven or more separate source files (not Ruby, but some OOP-languages would).
Decades of fruitless searching for proof that OOP improves anything suddenly fall neatly under "no, you prove it", which is very reminiscent of that old M&M advert. It has in fact long been shown there is no significant difference in software development productivity between OOP and the procedural approach, which actually makes me think there must be something deep down somewhere really good about OOP, that somehow counteracts all the bad stuff!
Being able to modify something without understanding how it works also sounds like a really clever idea, but (imo) must eventually make it simply impossible to ever make another properly informed descision. I don’t expect any one person to know everything there is to know about a large project, but I do expect to be able to glean what I need by simple inspection. If I can alter the behaviour of some bit of code without modifying it, how can it ever possibly be readable? If I have a base class B and some derived class D, when I add class E what precisely prevents me from taking (another) copy of B.doit() when I should in fact be basing my revisions on D.doit()? Or fixing something in E and forgetting to fix the same thing in D? My local library does not have seven separate shelves for "An Agent" since seven separate staff saw nothing between "An Actor" and "An Author", instead they are allowed to use their common sense and modify the main shelf itself. I could no doubt go on like this forever. (To be fair, those criticisms are only really about adamantly applying OCP to improperly refactored code.)
Quite often I hear the phrase "naming is hard", which I have always struggled to even begin to comprehend, apart perhaps from the shorter and pithier side of things. However and especially when confronted by an ever-increasing outrageously overcomplicated and for the most part completely undocumented hierarchy of meaningless classes, typically solely created to overcome the restrictions and limitations inherent in an object oriented paradigm, I can get behind "naming this drivel is hard".
Ultimately, not just the point but the entire triumph of object orientation is to allow, and in practice actively encourage you to construct programs that you simply cannot understand, at least in any meaningful holistic sense. Another way of saying that: object orientation allows you to modify some small part without the slightest clue what you’re doing. I get the need for compartmentalisation, but that is just insane. I don’t know about you, but I don’t care if it might cost an awful lot less to train them up, I don’t ever want a surgeon to operate on my foot (say), however flawlessly, but without any consideration at all being given to the possible consequences on the rest of me. In a complex system, even one far less complicated than the human body, promising me there will be no consequences, when you don’t even know what they might be, simply doesn’t cut it. Fundamentally I suppose the intended aim must be perfectly achievable in any programming paradigm that allows the programmer to write sensible abstractions, my objection is to forcing the creation of literally countless layers of meaningless abstractions.
Innovation inevitably incurs the unavoidable cost of deep understanding, putting that (unwanted?) litter of lovely little kittens in a sack weighed with stones and slinging it in the nearest canal or reservoir, well that simply ain’t me.
Maybe I am just different, I fondly remember being gently teased at the age of six over my inquisitive desire to figure out how things work, and (absurdly abstract abominations aside) I have never lost that.
The SOLID principles as applied to Phix would probably be:

- `S`ingle source is somewhat simpler than seventy-six separate sources.
- `O`pen, just keep it open, for extension, modification, or whatever.
- `L`et’s let you decide what is and is not a legal parameter.
- `I`nterfaces should ideally be documented somewhere, please.
- `D`ebugging should be easy, even for ("") inverted dependencies.

Bugs are going to happen: running away terrified or putting your fingers in your ears and humming loudly is not going to help, nor does saying "there is no new bug in the unmodified code, it must be somewhere else" or perhaps more relevantly in the freakishly misguided object oriented mentality, "there is no omission, because that bit of code has not yet been written". (WHAT?)
Rather than making you jump through hoops to avoid adding bugs, why not make finding and fixing bugs easier?
To paraphrase Kent Beck, I might say:

- First make debugging easy, then make the easily found fix.

- Warning: this may be hard, and break other things.
- Should/when other things break, add more tests/asserts.

- Save sensibly named temporary variables, as often as you can.

- Factor out common subexpressions and give them a proper name.

- Except perhaps in tight inner loops:
  - Store diagnostic info in local vars, even if not needed right now.
  - Map meaningless things to human readable strings whenever you can.
  - Tag things properly, eg {"gImage",#NNNN}, rather than just #NNNN.
  - Comment such out only when they verify-ably impact performance.
- Messy code that is easy to debug is far more valuable than neat code that isn’t.

- Not that you shouldn’t take some pride in your work, of course.

Lastly, the obligatory quotes:

“Object oriented programs are offered as alternatives to correct ones...”
“Object-oriented programming is an exceptionally bad idea which could only have originated in California.”
- Edsger W. Dijkstra

“The combination of threads, remote-procedure-call interfaces, and heavyweight object-oriented design is especially dangerous ...
if you are ever invited onto a project that is supposed to feature all three, fleeing in terror might well be an appropriate reaction.”
“To the surprise and gradual disillusionment of many, it has proven difficult to demonstrate significant benefits of OO.” [outside certain areas]
- Eric S. Raymond

“Object-oriented programming offers a sustainable way to write spaghetti code. It lets you accrete programs as a series of patches.”
- Paul Graham

“The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them.
You wanted a banana but what you got was a gorilla holding the banana and the entire jungle.”
- Joe Armstrong

“Object-oriented programming had boldly promised "to model the world".
Well, the world is a scary place where bad things happen for no apparent reason,
and in this narrow sense I concede that OO does model the world.”
- Dave Fancher

“I used to be enamored of object-oriented programming. I’m now finding myself leaning toward believing it is a plot designed to destroy joy.
The methodology looks clean and elegant at first, but when you actually get into real programs they rapidly turn into horrid messes.”
- Eric Allman

“I invented the term 'Object-Oriented', and I can tell you I did not have C++ in mind.”
- Alan Kay

“It’s OK to figure out murder mysteries, but you shouldn’t need to figure out code. You should be able to read it.”
- Steve C McConnell

“There is no silver bullet.”
- Frederick P. Brooks

I would never discourage appropriate use of OO, but Phix will simply never be an "OO-only" language.