Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

[This talk is] a call to stop writing object oriented software. He gives a convincing argument. You can probably find a thing or two to disagree with, but like he says, this is something we all know to be true.

I agree very much with the underlying theme of the talk. But changing the focus to working with immutable values is only one step in a direction away from the dominant, imperative style of programming typified by OOP. There are (at least) two more big steps that need to be taken before I can see this more functional style of programming having any chance of going mainstream.

Firstly, we have to deal with the time dimension. The real world is stateful. All useful programs interact with other parts of the world in some form, and the timing of those interactions is often important. While programming with pure functions has advantages and lends itself very well to expressing some ideas, sooner or later we have to model time. There are plenty of relevant ideas with potential, but I don’t think we’re anywhere near getting this right yet.

Secondly, there are some algorithms that you simply can’t implement efficiently without in-place modification of data. If programs are to be expressed in a way that pretends this doesn’t happen, then the compilers and interpreters and VMs need to be capable of optimising the implementation to do it behind the scenes. At best, this is a sufficiently smart compiler argument, and even as those optimisations develop, I suspect that programmers will still have to understand the implications of what they are doing at a higher level to some extent so that they can avoid backing the optimiser into a corner.

We know from research into program comprehension that as we work on code we’re simultaneously forming several different mental models of that code. One of these is what we might call control flow, the order of evaluating expressions and executing statements. Another is data flow, where values come from and how they are used. Often the data flow is what we really care about, but imperative code tends to mix these two different views together and to emphasize control flow even when it’s merely an implementation detail. Moving to a more functional, value-based programming style is surely a step in the right direction, since it helps us understand the data flow without getting lost in irrelevant details.

To really get somewhere, though, I suspect we’ll need to move up another level. I’d like to be able to treat causes and effects (when a program interacts with the world around it or an explicitly stateful component) as first class concepts, because ultimately modelling of time matters exactly to the extent that it constrains those causes and effects. Within that framework, everything else can be timeless, at least in principle, and all those lovely functional programming tools can be applied.

Sometimes, for efficiency, I suspect we’ll still want to introduce internal concepts of time/state, but I’m hoping that however we come to model these ideas will let us keep such code safely isolated so it can still have controlled, timeless interactions with the rest of the program. In other words, I think we need to be able to isolate time not only at the outside edge of our program but also around the edge of any internal pieces where stateful programming remains the most useful way to solve a particular problem but that state is just an implementation detail.

So, I agree with you that this idea is about much more than just programming with immutable values. But I don’t think we can ever do away with a time dimension (or, if you prefer, place-oriented programming) completely. Rather, we need to learn to model interactions using both “external time” and “internal time” with the same kind of precision that modern type systems have for modelling relationships between data types. And whatever model we come up with had better not rely on scary words like “monad”, at least not to the general programming population rather than the guys designing programming languages. In fact, ironically (or not), it starts to sound a lot like the original ideas behind OOP in some respects. :-)



> a time dimension (or, if you prefer, place-oriented programming)

Place oriented is the opposite of having a time dimension. It means that at any time, the thing at that place might be different. This was done for your second argument, efficiency. The talk argues that if functional programming with values is efficient enough for you, than you shouldn't be writing object oriented software.

Values on the other hand absolutely have a time dimension. His "Facts" slide says it as does datomic and his revision control example.

He has another great talk that touches a bit more on time:

http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hic...


For the avoidance of doubt, when I’m talking about (not) doing away with a time dimension here, I mean from the perspective of the world changing over time as our program runs, not of associating values that effectively last forever with a certain point in time (as in purely functional data structures, version control systems, etc.).

That is, even if we follow the current trend of adopting more ideas from functional programming in mainstream programming languages, I’m saying that I doubt we will ever completely remove variable state, which is what I understand Rich to mean by “place-oriented programming”, or events that must happen in a certain order.

Instead, I think we will learn to control these aspects of our programs better. When we model time-dependent things, we want to have well-specified behaviour based on a clean underlying model, so we can easily understand what our code will do. Today, we have functions and variables, and we have type systems that can stop us passing the colour orange into a function eat(food). Tomorrow, I think we’ll promote some of these time-related ideas to first-class entities in our programming languages too, and we’ll have rules to stop you doing time-dependent things without specifying valid relationships to other time-dependent things. Some of the ideas in that second talk you linked to, like recognising that we’re often modelling a process, are very much what I’m talking about here.

As an aside, it’s possible that instead of adding first-class entities for things like effects, we will instead develop some really flexible first-class concepts that let us implement effects as just another type of second-class citizen. However, given the experience to date with monads in Haskell and with Lisps in general, I’m doubtful that anything short of first-class language support is going to cut it for a mainstream audience. It seems that for new programming styles to achieve mainstream acceptance, some concepts have to be special.

In any case, my hope is that if we make time-related ideas explicit when we care about them, it will mean that when we don’t need to keep track of time, we needn’t clutter our designs/code with unnecessary details. That contrasts with typical imperative programming today, where you’re always effectively specifying things about timing and order of execution whether you actually care about them or not, but when it comes to things like concurrency and resource management the underlying models of how things interact usually aren’t very powerful and allow many classes of timing/synchronisation bug to get into production.


I'm far from an expert on this topic, but it seems that you're still missing the main point--this talk is exactly about how to model time dependent data (immutable data), and how not to (mutable state, oo). Hickey definitely isn't advocating a system that can't change with time. Such a system would be pointless. He wants changes in state (which, naturally, occur on a time axis) to be represented by new values, not as in place, destructive updates of old values, as it's done in oo and currently popular databases.

If you look at the results of this approach in Datomic, I think you actually do see a design that treats time as much like a first-class citizen as it's ever been treated, in the sense that time essentially acts as a primary key, and developers are provided with a time machine that allows them easy and efficient access to any state that has existed in their data in the history of the application. (In theory, at least--I haven't personally tried Datomic).


I’m pretty sure I understand where Rich is coming from. I’m just arguing that while moving to persistent, immutable values is a big step in what could be a good direction, it’s not sufficient by itself to justify or cause a shift in mainstream programming styles on the scale of abandoning OOP (as suggested in the original post I replied to).

You lose things in that transition, very useful things that are widely applicable. We’re not going to just give those up without having something good enough to replace them, and I thought that in this specific talk those two areas I mentioned were glossed over far too readily.

For example, although Rich said very clearly that he thought it was OK to manipulate data in-place as an implementation detail of how a new value is built, he then argued that once the finished result was ready it should become an immutable value, and that we no longer need to use abstractions that are based on or tied to that kind of underlying behaviour. I contend that there are many cases where it is not so simple even with today’s technology, and that the idea of constraining in-place mutation to the initial creation of a value is a leaky abstraction that will not survive a lot of practical applications.

Later on, processes are briefly mentioned, but that part of the talk is about information systems, which are mostly concerned with pure data analysis. That makes it is rather easy to dismiss the idea of modelling interactive processes in context, but unfortunately, very many real world programs do need to be concerned with the wider time-related concepts like effects.

I’m sure Rich himself is well aware of all of these issues. He’s discussed related ideas in far more detail on other occasions, including in the talk that lrenn cited above. But I find his challenge near the end of this talk, “If you can afford to do this, why would you do anything else? What’s a really good reason for doing something else?” to be rather unconvincing. For one thing, that’s a mighty big “if”, whether you interpret “afford” in terms of performance or dollars. For another thing, the answer to those questions could simply be “Because ‘this’ isn’t capable of modelling my real world, interactive system effectively.”




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: