Skip to content

Guide Replacing Object Oriented Programming

Jonathan Potter edited this page Mar 24, 2015 · 4 revisions

Code Reuse

Say you had an object oriented example:

function Rectangle(width, height) {
    this.width = width;
    this.height = height;
}

Rectangle.prototype.area = function() {
    return this.width * this.height;
}

// pretend this inherits from Rectangle
function Square(width) {
    this.width = width;
    this.height = width;
}

var r = new Rectangle(2, 4);
r.area(); // 8

var s = new Square(2);
s.area(); // 4

That's pretty cool, because it gives you code reuse. But you can get the same code reuse with normal functions:

function Rectangle(width, height) {
    this.width = width;
    this.height = height;
}

function Square(width) {
    this.width = width;
    this.height = width;
}

function area(shape) {
    return shape.width * shape.height;
}

But what if you wanted to call a super constructor? You can do that with plain old functions also:

function Rectangle(width, height) {
    this.width = width;
    this.height = height;
}

function ScaledRectangle(width, height, scale) {
    this.width = width;
    this.height = height;
    this.scale = scale;
}

function rectangleArea(rectangle) {
    return rectangle.width * rectangle.height;
}

function scaledRectangleArea(scaledRectangle) {
    return rectangleArea(scaledRectangle) * scaledRecangle.scale;
}

Namespacing

But these functions are in the global scope. That's annoying and wouldn't happen with normal object oriented programming. We can easily fix that with modules:

var rectangle = {};

rectangle.area = function(rectangle) {
    return rectangle.width * rectangle.height;
};

var scaled_rectangle = {};

scaled_rectangle.area = function(scaledRectangle) {
    return rectangle.area(scaledRectangle) * scaledRecangle.scale;
};

Polymorphism

But what if we didn't know whether we had a Rectangle or a ScaledRectangle and we just wanted to call the right area function without having to test the type. For that we use Translucent's typeclasses:

tlc.addInstance(Rectangle, {area: rectangle.area});
tlc.addInstance(ScaledRectangle, {area: scaled_rectangle.area});

function shapeArea(shape) {
    var area = tlc.getInstanceFunc(shape.constructor, "area").value;
    return area(shape);
}

In future versions of Translucent you'll hopefully be able to write this instead:

function shapeArea(shape) {
    return tlc.polymorphicCall(shape, "area", [shape]);
}

API

  • [Array](API Array)
  • [Function](API Function)
  • [Maybe](API Maybe)
  • [Object](API Object)
  • [Set](API Set)
  • [Typeclass](API Typeclass)

Guides

  • [Operators](Guide Operators)
  • [Typeclasses](Guide Typeclasses)
  • [Replacing OOP](Guide Replacing Object Oriented Programming)

General

Clone this wiki locally