Donnerstag, 19. Juli 2012

If Vim Then Janus

If you're a vim user, then you should definitely check out janus (https://github.com/carlhuda/janus/). Installation is fully automated: Just do curl -Lo- https://bit.ly/janus-bootstrap | bash. Your old .vim/ and .vimrc will be backed up. If you want to add additional tweaks, you can put them into .vimrc.before and .vimrc.after, respectively.


What Janus will do for you:

  • Provide you with NerdTree, a file-explorer inside vim (\n).
  • Add automated syntax checking to your program sources upon :w.
  • Add Tagbar (\rt) for eayily access to the ctags in your source tree. (works with exuberant ctags only)
  • Add EasyMotion (\\<MOTION-COMMAND>), which is probably the most jawdropping vim plugins I ever found.

Give it a try. There is nothing like an antediluvian text editor that doubles as a full-blown IDE. Or, as some might argue, its own operating system.


Oh and also... since we're on the topic: A simple google search for "vim configuration" will save you a LOT of time in the future. It's incredible what those vimthusiasts have already come up with, so why reinvent the vil?

Sonntag, 15. Juli 2012

It Takes Two To Tango!


A friend just sent me the following OO brainteaser:

So what is the natural and clean design for an operation that represents the sale of a property? Say we have these objects: the buyer, the seller, the agent, the property and the contract. Which one of these would you prefer?

property.sell(buyer, seller, agent, contract)

seller.sell(property, buyer, agent, contract)

buyer.buy(property, seller, agent, contract)

agent.sell(property, buyer, seller, contract)

contract.sign(property, buyer, seller, agent)


My friend's suggestion was to create a Transaction object that abstracts the possession of property on the one hand and money on the other.

This is, I guess, a good idea. But I would like to point out another issue.

To some degree, it's a trick question: The way I see a sale, the agent really has nothing to do with it - it's actually three transactions, buyer/seller/contract, seller/agent and buyer/agent. I may be mistaken here, I've never sold property via an agent, but my impression is that the setup is obfuscating the problem that the creator of that brainteaser was aiming at. Let's just cut out the middleman, and reduce it to buyer/seller/property, which is probably the most frequent use case.

So, our options are

property.sell(buyer, seller)
property.buy(buyer, seller)
property.sellAndBuy(buyer, seller)
seller.sell(buyer, property)
buyer.buy(seller, property)

That's still an awful lot of equally viable options - and all of these have been seen in practice quite a few times! (Okay, the sellAndBuy option is more of a joke, but it's actually an apt description of what's going on, if you just find a more abstract word to replace the awkward "sellAndBuy".)

I think that the case in question is unsolvable, especially given the options presented. My preferred solution would depend on the context of the overall application. And that is a clear sign that something is afoul here. It's a code smell, albeit one that doesn't point to bad code, bad to a limited language paradigm.

I thin that my friend's solution is a very good one - abstract the whole thing into aan independent entity to avoid the confusion. But it still makes the nails of my feet roll up in displeasure.

First off, I think that there are actually two seperate problems hidden in the task above.

1. OOP is actually SOP


I've maintained for quite a while now that OOP is a misnomer. It should more aptly be called "SOP" - "Subject Oriented Programming". Call me a grammar nazi - I'm a literature major, after all. I still think I'm right.

See, in the real world, we deal with subjects and objects. Subjects interact with subjects, subjects act on objects, but objects do nothing themselves. In OOP, all you really have is subjects - entities that interact with other entities. (You could model an actual object as a class with only public members - a struct in C++ - , but that's just ridiculous.)

seller.sell(buyer, property) is really just a formalized way to say

"a seller sells a property to a buyer". In abstract terms, a subject conspires with another subject to do something to an object.

But in OOP, since we cannot distinguish between subjects and objects, a solution that has the contract as the primary object that drives the whole business (i.e., the subject) is perfectly acceptable. Which isn't bad per se, but it's a rather unintuitive solution. So I'd probably rule that one out.

That still leaves us with

seller.sell(buyer, property)
buyer.buy(seller, property)

2. Missing reciprocity


Now we arrive at the real beef: There is no concept of reciprocity in OOP. You have to bind an operation to one class, and one class only. But in reality, interactions are a reciprocal act between subjects: Buying always necessitates selling. It takes two to tango!

The awkward situation gets very obvious when you consider overloaded operators in C++ (in the case of commutative operators): seeing "a + b" as equivalent to "a.operator+(b)" does not make an awful lot of sense. The two objects are perfectly interchangable. But you cannot easily model that in current OOP languages. (At least the ones I know.)

(Okay, admittedly it's not exactly the same problem, since we're dealing with objects of the same class here, but it still illustrates our issue.)

3. A humble suggestion


What we need is a syntactic expression for the fact that selling is the reciprocal action of buying: It should be possible to express that seller.sell acts on both the buyer and the seller, and you can use whatever is more obvious in the context of your code.

I'm thinking of something like

Reciprocal BusinessTransaction {
    void sell(buyer, seller, property)
        == buyer.buy(seller, property)
            && seller.sell(buyer, property)
            && property.sell(buyer, seller);
}

That way, every object can still mind their own business, and the coder could use either one of four semantically identical operations, depending on which perspective fits her code best. Triggering buyer.buy() would automatically run seller.sell().

Of course, this necessitates that the methods in the various classes are actually independent of each other and can be handled in every possible order without causing trouble. (Looking at what I wrote here, I wonder - why does it look so damn functional-y? Hmmmmmm. Must be something to it... something sinister...)

One issue yet to solve would be that it should be perfectly obvious, when you look at the code for buyer.buy(), that seller.sell() gets triggered in the background. I have no idea how to guarantee that without creating duplicate code. So, maybe, class BusinessTransaction is still the best solution. Sigh. Or putting the code into BusinessTransaction, but labeling buyer.buy() as an alias to that, some kind of shortcut or implicit delegate.

Or so I hope.