Declarative vs Imperative programming

I’ve been using declarative programming for the last eight months, and it’s changed the way I approach my code. Managing complexity (the main job of any software engineer) becomes a lot easier when the code is structured more like human logic than machine logic.

I’ve been using ReactiveCocoa, a port of .NET reactive extensions by the guys at Github.

In imperative programming (what most of us do each day), we might have something like this:

function updateTotal {
    float totalPrice = (self.quantity * self.pricePerItem)  —  self.couponValue;
    self.textfield.text = [NSString stringWithFormat:@”$%.0f”, totalPrice];
}

function setQuantity(int newQuantity) {
    _quantity = newQuantity;
    updateTotal();
}

function setPricePerItem(float newPrice) {
    _pricePerItem = newPrice;
    updateTotal();
}

function setCouponValue(float newCouponValue) {
    _couponValue = newCouponValue;
    updateTotal();
}

This code is imperative in the sense that it’s explicitly executing procedures based on previous actions — i.e. it’s telling the app to update the total. But it’s bulky and there’s a lot of redundancy in there.

The problem would be worse if the couponValue, pricePerItem and quantity were variables in other classes. You would have to figure out if the textfield’s view controller is instantiated, and expose the updateTotal method publicly, and you’re forced to write a setter method for each influencing variable, or be stuck calling updateTotal from a bunch of random places in your codebase and coupling things needlessly.

Here’s where Reactive Cocoa is great:

RAC(self.textfield, text) = [RACSignal combineLatest:@[RACObserve(self, quantity), RACObserve(self, pricePerItem), RACObserve(self, couponValue)] reduce:^NSString *(NSNumber *quantity, NSNumber *pricePerItem, NSNumber *couponValue) {
    float totalPrice = (quantity.intValue * pricePerItem.floatValue)  —  couponValue.floatValue;
    return [NSString stringWithFormat:@”$%.0f”, totalPrice];
}

This essentially says “the text in the textfield depends on the variables quantity, pricePerItem and couponValue, and its value is equal to (quantity * pricePerItem) — couponValue”. Much closer to how we think about these things ourselves, right? Now, if this ever happens…

self.quantity++;

…the total will be automatically updated. The code above only needs to be called once, and if the view controller holding the textfield is deallocated, the bindings will be automatically disposed of. Awesome.

If you want to find out more about ReactiveCocoa, this is what helped me get started:

Functional Reactive Programming by Ash Furrow
The ReactiveCocoa readme
Colin Eberhardt’s tutorial