russellperry
A 'productivity boon'? I don't understand. At the risk of invoking the ancient static vs. dynamic religious war, this statement makes no sense to me.
I get that if your codebase is tangled enough, and your unit test suite is inadequate to "guarantee that your dataflow is more or less going to work" that maybe rewriting significant portions of it in a type-safe system makes sense. I guess. But without specific code examples it's hard to say exactly what he's talking about.
Myself, I've spent many years in both static and dynamic environments and I know exactly where I'm more productive -- and it's not wrestling complex parameterized types to the ground, pulling up abstract classes or interfaces, and/or configuring IOC containers, abstract factories and the like.
I wonder though -- this has echoes of Alex Payne's criticisms a couple of years ago, which I think Obie Fernandez addressed pretty well:
http://blog.obiefernandez.com/content/2009/04/my-reasoned-re...
"Rails is a Ghetto" notwithstanding, Zed's writing is always worth engaging even when you strongly disagree. In that respect he's always reminded me of Steve Albini.
What Albini would do with Fret Wars, however, is another question entirely.
And, again...<shudder>
The horror...the horror...
I wasn't intending to diminish the role of QA (essential) or assert that TDD cures all (doesn't), just that The Black Team weren't doing TDD.
You sound like every Rails dev I know.
It depends on the controller action in question. If it's a boilerplate Rails controller action, then the ROI might not be that high, but if the controller is doing something more specific (assuming it's not doing something that ought to be pushed to the model) then unit testing the action is important, sometimes very important.
Code coverage is pretty much a meaningless metric because it can't say whether the tests are actually good and useful. But it can help point experienced devs into areas of risk that may or may not warrant more attention.
The integrity of some acronyms is worth defending. I wouldn't want 'ACID' diluted to mean anything less than its strict definition, and I think the same holds true for 'REST'. The benefit of these distinctions is twofold: 1) we encourage the advantages of good RESTful practices and 2) we can communicate consistently without spending unnecessary effort qualifying our meaning. If REST means 'Anything but SOAP' then at some point we'll have to come up with another shorthand for 'Real REST' or spend lots of time re-stating the principles of REST every time we need to communicate architectural strategies that use them.
I should be able to say 'Singleton' or 'MVC' or 'ACID' and know that there is enough integrity to those ideas that a competent coder will know what I mean without me having to pseudo-code or UML the concept for them. The same should hold true for REST.
In Eclipse it's as simple as using the refactor tool to 'pull up interface' from any God Class of my choosing.
Neither language nor framework can force a coder to apply the Single Responsibility Principle. Coders can be willy-nilly with or without interfaces.
Two modern philosophers that I think may provide a better conceptual foundation for a less reified/Platonic/Aristotelian/Formalist view would be Alfred North Whitehead and Henri Bergson, both of whom described the ingression or duration of individual substances into other substances. Rather than hard borders (interfaces?) that interact in static and unchangeable ways, substances actually change each other at these borders. Bergson in particular I think would be interesting at many levels of the SDLC -- from emergent design (he advocated an 'emergent' fingertip-feel, intuitive approach to Science) to the nature of objects and hierachies.
What about the notion that an interface can change/morph according to the client that consumes it? This would move towards a more Heraclitean/Whiteheadean/Bergsonian paradigm.
I've used dozens of Ruby gems, plugins and classes over the years that have well-documented shared APIs and none of them (obviously) have had interfaces. Interfaces are good in certain environments for hiding implementation details where class-level contracts are enforced, but in Ruby this would provide no benefit at all.
Think of it this way: since Ruby has no class-level contracts, to some extent everything is already an interface. Everything is abstract. Every Ruby object has the opportunity to re-implement functionality in an abstract way.
I'm not sure Kant would allow that phenomena are all that abstract. They're not eidetic/formal (although later Husserl would argue that they intend towards eidetic objects), they're merely the subjective experience of a particular thing. The (purely hypothetical) relationship between the noumena and phenomena are (naively and hypothetically) one-to-one, if there is any real relationship at all.
The n/p distinction is made by Kant not to emphasize the abstract nature of our mental experiences, but rather to emphasize a radical epistemic uncertainty regarding the objects that we would naively assume "exists" apart from the experience.
Well, not exactly, and in fact this would turn Aristotle into his metaphysical opposite: a nominalist in the mold of Occam.
For Aristotle the formal cause of a substance is in fact absolute, every bit as real and 'prior' as with Plato, the big difference between the two being the question of epistemology, or how we become acquainted with the form to begin with. Yes, Aristotle argues that we know the form of a thing from experience, but the form of that thing, and the abstractions we produce from many experiences from similar things, are as real as with Plato and, as in Plato, point to higher, more organized spiritual structures that comprise ultimate reality.
Call me when somebody comes up with a Whitehead-ean programming paradigm.
Kant locates the origin of ideals/forms/categories in the mind only, as an essential pre-existing structure of the mind (think: hard-coded ROM), where Plato located their origins in reincarnate memory (not sure what the computer analogy would be there -- recycling a motherboard at Fry's?).
What mechanism would enforce the contract anyway? The best you could hope for would be a runtime error thrown when the interpreter detected the incompatibility, and you can do that manually now (I do it frequently to imitate abstract classes).
This is standard OOP 101 advice. 'Prefer encapsulation to inheritance' has been axiomatic in OO literature for over a decade. GOF and all the GOF-derived texts emphasize this.
OOP <> Inheritance
Inheritance is only one tool in the OOP toolbox, and probably one of the least important. OOP itself is only one conceptual tool in the programmer's toolbox, alongside procedural and functional tools. Learn them all, learn their strengths and weaknesses, and learn how to apply the right tool to the right problem.