What’s there after Objects?

As far as I can tell, there has been 3 major “revolutions” in software development since it all started:

  1. From binary to assembly language
  2. From assembly language to procedural languages
  3. From procedural languages to Object-Oriented Programming

Of course I’m not even talking about marginal evolutions like functional programming, scripting or formal programming.

And behind a revolution, there’s always a massive “there’s gotta be a better way” feeling. For assembly language people probably thought, “since we’re working with registers and memory addresses and instructions, let’s have readable forms of these concepts rather than just hexadecimal code, obviously we’re going to be more productive”. And then it was probably the same with procedural vs. OOP: Objects, classes, fields and methods were just closer to the kind concepts we were manipulating at some point and we couldn’t just keep tinkering with old paradigms, even on steroids (read structures and things like that).

Now I’m starting to wonder whether we’ve not come to the same point with OOP. At least I have come to this point myself. Objects, packages, components, whatever the granularity I’m still stuck having to tinker with old stuff to realize higher level tasks at some point. Most of the time, I’m not thinking about adding a field or a method in an object, but instead I want to add a property to an entity in my domain, or expose a business operation via a webservice. That’s the kind of tasks that make my day-to-day work. And still, let’s say I want to add a property to an entity in my domain, then I have to add the corresponding field in a class, write a getter and a setter, update the DDL script for the database, add the mapping to the Hibernate mapping file, add a validation directive somewhere… there’s gotta be a better way.

Now I realize that’s the main reason I love AndroMDA so much: because I can do high-level modifications in my UML models and boom! The generator just takes it over from there and updates the code almost everywhere it needs to be, which improves my productivity by a tremendous factor. Others use other tricks for the very same purpose: some use annotations, others turn to active record implementations. But whatever the trick, I feel more and more like it’s a dead-end, like… there’s gotta be a better way.

The closer the tools I’m using are to the concepts I manipulate, the less work I have to do to implement those concepts, the better it is for the whole project:

  • it reduces the probability for errors
  • it improves time-to-market
  • it frees up some time to focus on the real business at hand
  • it gives me a better sense of achievement
  • it dramatically improves return on investment since basically you’re doing more with less

Tonight I had a very interesting conversation with a very smart guy from the AndroMDA team, and it just appeared to me like magic: AndroMDA is just one way to cope with limitations of the underlying object-oriented paradigms, and we have to start thinking about how we can reach the same goals, but in a more native way. We need a brand new paradigm, a new way to build software closer to what we try to achieve everyday at a higher level.

What do you guys think? Have you heard of anything like that? Because I would be really interested in knowing about it. Otherwise, does anyone have any idea about what could be this new paradigm? And do you feel we need it? I’m really interested in your feedback on that one.

17 thoughts on “What’s there after Objects?”

  1. Hi Sébastien,
    did you realize that each revolution rises the programming abstraction level one level up ?
    In my opinion we have a lot to explore in OOP/MDA and the next step will be towards the user, creating environments where the applications will be created, tested and deployed automagically :-) with less “text programming” each day.
    From this point of view Andromda is a lot different from the other tools created only to make the programmer life more comfortable, since you can work at the model level, closer the user understanding.
    Like other recent “revolutions” like gmail, skype and youtube, the next revolution in sw development will have nothing to do with the underlying technologies, it will be a user centric revolution, allowing the user to control all the sw lifecycle.
    Cheers,
    Walter

  2. I totally agree with you that the level of abstraction goes one step up on each revolution. Now your “automagically” term tends to scare me a little bit, because it makes me think of idiotic things like this. And in my opinion, building software will always remain an expertise domain. What we can do though is reduce the distance between ideas and their software implementation but I think it will tend to an asymptotic line which is still very far away.

    Now I agree on AndroMDA being different but my problem is that it still requires a lot of wizardry and code generation to be able to implement high level concepts with low level constructs. That and the fact that it relies on UML so much is quite irritating.

  3. Just a wild guess here, but I think the next revolution will revolve around using graphics more and more to abstract away the actual programming. Maybe something like the Lego Mindstorms programming toolkit which allows you to drag visual blocks around in order to create a programs with loops, actions, and so on. IDEs are already going this route, with more and more code is being generated or changed for you. I think input devices will have to change as well, since using the mouse just isn’t as fast as keyboard shortcuts.

  4. Well, I’m not sure visual development is going to be a revolution in itself. I mean, with AndroMDA we’re already using a lot of UML, and there are a lot of visual designers for GUIs that rely heavily on the Object paradigm. I think graphical aids have been here and will always be here to help, more as an alternative way to manipulate the same concepts but for people with another… mindset.

    I was more thinking of a shift in the underlying paradigm, more than about the tools or goals pursued. For example, the metafacade concept in AndroMDA cartridges is very powerful. It allows you to define your own domain-specific language or a very generic one. Whether you want to model in terms of classes/field/methods or entities/services/value-objects, all of those are particular cases of higher-level concepts. The problem with metafacades is that they are entangled with UML and that since there is no way to interpret them natively, you’re forced to set up a whole machinery to translate them into lower-level OOP constructs.

  5. Despite your comment about marginal paradigms, the next thing is functions. Anything mathematical in software is easy to test, write, and scale. Anything not mathematical (OOP) is a pain in the proverbial, especially to test. Functional techniques are making it into mainstream languages, which presumably is because they’re useful. See Linq, Python’s list comprehensions, lambdas in C++0x, boost::lambda, JavaScript’s anonymous functions, etc.

    Mutable state needs controlling.

  6. Come on! I’m talking about paradigms that go in the direction of a closer relationship between software and the problems it’s trying to solve, high level concepts that could further reach the gap between what we want to achieve and what it does. When was the last time you thought of something in real life in terms of functions and lambda? And more importantly, when was the last time your boss did, or a customer or whatever.

    Easy to test, write and scale? If you make that a primary objective for any technology then I think you’re confusing the means and the end. Our goal as software developers should be to develop better software, more reliable, useful, elegant. This is the end. Now with the technologies that we have at our disposal today, we’ve been forced to learn how to test, and do something for scalability and so on. And adding low-level paradigms like functional constructs and closures is not going to solve the problem, it’s merely healing the symptoms, but the illness remains here.

    I believe there is a way to cure the real thing, to work with higher level constructs that both bridge the gap between our goals and our software while producing less code (so less probability for human errors, so less testing), and implement those constructs in a more native way so that it scales naturally well.

  7. I would tend to agree with Rick. Especially as the multi-core systems are rising and today developers don’t have the tools to address this…
    It is an industry driving force already, and while many of us stick their head in the sand, we will have to face it, rather sooner than later. Function oriented programming languages might be a solution and hence might gain a whole lot of popularity. Scala already being labeled as Java 3 by “people”…

  8. It’s interesting because it seems like a schism between people favoring the intrinsic “performance” of software paradigms and those who favor the “usability” of it. And I have the impression that both directions are antagonist, like you can’t have a paradigm that is both intuitive and optimized.

    As far as I’m concerned, when I realize that there is about the same calculation power in an iPod as what Appollo had in their ship when they landed on the moon, I tend to think that optimization is not and will never be a mainstream issue IN SOFTWARE. That’s why I don’t think that a paradigm whose primary purpose if to make things more performant or mathematically more correct will not solve what seems to me as our main issue: software usefulness.

  9. This isn’t really performance related… While it does also address it.
    Yet multi-core systems are becoming (oh wait, they already are) reality! And multi-threading as always been something (especially in UI) developers had to address, particularly in the gaming industry. Yet concurrency is a complex topic and you can’t really expect having every average developer deal with it correctly, especially in OO. The situation is simply there and functional programming addresses it. This just correlates well. Now if this (r)evolution is leading us down the right path, I have no clue… Hopefully there isn’t just a single path! Still, mathematicians will always tell you that functions are better suited to model the world than our objects…

  10. Functional programming doesn’t mean that you have to think about your customer’s problems purely in terms of functions and lambdas any more than OOP means that you have to think in terms of message passing and inheritance. We programmers have a tool called abstraction. Given a language with only lambda and a few other primitives, you can build datatypes, give them names, associate operations with them, etc. You could even call them objects.

    The main difference is that you wouldn’t typically change their state, but construct new objects to represent new state. This makes it easier to compose larger systems from small parts, because the larger systems no longer suffer from having more moving parts.

    The best way I know to say it briefly is a little ambiguous, but here goes: OOP seeks for values to *be* items from the domain, whereas functional programming seeks for values to *model* items from the domain.

    A model of a tennis ball flying through the air might never mutate an instance of Ball, but be a function over time. An object seeking to *be* a tennis ball is tempted to have a value according to the time involved. The non-mutating model is more composable – each user of it does not need to know what each other user of it is doing.

    Another approach is to refine your OOP programs as far as you can. Reduce duplication. Remove it entirely and you probably reinvented functional programming.

  11. JetBrains’ MPS and DSL are indeed an abstraction above, yet they address a different issue. And as of now, it would be expected out of “developers” to use a _set_ of DSL inside one application, and not a simple language.
    You probably also would want to see the “Building DSLs in Static & Dynamic Languages” presentation by Neal Ford.
    Yet those will not be replacing, but “supersetting” lower level languages.

  12. Oh my! That Language Oriented Programming is exactly what I was starting to think about. This is exactly what I needed. Those Jetbrains guys definitely have some talent. Walter, thanks a lot for the link: I think I’ll investigate a lot in that direction.

    Alex, I kind of agree with you: those will not replace OOP but merely superset it, like OOP does with procedures and functions (that are now methods), and like we’re still using assembly language in the virtual machine for example. But if those lower level constructs are hidden behind a set of more powerful tools, I think it will be for the greater good. I like Sergei’s analogy of stone and fire ages. It’s exactly that.

  13. This article is really enlightening, even though it’s four years old. Now Sergey underlines 3 major issues with mainstream OOP languages: expressivity, maintainability and learning curve. I would personnally add the quality issue. Since there is so much work needed to translate your ideas into code, there is all the more space for human errors and we’ve come to see practices like TDD as a necessary virtue, even though they are merely a workaround for the limitations of OOP.

  14. As a rough generalization: OOP gives you a single layer of abstraction, and then you wonder why it doesn’t scale. FP gives you tools (higher-order functions, expressive type systems) with which to build your own layers of abstraction at the granularity that’s appropriate for your problem domain. This way you don’t suffer the disconnect you cite between the high level and the low level. (and yes,as a bonus because you can state your intention more clearly it’s easier for your compiler to optimise it for increasingly complex hardware – but that’s only a bonus which I’m not sure is too important at this stage)

    As I see it, abstraction and quarantining the effects of state are the two biggest factors in program complexity, and OOP tries to apply one mechanism to handle both of them. FP handles state properly (i.e. explicitly!), leaving you free to use abstraction to model your problem domain, rather than having your abstractions partially dictated by the machine model. So although adding functional features to OOP languages can be convenient, it doesn’t deliver the necessary paradigm shift. But hopefully it _will_ smooth the way to mainstream adoption of referential transparency as a basic language requirement.

Leave a Reply