At the end of the day, pick what language and coding paradigms best suit your problem domain and you as a coder. Pick right, and there's no mistake there.
At the end of the day, pick what language and coding paradigms best suit your problem domain and you as a coder. Pick right, and there's no mistake there.
That's only true on a superficial level. Sure, in CS 101 it's easy to explain how to make a Point object and add a Move() method to it. But dive into any real-world code base and you're more likely to meet RectangleCollectionColorPickerFactory instead. Let's face it, writing a large program is an exercise in abstract symbol manipulation. Trying to make it correspond to "real" objects is about as hopeless as basing literature on coloring books.
Trying to make code correspond to real world objects is annoying because after you've modeled your Car with Wheels that support Tires, and an Engine with EngineParts attached ... you then have to write a adaptation layer to make all that fit into your storage engine, your user interface, your query engine, etc ad nauseam. Strings are not "real world" objects, but we use them in our code nonetheless. They're a great UI item that lets us interface with our users. "I need input from the user. Here, type some text in this field and I shall call it String." Now you can manipulate the String with operations (methods on the object) that make sense for Strings.
Point: OO is not about "modeling the real world," it's about code organization. Some people organize with OO. Some with other means.
There is of course an alternative: use a function rather than a factory; but that's kind of the point of this discussion :-).
(Before we start a flame war: This isn't a criticsm of ruby or C# specifically, it's just something I've seen a lot in those code bases. Both languages allow writing factories or using lambdas.)
And I entirely agree with you that a PointFactory is unwanted (barring special circumstances) - though I entire disagree you'd want points to be mutable. Certain control points? Certainly - make a MutablePoint which is (conceptually) simply a reference to a point value. All points? That's just asking for pain; I really have better things than to track down with nested submodule thought it was mutating a copy but due to some optimization interaction turned out to be mutating a copy someone was actually looking on. Not to mention that reference semantics don't work very nicely with hashtables and lots of other datastructures which become a lot more complicated when the values can change right under them.
>> That's only true on a superficial level.
Exactly. I had forgot that I learned OOP by modelling a CD collection. When thinking about it now, "mapping" a program into real-world models and terms seems totally backwards.
What's the point of thinking in real-world models unless you program actually manipulates real-world objects? Of course there are properties that are useful to carry over, but why limit your program to real-world models?
Something like "RectangleCollectionColorPickerFactory" is obviously a confusing and ridiculous concept, and exemplifies a failed application of OOP, not a failure of OOP itself. One could invent equally absurd demonstrations of functional programming, or indeed of any other paradigm.
I only really "got" design patterns when I realized that the strategy pattern was just treating an algorithm/implementation as an object and stopped thinking that OO was exclusively about mapping things to real world objects.
In the real world, everything is a process. Nothing ever stays the same or stands still. No object is the same object from one millisecond to the next.
Immutable state isn't just a formal exercise--it's a more authentic model of the world.
To me that's as bad as saying "everything is an object".
I'd rather try and understand where each approach is best rather than picking a single approach and dogmatically applying it in every scenario.
Now it turns out to be difficult to maintain synchronized clocks, and Lamport timestamps and vector clocks are alternatives. The end result looks similar to a relativistic situation, but (and I'm not a physicist), it seems wrong to claim this situation is because of Special Relativity.
Thoughts?
In practice, replace Special Relativity with Network Problems.
http://ocw.mit.edu/courses/electrical-engineering-and-comput...
Been reading up on Heraclitus lately?
While this is an interesting statement for a philosophical dialogue, it doesn't really make much sense in the context of programming, where many things are constant, many things are not processes, and there are plenty of use cases for both mutable and immutable state (which is exactly why I always get really defensive reading articles like this one, that pretend all problem domains would be best modelled by a single programming language/paradigm/model of computation).
Surely that is in part due to the developer. Poor developers will choose the wrong abstractions, and have a poor OOP model as a result. Better developers will choose the correct abstractions, and have better models. Obviously the domain you are modeling will make it easier or harder to model things, and in some cases OPP may not be a good choice at all.
In my day to day work I use Django. I start with a data model - based on an ER diagram. I code that in the Django model classes. Is that OOP modeling or ER modeling? I don't know. I don't really care too much. It works fairly well for most things I am doing.
This is important, and something almost everybody ignores.
Get an OO codebase, and try to implement a time-dependent feature, like snapshots, or even a simple undo. The abstractions fall apart.
I bet the authorities around the world don't like your time-inclusive-dimenstion view much.
No matter what you do, identity does not change. You commiting a crime yesterday was an event that included you as an object with identity and today you have the same identtiy so you are clearly responsible for what you did yesterday.
GUARDS! :P
If space-time is discontinuous, then we can think any change of state, like motion, as a set of discrete changes. If we think the motion of a particle from one energy bin to another is immediate (meaning the particle cannot be found on the border between the bins, or one moment the particle is in Bin A, next it is in Bin B) then we can think the particle was destroyed in Bin A and another one was created at Bin B. And this is what we call motion from A -> B.
> See, mutable state makes shorter English sentences, and the agent concept helps make analogies with our fellow humans. In the end, this first impression trumps the fact that avoiding mutable state where possible ultimately yield simpler programs.
- But shorter English sentences are awesome.
- Good analogies are awesome.
- Effectively communicating with our fellow humans is awesome.
Indeed, all these things contribute to simplicity.
I find that often critiques of OOP are actually critiques of poorly implemented OOP. When it's done well, it can retain many benefits of immutability while still mapping more naturally to domain concepts. This talk by Gary Bernhardt is a great discussion of using functional concepts in OOP, and doing OOP well:
https://www.destroyallsoftware.com/talks/boundaries
The talk "Functional Core, Imperative Shell" is also a must see.
You missed the author's point here. He of course prefers shorter sentences as well. He is complaining that mainstream language syntax is biased in favor of mutability since you need to use an extra keyword to make a const expression. In F# for example it is just the opposite, you have to use the keyword "mutable" in your declaration.
He then proceeds to launch his piece of chalk across the room! (good stuff). And proposes that instead of the chalk having changing state (position, velocity, etc), instead, its better to thing of the chalk as a collection of immutable values; each value existing at a moment in time. And this of course aligns more to functional programming; and you see the same notion (immutable values over time) with descriptions of Datomic.
[1] http://ocw.mit.edu/courses/electrical-engineering-and-comput...
I don't know, I think it's a point where education fails. Your average enterprise developer should be forced to read books like "Clean Code" by Bob Martin before being allowed to touch a keyboard.
I'd argue that the problem with software quality is not so much in the (ab)use of mutable state, but the fact that (especially in enterprises) software often reflects the organizational structure of the people who worked on it.
Exhibit A: the software solution where every tiny part of the system is developed by some (semi) random group of people that often changes, doesn't directly communicate with any of the other groups, doesn't bother to much with the 'architecture' of the complete system (a big ball of mud), and has no interest improving either the overall architecture of the system, or any of the components outside their scope. Add pervasive mutable state into this mix, and you have a recipe for disaster.
That's not to say the mantra 'eliminate (almost) all forms of mutable state' will improve this problem much.
See what I did there.
Also note that theories that have tried to categories real world objects into classes have a tendency to fail (although they also have a tendency to become enormously popular [see Platon and Aristoteles fx.]).
So the claim that classes allows you to model a problem in real-world terms, is most likely false.
See for example http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.56.... for a review.
You can have OOP without classes - prototypal inheritance for example. In JS, you just clone an exemplar with Object.create() for example.
That said, the article author does the same thing.
An addendum: there is often no single obvious best way to do something. Though many approaches are obvious as being less wrong than others.
It absolutely reduces cognitive overload. Having "containers" of functionality that allow me to easily know at a glance what I'm working with is invaluable. I'm not knocking functional programming, since I haven't built a few projects in a purely functional language yet, but trying to do some things with the functional paradigm (or at least, my understanding of it) left me recognizing class-based programming as a powerful tool when used correctly.
To me, it makes much more sense to try to create programming languages that are able to express human thought. People think in terms of things that are, to a first approximation immutable, memories are a good example.
Many times I've heard this argument from someone who only knows the one or two tools they learned in college or in their first job, and they try to dress up their ignorance as wisdom for "not wasting time on the wrong tools".
I recommend http://norvig.com/21-days.html as a great place to start (I have only learned, at best, 3/6 of his suggested language categories, and I am on the 4th).