Chad Perrin: SOB

31 December 2007

thinking in FP or OOP syntax

Filed under: Geek — apotheon @ 03:00

Bear with me. I’m sure most of my readers know most, if not all, of the following explanation.

We (where “we” means “programmers”, “mathematicians”, and even “people who have been in third grade”) should all be familiar with infix syntax. That’s where you divide 10 by 2 with this syntax:

10 / 2

That’s common to many C-like programming languages such as Perl, Java, and C itself, when using arithmetic operators. It’s not so common to languages like Lisp, of course — and even in C-like languages, it tends to be limited to special (if common) cases, like arithmetic. C and Perl tend to use functional syntax for everything else — even when doing object-oriented things in Perl. In Lisp, it would look like this:

(divide 10 2)

That’s not how most languages employ functional syntax, of course. Most of them do something a bit more like the way functions tend to look in pure mathematics:

divide(10,2)

One might also call this prefix syntax. Of course, in C and Perl, division (an arithmetic operation) uses infix notation (what C and Perl use for arithmetic operations). Much of the rest of the language uses the above sort of syntax, however — and one could easily define a divide function like the above:

#/usr/bin/env perl

sub divide {
  ($dividend, $divisor) = @_;
  $dividend / $divisor;
}

divide(10,2);

There’s also postfix functional syntax, of course. Division with such a syntax might look something like this:

10 2 /

. . . but that’s not really relevant. It wasn’t until I started playing with Lisp-like languages (again) that I really grokked the value of a prefix/functional syntax for arithmetic. I began refamiliarizing myself with Logo, via UCBLogo — a Logo that supports macros at least somewhat like those of Lisp, and uses an M-expression functional syntax (that is, a syntax that doesn’t require the “fingernail clippings” of Common Lisp). In Logo, division looks like this:

quotient 10 2

One of the great things about prefix (and postfix) notation for arithmetic is that it makes all the problems of precedence common to grade school arithmetic and many programming languages irrelevant. Arithmetic operations are organized hierarchically rather than linearly, which means that multiple operation dependencies for a single operation can be handled without specific grouping characters and messy precedence rules.

There’s another syntactic form that interests me right now: object oriented syntax. It varies somewhat in its appearance depending on the implementation language, of course. In Ruby, it looks like this:

10./(2)

I got to thinking about all this when I saw someone post something on the ruby-talk mailing list that used a method invoked thusly:

divide(10,2)

What struck me about this is that, for the first time since re-encountering Logo and learning to love prefix arithmetic notation, that looked wrong to me. I actually found myself wanting to rewrite the method so that it worked like this:

10.divide(2)

The object oriented arithmetic notation has insinuated itself into my preferences somehow. It hasn’t truly supplanted prefix notation. For one thing, this object oriented syntax is an odd mix of prefix and postfix notational syntaxes. It provides many of the same benefits of either of them — but it is tailored more specifically to an object oriented programming style (obviously).

Rather than having an operator that operates on the arguments on either side of it, or an operator that operates on the following (or preceding) operators, it is instead an operator used by the object before it to operate on the argument following it. If you don’t understand how that’s beneficial, it probably means you haven’t really grokked object oriented programming fully.

I understood all that for years, but it’s only now that it has come to feel as familiar and natural to me as prefix notation for arithmetic operations. I guess one could say I’m thinking in OOP syntax just as easily as in functional programming syntax.

2 Comments

  1. One of the nice things about postfix notation is that it saves the compiler/interpreter the trouble of stacking the operations until all operands have been gathered. Prefix notation makes it possible to parse functions and arithmetic operations all the same, immediately pushing the function and then gathering all the arguments. Infix notation means you have to recognize the operator, either as a keyword or by its syntactic location. But we shouldn’t be too concerned about making things easy on the compiler/interpreter author.

    I like Ruby’s methods on numeric literals (e.g., 2.times) but in some cases it doesn’t logically make sense to make an operation a method of one of its operands. In the case of 10.divide(2), is it really the number 10 that is acting? It seems to me that division is one of those functions that really shouldn’t belong to an object, and so I favor a functional syntax for that operation. The number 10 is being acted upon by an unseen force (the program, actually) that uses the number 2 to divide it.

    OTOH, Ruby (like many languages that support operator overloading) uses operator definitions in a class to specify how various combinations of parameter types are to be handled, and that can be quite useful (although it can also be used to obfuscate code mightily).

    Comment by SterlingCamden — 6 January 2008 @ 05:12

  2. re: prefix vs. infix

    I agree that we shouldn’t be optimizing for the compiler entirely at the expense of optimizing for the programmer. If that were the case, we’d be writing in assembly all the time — and assembly itself would be much less friendly than it already is. On the other hand, I don’t find prefix notation in the least problematic in terms of ease of use. In fact, I find that it’s a net benefit for thinking about the problems at hand, compared with infix notation.

    re: the number as actor

    Sure, it’s the number 10 acting. You’re asking it to tell you what the result of dividing its value by 2 is. Thus, it tells you. It’s only the number 10 acting so long as you’re doing object oriented programming, of course — but that’s no less valid a way of looking at it than the more traditional functional model. Which seems more natural at any given moment is really just a matter of state of mind.

    A big part of what I find problematic about infix arithmetic notation is that it’s not a state of mind, really — or, at least, not a systematic state of mind. It’s cobbled together out of arbitrary rules that depend upon too damned many other arbitrary rules. Multiplication coming before addition is just an arbitrary convention, necessitated by a notation that doesn’t make the order of operations self-evident, which in turn necessitates using additional special notation for exceptions to that convention. Prefix notation, postfix notation, and object oriented notations such as can be had in Ruby, all avoid that problem by making order of operations self-evident due to a single, simple set of self-consistent rules, in which only the most basic expression form is convention rather than natural consequence.

    I wonder if there’s a language out there that eschews that traditional infix arithmetic notation stuff entirely, and uses Ruby’s non-arithmetic OOP notation style for arithmetic operations instead. It seems there must be, but then of course I wonder if it’s any good in any other ways.

    Comment by apotheon — 6 January 2008 @ 11:41

RSS feed for comments on this post.

Sorry, the comment form is closed at this time.

All original content Copyright Chad Perrin: Distributed under the terms of the Open Works License