Skip to main content

OO in Language Design

If you were to create a new programming language, and you wanted to support object oriented programming with it, what would it look like? An object is a set of instance data and various functions that work with it. In Java, they're specified by first grouping the variables and functions together in a class, and then creating an instance from the class definition. In JavaScript, functions are dynamically attached to the instance data (or it's prototype). This is an intentional over-simplification but does highlight the fact that different programming languages approach working with objects differently. I've been thinking about objects and working with structured code in relation to Kiwi and it depresses me how much the object oriented school of thought that started with C++ and came to fruition in Java has influenced our industry.

Of course there are the so-called five concepts of object oriented design, which says a design that meets the following criteria is considered object-oriented (OO):
  • Object/Class
  • Information Hiding
  • Inheritance
  • Interface
  • Polymorphism

But I'm not so sure I'm convinced. A coworker accused me of trying to re-define it:

Coworker: So now we're redefining what OO is too... care to define common words as well?

Me: I'm not redefining it per se... just calling bullshit where I see bullshit.

Coworker: Excuse while I go outside and laugh loudly.

Me: Sorry my name isn't Martin Fowler so my opinion probably doesn't matter much, but I still smell bullshit.

If we think about programming in C for a moment, a language that isn't considered to support OO practices, we can still encapsulate our code and provide an interface for data manipulation. Member variables are placed in a struct, public methods are functions listed in a header file, and private methods exist only in the code file. Encapsulating in this case depends on an understanding of variable and file scoping rules of the language, not the existence of some class, public, protected, and private keywords.

We have to pass a pointer to the instance class into the functions, but that still happens in languages that are considered to be OO languages too; it's just syntactic sugar that automatically passes it and assigns it to this. It's difficult to ignore the similarity between foo.doSomething() and doSomething(foo).

Java has developers define the method functions in the same code unit as the member variables. Others allow defining them separately, and then associate them in some way later. C++ does this through file and namespacing, and Go does this with interfaces.

If we were to think of instances of objects in terms as payload structs, then is inheritance really necessary? We don't extend a class for example because we have a protected integer member we want to reuse, we do it for the functionality provided by method functions. Inheritance supposedly helps with code-organization and promotes re-use, but I'd argue not essential for OO. In fact, the proliferation of OO far exceeds the amount of code we actually end up reusing.

Polymorphism probably isn't really needed either for OO. Data typing is all about the underlying semantic meaning of data and what operations are allowed to be performed on it. What it means to "add" two strings together and what it means to "add" two integers together are different even though both are aggregate operations. Typing is less relevant in dynamic languages like PHP and Ruby. We don't care what type an object is so long as we can call a method on it. The concept of polymorphism is only important in statically-typed languages, and promoting it as a core OO concept means a true dynamically typed language could never be object oriented.

The way I see it, encapsulation begets abstraction. Inheritance is about reusability, not objects. Interface is a design pattern that attempts to overcome difficulty for reusing code from different objects. Pure object oriented programming seems really to be about encapsulation and message passing, while the concepts above seem more concerned about structure.

It can be argued that the software industry is in the mess it's in right now because of the over-definition and application of intolerant ideas about OO, and a refusal to acknowledge other schools of thought on the subject. But if I'm taking on the responsibility to create a new language, then I'm going to take the time to think about such things and not just follow the herd. I want to create something better, not just a better Java.

Comments

  1. I always appreciate your ability to focus on the core maxims rather than get distracted by petty implementation specifics. It allows you to stay open to core principles and approach problems as opportunities for perfect solutions. I think that if there's any "mess" in the industry, which I wouldn't go so far as saying "mess", it's because people are unwilling to try something new, be wrong, be humble about getting corrected, learn something new, and grow. Keep it up!

    ReplyDelete
  2. Polymorphism isn't just about data typing. I use that for functions all of the time. So that means that Polymorphism can work on dynamically typed languages, too. To me polymorphism is the strongest and best part of OO. Oh, and just because I change a function, doesn't mean I'm not doing OO. I've had this argument before. An object, is an object, is an object... just because one small exception is found, doesn't mean I'm forced to create a new object. I can keep the same object with a special exception as long as it doesn't go against my overall design.

    ReplyDelete

Post a Comment

Popular posts from this blog

Writing a Minimal PSR-0 Autoloader

An excellent overview of autoloading in PHP and the PSR-0 standard was written by Hari K T over at PHPMaster.com , and it's definitely worth the read. But maybe you don't like some of the bloated, heavier autoloader offerings provided by various PHP frameworks, or maybe you just like to roll your own solutions. Is it possible to roll your own minimal loader and still be compliant? First, let's look at what PSR-0 mandates, taken directly from the standards document on GitHub : A fully-qualified namespace and class must have the following structure \<Vendor Name>\(<Namespace>\)*<Class Name> Each namespace must have a top-level namespace ("Vendor Name"). Each namespace can have as many sub-namespaces as it wishes. Each namespace separator is converted to a DIRECTORY_SEPARATOR when loading from the file system. Each "_" character in the CLASS NAME is converted to a DIRECTORY_SEPARATOR . The "_" character has no special ...

Composing Music with PHP

I’m not an expert on probability theory, artificial intelligence, and machine learning. And even my Music 201 class from years ago has been long forgotten. But if you’ll indulge me for the next 10 minutes, I think you’ll find that even just a little knowledge can yield impressive results if creatively woven together. I’d like to share with you how to teach PHP to compose music. Here’s an example: You’re looking at a melody generated by PHP. It’s not the most memorable, but it’s not unpleasant either. And surprisingly, the code to generate such sequences is rather brief. So what’s going on? The script calculates a probability map of melodic intervals and applies a Markov process to generate a new sequence. In friendlier terms, musical data is analyzed by a script to learn which intervals make up pleasing melodies. It then creates a new composition by selecting pitches based on the possibilities it’s observed. . Standing on Shoulders Composition doesn’t happen in a vacuum. Bach wa...

Learning Prolog

I'm not quite sure exactly I was searching for, but somehow I serendipitously stumbled upon the site learnprolognow.org a few months ago. It's the home for an introductory Prolog programming course. Logic programming offers an interesting way to think about your problems; I've been doing so much procedural and object-oriented programming in the past decade that it really took effort to think at a higher level! I found the most interesting features to be definite clause grammars (DCG), and unification. Difference lists are very powerful and Prolog's DCG syntax makes it easy to work with them. Specifying a grammar such as: s(s(NP,VP)) --> np(NP,X,Y,subject), vp(VP,X,Y). np(np(DET,NBAR,PP),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y), pp(PP). np(np(DET,NBAR),X,Y,_) --> det(DET,X), nbar(NBAR,X,Y). np(np(PRO),X,Y,Z) --> pro(PRO,X,Y,Z). vp(vp(V),X,Y) --> v(V,X,Y). vp(vp(V,NP),X,Y) --> v(V,X,Y), np(NP,_,_,object). nbar(nbar(JP),X,3) --> jp(JP,X). pp(pp(PREP,N...