Showing posts with label object oriented. Show all posts
Showing posts with label object oriented. Show all posts

Tuesday, April 14, 2009

But, But...You Didn't Mutate Any Variables

In a private email, somebody asked of my previous article "Okay, I can see that there must be state since you've created a state machine. But you aren't mutating any variables so where does the state come from?" It's a good question. If you feel you "got it" then skip this article. But if you're still hesitant or think I'm misusing the word "state" please read on.

First, let me remind that I contend that state is 1) something responding to the same inputs differently over time as far as another observer is concerned and 2) an abstraction and not the representation. None-the-less, state always ends up with some representation. For instance, files can represent state. And even users of programs can hold state (quick, I'm in a drunken state and I plan to write a long rant, who am I?).

I want to ignore all but memory based state and show that, ultimately, even the Erlang code must manipulate mutable memory and that message sending effective leaks a little bit of that detail. Now, on Reddit an offended Erlanger called me a Java fanboy. As any of my loyal readers know, it is true that I think Java is the most incredibly awesome language EVER and I can hardly stop writing glowing things about it. But for this article I'll struggle against my natural instincts and use Ruby, Haskell, assembly, and Erlang.

I'll use Ruby to illustrate some points about state and representation. First the tired old state diagram and then some Ruby

class SockMachineSimple
  def initialize
    @state = :zerocoins
  end  

  def insertcoin
    case @state 
      when :zerocoins
        @state = :onecoin
        :nothing
      when :onecoin
        @state = :twocoins
        :nothing
      when :twocoins
        :coin
    end
  end
 
  def pushbutton
    if @state == :twocoins
      @state = :zerocoins
      :tubeofsocks
    else
      :nothing
    end
  end
end

If you don't read Ruby then Ruby control flow structures generally result in the value of their last contained expression so explicit returns aren't needed. :foo is a symbol (kinda like a string). @state declares a field (which is private) named state. I called it state because it so clearly matches to the state space specified by the diagram. But here's another way to write SockMachine with a completely different representation

class SockMachineComplex
  def initialize
    @count = 0
  end  

  def insertcoin
    if @count % 3 == 2
      :coin
    else 
      @count = @count + 1
      :nothing
    end
  end

  def pushbutton
    if @count % 3 == 2
      @count = @count + 1
      :tubeofsocks
    else
      :nothing
    end
  end
end  

Instances of this class keep track of the total number of coins or button pushes ever accepted and use the modulus operator to decide what to do about it. The representation is quite different from that of SockMachineSimple, but to anybody using this class the difference is mostly irrelevant - it still conforms to the same state diagram. Internally it has a very large number of states but externally it still has the same three. And here's one last stateful machine

class SockMachineDelegated
  def initialize
    @machine = SockMachineComplex.new
  end  

  def insertcoin
    @machine.insertcoin
  end

  def pushbutton
    @machine.pushbutton
  end
end  

By looking at the source it would appear that this version never mutate any variables after being initialized, but of course it does by calling methods on SockMachineComplex. Hiding the manipulation of representation is not the same thing as making something stateless. And now one last example, one that is totally different because it is not stateful.

class SockMachineStateless 
  def pushbutton
    machine = SockMachineComplex.new
    machine.insertcoin 
    machine.insertcoin 
    machine.pushbutton
  end
end

Internally, pushbutton uses a stateful machine but externally it is not stateful. Short of using a debugger you can't observe the state changes in SockMachineStateless's internal machine. Actually, I guess you could monkey patch SockMachineComplex to do some kind of IO or callback to expose the workings so maybe I shouldn't have used Ruby to illustrate my OO points. Too late now.

Hiding State

Okay, but that's OO stuff. Erlang is a functional language and the code never appeared to have any mutable variables or nested mutable objects. So what gives? Well, to illustrate Erlang I'm going to use Haskell, another functional language. Haskell's great advantage to this exposition is that it's really, really easy to get at some nice clean assembly.

So here's a very silly Haskell function for determining if a positive Int is even or odd. Its implementation is silly, but it allows me to make a point.

flurb :: Int -> String
flurb n = if n == 0 then "even" 
          else if n == 1 then "odd" 
          else flurb $ n - 2

This is a pure function - it mutates nothing. Yet when compiled with ghc -S -O to get AT&T syntax assembly, the function looks like this

Main_zdwflurb_info:
 movl (%ebp),%eax 
 cmpl $1,%eax
 jl .Lczq
 cmpl $1,%eax
 jne .Lczo
 movl $rxA_closure,%esi
 addl $4,%ebp
 andl $-4,%esi
 jmp *(%esi)
.Lczo:
 addl $-2,%eax
 movl %eax,(%ebp)
 jmp Main_zdwflurb_info
.Lczq:
 testl %eax,%eax
 jne .Lczo
 movl $rxy_closure,%esi
 addl $4,%ebp
 andl $-4,%esi
 jmp *(%esi)

GHC has compiled the flurb function down to a loop and the immutable n variable is represented with the mutable eax register [1]. Some pseudo Haskell/assembly mix might help illustrate

flurb n = 
         movl n, eax -- copy n into the eax register
Main_zdwflurb_info:
         if eax == 0 then "even" 
         else if eax == 1 then "odd" 
         else 
           addl $-2, eax -- decrement eax by 2
           jmp Main_zdwflurb_info  -- jump to the top of the loop

As you can see, the Haskell code does use mutable "variables" at runtime. This is a common optimization technique in functional languages for dealing with direct tail recursion. But all that machinery is hidden from you as a programmer so just like SockMachineStateless the end result is stateless unless you peel back the covers with a debugger.

Finally, Some Damn Erlang

All right, I've written Ruby and Haskell, generated some assembly, and then written in an impossible chimeric language. But my original question was about Erlang. Here's a simple Erlang counter actor

-module(counter).
-export([create/0, increment/1]).

create() -> spawn(fun() -> loop(0) end).
increment(I) -> 
  I ! self(),
  receive X -> X end.

loop(N) -> 
  receive From -> 
     From ! N,
     loop(N + 1)
  end.

Again, no variables are mutated. But if I assume that Erlang does the same kind of direct tail call optimization that Haskell does, the pseudo Erlang/Assembly loop looks like this

loop(N) ->
  movl N, eax  % copy n into the eax register
.looptop:
  receive From -> 
     From ! eax, % send the current value in eax back to the original sender
     inc eax  % increment eax by 1
     jmp .looptop  % jump back to the top of the loop
  end.

It's still a loop like the Haskell one, but there's an important difference. Each message receive sends back the current value of the mutable eax register then mutates it. So this behaves a bit like SockMachineDelegated - the original code didn't appear directly manipulate any mutable variables, but there was mutation under the covers and unlike SockMachineStateless but like SockMachineDelegated this change of state is visible beyond the local confines. [2]

Now, there are other ways to deal with recursion. I don't know Erlang's implementation, but it doesn't matter. Something is being mutated somewhere and that change is being made visible by messages being sent back. Typically non tail calls mutate the stack pointer so that it points to new stack frames that hold the current value of arguments, or then again some arguments might stay in registers. Tail calls that aren't direct tail recursion might mutate the stack region pointed to by an unchanging stack pointer. Whatever, it always involves mutation, and it's always hidden from the programmer when using pure functions. But actor loops are not pure functions. The sends and receives are side effects that can allow a little tiny bit of the mutable machine representation to be mapped to state that an observer can witness.

But Really Where Are The Mutable Variables?

So all that's fine, but it doesn't really show where the state is in my original Erlang code. The code didn't have an N to stick in a mutable register or a mutable stack frame. Here's the core of it.

zerocoins() ->
   receive
       {coin, From} ->
           From ! nothing,
           onecoin();
       {button, From} ->
           From ! nothing,
           zerocoins()
   end.

onecoin() ->
   receive
       {coin, From} ->
           From ! nothing,
           twocoins();
       {button, From} ->
           From ! nothing,
           onecoin()
   end.

twocoins() ->
   receive
       {coin, From} ->
           From ! coin,
           twocoins();
       {button, From} ->
           From ! tubeofsocks,
           zerocoins()
   end.

For this final answer I'm afraid I have to do a bit of hand waving. The explanation is even more abstract than the mutable variable as register/stack local explanation. You see, no matter what, your code always mutates one register: the instruction pointer. Its job is to point to the next instruction to be executed. As the CPU executes instructions the IP moves around, typically just being bumped up a bit for everything but jumps which move it more substantially.

In purely functional code the IP moves around but these moves can't be observed by other parts of the program as they are happening. In other words, in purely functional code, the changing IP is invisible. It's a completely black box unless you use a low level debugger. It's very much like SockMachineStateless where the internals were mutable but invisible to the outside world.

But with message receives the IP can be induced to move around based on things communicated from outside the function. The IPs current instruction can then define in large part what a message received by a process will do. If the IP points at the receive in the "zerocoins()" function then that's one behavior and if it it points to the receive in the "twocoins()" function then that's another. The different behaviors can be observed by other actors via messages sent back to them. When an actor sends a SockMachine a coin or buttonpress message it may indirectly be causing the IP to be mutated. And when it gets back nothing, coin, or tubeofsocks it's really being told, in a very indirect way, something about the value of the IP.

Conclusion

State is not the same thing as representation. None-the-less, with an omniscient view of things you can always find the representation of state. It might be in bits stored on a drive, it might be in neurons in a user's head, or it might be in a computer's memory and registers. The representation might not be directly visible in the source you're looking at but hidden in low level machinery. It might just be the instruction pointer pointing at different parts of your code base.

If you equate state with representation you end up with the very un-useful property that everything is stateful since at some level of representation every bit of executing code on your computer involves stateful processes. This view robs you of the ability to think about high level languages, especially purely functional ones like Haskell, at an appropriate level of abstraction.[3]

Purely functional code ensures that that the state represented by registers and stack pointers and instruction pointers is kept local. But side effects like message sends and receives allow that low level machinery to be used as the representation of shared mutable state even if you don't see it in your code.

In the end, it's far more useful in most cases to think of state from the point of view of an observer than the point of view of its implementation. The SockMachine actor was stateful regardless of how that state was represented simply because other actors could observe it changing state. Digging down into how send and receive allow a modicum of access to the instruction pointer just isn't a useful model for thinking about stateful actors normally. So the short answer to the original question is "Who cares how the state was represented? It was shared mutable state."

Foot notes

  1. Actually, it appears to be moving n back and forth between memory pointed to by eap and eax, which seems oddly wasteful given that it never branches out of this function. It also does 3 tests when only 2 should be necessary.
  2. Technically the Erlang code probably can't keep the current value of N in a register when calling receive since receive may cause a task switch to another process, so assume that receive copies registers out to memory before executing then swaps them back in when its done.
  3. Some people equate state with data, but that's just as bad. Code is data so all code must be stateful - another useless conclusion.

Friday, April 3, 2009

The State of Sock Tubes

Oddly, given that state is such a central notion to so much programming, it's awfully misunderstood. How do I know? Because OO programmers think they can make it private and Erlang programmers think they don't share it. If you agree with either of those statements then this article is for you.

I want to start with a simple, hypothetical vending machines. It dispenses socks in a tube, which is cool, because "tube of socks" is a huge Internet meme. Well, not yet, but will be when this article makes the front of Reddit, Digg, Hacker News, and CosmoGirl.

So, anyway, the machine has a coin slot, a button, and a dispensing tray. If you put in two coins one after the other and press the button you get a tube of socks. If you insert two coins and then insert a third you get your coin back. Same with fourth, fifth, etc. Pressing the button after putting only one coin or no coins at all results in nothing happening. It's a simple machine, but it's enough to illustrate all my points. A diagram sums it up nicely.

This is, you guessed it, a diagram of a state machine. In particular this one is a finite state machine, but that's not important to this article. So I'm wasting time by mentioning it. And more time by explaining that I'm wasting time. The diagram shows 3 states labeled 0 coins, 1 coin, and 2 coins. Between the states are arrows labeled with an action you would take to cause the machine to move from one state to another. Some of the transitions also have an action that the machine takes during that transition like dispensing foot warmers or returning a coin. The diagram assumes an infinite supply of socks. And tubes. Got it? Good. Patent pending. Onward.

Hypothetical

Imagine I locked you in the room with a bag of coins and that machine. The machine is a sealed, glossy black, and glows with a malevolent sock tube evil. Imagine there's no way for you to see what's inside, no way to know how the machine actually works. Assignment: figure out as much about its internals as you can.

Even with these restrictions, I'd bet that with only a small amount of experimenting you could easily draw something like the diagram above. I mean, if I unlocked the room long enough for you to get a pen and paper you could draw it.

True, you'd never be certain you knew all the details. It could be that after dispensing 1,000,000,000,000 pairs of socks it would reward you with a unicorn instead. You also wouldn't know if the machine was written in Ruby or Java. Er, integrated chips or discrete components. So many details could still be hidden. But you would certainly know that the machine had state and that the state changed based on actions you took.

You Can't Make State Private

So, point #1) you can't make state private. You can hide the details of how the state is represented and you can carefully control the valid state transitions and you can control who has access to change the state, but you can't make the state private. State is the fact that something reacts differently to the same inputs at different times. Sometimes putting a coin in and pushing the button does nothing but sometimes it results in a cool tube of socks. That's state. The gears and transistors are hidden, but the state is observable. If your favorite OO object has all private data but one single method does something different based on changing values in that hidden, private, super secret data then by definition state has been exposed to anything with access to that method or anything that has access to anything that has access to that method or anything that has access to anything that...etc.

Now, hypothetically the tube sock machine could have some internal counter that counts the total number of coins that has ever been inserted. But if that counter is strictly internal and can never be observed then it's not private state, it's just dead code ... er useless machinery. Make sense? Good. Patent pending. Onward.

How You Can Make State Private

Having just explained that you can't make state private, I will now explain how you can make state private. Imagine if our sock machine were sealed inside another machine which has a single button and a single dispenser tray. Further, imagine the outer machine has an infinite supply of coins in its guts. Pushing the button on the outer machine causes it to insert two coins into the inner machine, push the inner button, and then dispense the resulting tube of socks. If you were locked into the room with this machine you would never know that inside lives a Rube Goldberg state machine. You would just know that pushing the button gives you socks, every time, no ifs, ands, or buts. To an outside observer this machine is stateless. Only by ripping opens its guts would you know the awful truth.

The moral is that you can't make state private with a "private" keyword, but you can make it local. In programming world that means you can implement something stateless using "local" mutable variables. State is relative to an observer. If you can't observe it changing, then it's not state as far as you're concerned. That's why it's perfectly valid to say that the pure parts of Haskell programs are done without state even though thunks are memoized. If that was gibberish to you, I apologize, it was gibberish to me too.

The End, Or Is It?

This long ass article was really just a prequel to the real article coming soon which will explain why Erlang style actor "shared nothing" message passing concurrency is all about shared state. Shocked? Good. Patent pending.

Thursday, August 16, 2007

The Kingdom of Nerbs

In his famous rant Execution in the Kingdom of Nouns, Steve Yegge hilariously excoriates Java for being so "noun oriented" that it's difficult to express ideas that are simple to express in functional programming languages. Scala is a language for the JVM that attempts to unify the funcional and object oriented worlds using first class functions, pattern matching, and what I'm going to call nerbs.

First, a short attention span theater version of Steve's post.1

Once Upon A Time In The Land of JVM

Nouns(together): You there, verbs, get encapsulated at once!
Verbs: Oh please set us free.
Noun1 (implements an interface with only one verb): I am a verb. I am a functor!
Nouns(together): Hahahaha, what a clown.
Citizens of functional lands: Look how much power our verbs have.
Verbs: Free, free, set us free.2

So what was to be done for the poor denizens of the JVM?

To Make a Nerb

There are a bunch of language implementations that support functional programming on the JVM to one extent or another (Cal, Jaskell, Kawa, SISC, Jython, JRuby, Groovy, Rhino, ABCL, hey guys, 'sup?). Unfortunately, none of them are named Java.

For this post I'm going to pretend that Scala is the One True Answer(TM). Other answers will require their own fairy tales er blog entries. Scala is interesting because it not only supports "mere" first class functions, it also supports nerbs.

So what is a nerb?3 Good question, I'm so glad you asked. A nerb is a noun that has been verbed. If you don't believe me, go Google it. But before you do, realize that Google is a publicly traded corporation that makes oodles of cash from selling paid advertising using free web search as a loss leader. But in saying "Google it" I'm not referring to the noun that offers free donuts to its programmers, I'm referring to the verb that this noun is most well known for enabling. Hence the ever so slightly tautological definitions "Google: (verb) to search the web using a web search engine provided by Google - (noun) the company that lets you Google(verb)." 4

Before I continue, let me say that the word "nerb" does not from my close scrutiny seem to appear in any portion of the Scala language specification. But it should.

Back to my butchering of Steve's fairy tale. The verbs are clearly functions and the nouns are clearly objects.5 So a nerb would be an object that's been turned into a function. But in my version of the fairy tale, the verbs all laughed at the noun um object pretending to be a function. Why? Well, because while such beasts work they're just so, so, ... verbose and awkward. Here's one in Java:

public interface Transformer<P, R> {
  public R execute(P param)
}

public class NumberToFrenchStringTransformer 
    implements Transformer<Integer, String> {
  public String execute(Integer param) {
    switch (param.intValue()) {
      case 0: return "zero";
      case 1: return "un";
      case 2: return "deux";
      case 3: return "trois";
      default: throw new 
        RuntimeException("Je ne sais quoi");
    }
  }
}

public class Test {
  void countToThree(Transformer<Integer, String> 
      numberToStringTransformer) {
    for (int i=1;i<4;i++)
      System.out.println(
        numberToStringTransformer.execute(
          new Integer(i)));
  }
  
  public static void main(String[] args) {
    new Test().countToThree(
      new NumberToFrenchStringTransformer());
  }
}

Transformer is a generic interface that requires two types to fully specify: a parameter and a return type. The countToThree method requires a Transformer from Integer to String. The goal is that another Transformer could allow counToThree to speak in some other language, but this code only implements French. The main method hooks everything together.

For a toy example this may not seem so bad. But consider: every time you want to turn an existing function into an object you recreate a significant amount of boilerplate. Imagine writing a significant portion of a real application this way. I could have made it slightly more concise by using an anonymous class, but that would have been a minor change. Let's clean things up for the Scala interpreter.6

def numberToGermanString(n: Int) = n match {
  case 0 => "null"
  case 1 => "ein"
  case 2 => "zwei"
  case 3 => "drei"
  case _ => throw new RuntimeException(
    "Ich bin nicht ein Berliner")
}

def countToThree(
    numberToString: Int => String) =
  for (n <- List.range(1,4)) 
    println(numberToString(n))

countToThree(numberToGermanString)

The play by play: numberToGermanString is a function from integers to strings, countToThree just happens to require such a function, and the last line makes everybody go to town. It's concise and exactly to the point. In a lot of ways it's similar to any other language with first class functions. Again, I could have used an anonymous function but that would have been a minor change. Still we haven't created a nerb - at least not obviously. First class functions are more like gerunds - verbs turned into nouns.

To motivate the desire for a nerb, I ask you this: what else, when given an integer can return a string? Well, how 'bout an array of strings? I can hear you now, "yeah, but an array is a noun not a v.... hey...wait a minute..."

def countToThree(numberToString: Int => String) =
  for (n <- List.range(1,4))
    println(numberToString(n))
  
val words = 
  Array("none", "one", "a couple", "many")
  
countToThree(words)

Yup, in Scala an Array is a nerb. Clearly, an Array is a noun. But we didn't change countToThree a bit and it took the array - the array was verbed. Cool, eh? In scala, getting the 3rd element from the words array just do words(3).

So you might be thinking that arrays must get some special treatment, then, some special syntactic sugar all their own. Nope. You can sprinkle that sugar anywhere you want and turn any of your classes into nerbs.

How? Well, much like you would in Java but you use interfaces (well, traits) that Scala provides.

object NumberToSpanishStringTransformer() 
    extends Function1[Int, String] {
  def apply(n: Int) = n match {
    case 0 => "cero"
    case 1 => "uno"
    case 2 => "dos"
    case 3 => "tres"
    case _ => throw new 
      RuntimeException("Soy un sustantivo")
  }
}

def countToThree(
    numberToString: Int => String) =
  for (n <- List.range(1,4)) 
    println(numberToString(n))
  
countToThree(NumberToSpanishStringTransformer)

Obviously in this case it would be cleaner if I just used a function instead of creating a nerb. But the point here is that I CAN create a nerb - which is nice when I have a more complex class like Array. The "object" keyword means I'm creating a singleton. Function1 is an interface (trait in Scala terms) that is parameterized by two types. Think of it like a generic in Java or a template class in C++ but using square brackets instead of angle braces. The trait requires me to implement one method: apply. In other words, it's pretty much the same as the Java implementation above, except that I was able to treat my object as a function.

The Nerbs United Shall Never be Divided

Earlier I said of our first class function that we had not created a nerb "at least not obviously." Here's the punch line to my cryptic hint: whenever you use a function in a first class manner Scala implicitly creates a nerb. So this code

def numberToGermanString(n:Int) = ... 

def countToThree(numberToString: Int => String) =
  for (n <- List.range(1,4)) 
    println(numberToString(n))
  
countToThree(numberToGermanString)

translates into something along the lines of

def numberToGermanString(n: Int) = ... 

def countToThree(
    numberToString: Function1[Int, String]) =
  for (n <- List.range(1,4)) 
    println(numberToString.apply(n))
  
val $anonymousNerb = new Function1[Int, String]{
  def apply(n: Int) = numberToGermanString(n)
}

countToThree($anonymousNerb)

The byte code generated won't be exactly that but the the gist will be the same: underneath the hood Scala turns first class function creation into nerb creation. This might just seem like just an implementation detail, but it turns out that the Function1 trait provides additional methods for creating function compositions and those methods can be used anytime you create a first class unary function. It's also how Java code can interact with Scala first class functions.

The Grand Unification

In Scala, classes and objects can be turned into nerbs using the object oriented technique of inheritance. Functions and methods can be turned into gerunds using typical functional programming techniques but the gerunds turn out to be nerbs.

Nerbs are a key part to how Scala unifies the object oriented and functional paradigms. There's much more to the unification story including closures and pattern matching. I'll save those for another time.

Once Upon a Time in the Land of Scala

Unlike the land of Java the land of Scala was all peace and harmony. Verbs could be nouned and nouns could be verbed as needed. Together they held hands and sang the songs of nerbiness.

Footnotes

1. My apologies to Steve. Really, sorry dude.

2. My apologies to The Police. Really, sorry dudes.

3. Due credit - I stole the word "nerb" from Nancy Allison's "Every noun can be...".

4. To be madly self referential I would say the word "Google" has been nerbed.

5. Actually, the fairy tale draws the analogy of nouns being both objects and classes but Steve didn't make much distinction and I didn't either. I also won't make the distinction between functions and methods. Please just read on and pretend I know what I'm analogizing.

6. For compiled Scala we just need to wrap all the code in an object that extends Application. I know, I know, it's ironic after all my talk about setting verbs free, but please bear with me until I can talk about singletons.