Tag Archives: coding

Prefix, Postfix, Newfix, Bluefix

My, my, look at all those notations. You can infix: 2 + 2. You can prefix: + 2 2. You can postfix: 2 2 +. All three notations are perfectly arbitrary for the purposes of mathematics. (2 + 2) * 3 = 12, so what’s really different about these codes?

Code 1

x = 2 + 2
y = x * 3
print(y)

Code 2

x := 2 plus: 2
y := x times: 3
y print

Code 3

2 2 + 3 * print

Code 4

(let* (
   (x (+ 2 2))
   (y (* x 3)))
      (print y))

Code 1 is typical of procedural programming (Python1, C, Basic, Pascal). You declare variables, store data in variables, and display variables.

Code 2 is typical of object oriented programming (Java, C++, Ruby2, Smalltalk2). You instantiate objects, send messages to objects, and display objects.

Code 3 is typical of stack programming (Factor, Joy, Forth). You push values onto the stack, push functions onto the stack, and display the stack.

Code 4 is typical of functional programming (Haskell, ML, Erlang, Lisp). You pass expressions, evaluate expressions, and display expressions.

But what’s really different?

Codes 1 and 2 are fundamentally the same: they’re stateful computations. Code 1 stores state in variables, Code 2 stores state in objects, but it’s all the same. Code 2 is syntactical sugar for Code 1. And Code 1 is syntactical sugar for:

Code 0

add x,2,2
mul y,x,3
put y

In other words, you’re still explicitly performing register transactions. Do this calculation then STORE THE RESULT IN HERE. Do that calculation then MOVE THE BYTES TO THERE.

By contrast, Codes 3 and 4 are an island all their own: they’re functional computations. Instead of manipulating machine registers, they manipulate mathematical expressions3. Code becomes data becomes code again; you can pass functions as arguments to other functions as if they were pure mathematical constructs. Code 4 named the expressions “x” and “y”, while Code 3 didn’t, but as Code 3 shows, naming isn’t really necessary, it’s just a convenience.

So what’s really different? Functional programming provides a whole new level of abstraction, one that allows you to write more complex code than you could in low-level languages like Java. Really. Do you like moving bytes around, or would you prefer to leave that as an exercise for the compiler?

1 Python has functional elements, but they’re underused. Most Python programmers aren’t even aware that Python has list comprehensions and anonymous functions.

2 Ditto for Ruby and Smalltalk. They have blocks, and therefore can do functional programming, but it’s not emphasized. With all the OOP hullabaloo, the incentive is to write stateful methods instead of pure methods, especially in Ruby where the line between f and f! blurs because the result of the last evaluated expression is always returned.

3 Most functional languages have stateful capabilities, but they’re strictly only necessary for specialized calculations such as pseudo-random number generation, concurrent programming, and I/O. Also, functional language compilers must be stateful in order to compile functional programs that provide the abstraction of pure, stateless code. (see Haskell).

Haskell Type Transparency

program it patrick

Coding is often a matter of looking up API calls, chaining them together, and outputting the result. In a dynamically typed language like JavaScript, it can be difficult to determine exactly what kind of thing a function returns. For example, a JSON parsing library might have the function:

function parse(data) {
   ...
}

According to the docs, parse() takes JSON text and turns it into a JSON object. But will parse() return a tree literal? A manipulable JSON object? A callback that returns a JSON object? Does parse() return anything at all? Does parse() modify data in place to become a JSON object? What is the type of data anyway? A string? A URL to a location containing a string?

In statically typed languages, types are more transparent:

parse :: String -> Tree String
parse = ...

This Haskell code defines parse as a function which accepts a string and returns a tree of strings. No more slogging through Google results just to see how to use API calls. Haskell’s type strictness is a blessing in disguise; although it may seem inconvenient to specify types up front, in the long run, the code is more readable and more robust.

There’s the JavaScript bayou of playtesting combinations of o.foo(), o.bar(), o.foo(o.bar()) in the interpreter until o responds to one of them.

There’s the scurvy C, where data is could be a long, or a pointer, or a pointer to a pointer, or NULL. The type system is more what you’d call “guidelines” than actual rules.

Then there’s the calm, steady stream of lucidly typed Haskell.

top: The poor man’s performance analyzer

hunchentoot logoFor the sake of the future of all mankind, I wrote a tiny web server for proving that Hunchentoot works with certain system specs. “doeshunchentootwork” is only 77 lines long, serves a singe page and its favicon, and the application is compiled, not interpreted. So why does top show it using so many CPU cycles?

Daemonization may have been a bad idea, at least this early in development. The process spends a lot of time… doing what exactly?

Since the app is only 77 lines long, debugging wasn’t that hard. Long story short, CL loads the program and quits, so I was using (loop) to keep the program running. I know, I know, terrible. (read) is a better choice, since it doesn’t waste CPU by looping but merely blocks for command line input that will never arrive to a daemonized web server.

With the new code, top shows almost no activity for doeshunchentootwork unless someone is currently requesting the webpage. Whew! Now the resources can be wasted on other servers.