Sunday, June 30, 2013

BuddyChat, a Simple Example of Akka Actors with an Akka FSM

I wrote a silly chat program in Scala to demonstrate functionality provided by something called "Akka", which is available for both Scala and Java.  It lets you easily write your program so that:

  • Everything is asynchronous, which means that things can be run at the same time when possible.  If two people want to say hello, let them say hi at the same time.  Those "hello" messages will be be displayed when they arrive, in whatever order.  Being able to run things in parallel is massively important when a computer has more than one processor, or some things might have to wait to complete, such as, perhaps, searching for a Wikipedia article.
  • Asynchronous programming is safe.  With "lower-level" implementations, it's very easy to screw up, and your software, although perhaps faster, will be prone to crashing or generating erroneous results.

Without further ado, let me introduce you to BuddyChat!  It's ugly and it's silly, but it's educational.  For people who want to see it on github.com, it's publicly available here:

https://github.com/sdanzig/buddychat

And here's a sample test run:



Description


The "gist" of this is that you're participating in a chatroom.  You run BuddyChat.  BuddyChat creates the manager of the chat.  This manager will create all the participants, both automated and human.  The one human participant it creates represents you and will provide you an interface to make it speak in the chat room.  Whenever a participant speaks, the message goes to the chat manager who forwards the message on to the other participants.

There are a couple other little features I'll describe later, but that's the brunt of it.  Here's a diagram showing this:
Aside from the slightly different names, and a couple of the messages, it's exactly as described.  The arrows represent both the actual construction of the objects, and also sending messages between them.


Construction


  1. The BuddyChat object is automatically created when the application is run.
  2. The BuddyChat object builds ChatManager.
  3. ChatManager builds the three BuddyActors (the automated chat participants)
  4. ChatManager builds UserActor.
  5. UserActor builds ConsoleActor, which accepts input from you.

Messaging


  1. BuddyChat starts off ChatManager with a CreateChat message.
  2. ChatManager receives CreateChat, then constructs the participants.
  3. ChatManager starts off all participants with a Begin message, which all but UserActor ignores.
  4. UserActor starts off ConsoleActor with an EnableConsole message.
  5. ConsoleActor sends each line of text you type as a MessageFromConsole message to UserActor.
  6. UserActor will send this text in a Speak message to the ChatManager.
  7. ChatManager will record the Speak message to its history, then forward it onto the BuddyActors.
  8. In response, each BuddyActor generates and sends a new Speak message to ChatManager.
  9. ChatManager will record each Speak message to its history, then forward them to the other participants. The BuddyActors will see the new messages are not from a human and will ignore them. The UserActor prints out the message to the screen.

There are also other messages UserActor can send ChatManager:

  • KillChat - Shut down the chat application.  Generated when UserActor receives "done".
  • StopChat - ChatManager will clear its chat history and stop accepting Speak messages.  Generated when UserActor receives "stop".
  • StartChat - ChatManager will resume accepting Speak messages. Generated when UserActor receives "start".

ChatManager's Finite State Machine (FSM)


I love finite state machines.  Let me explain what it is:

Something can be in just one out of a set of states.  When in a particular state, it behaves a particular way. When a particular condition is met, it can transition to a different state.

That's it.  They make it very easy to model potentially complex software.  Just think of what your possible states are, and what it takes to get from one state to another.  I implemented ChatManager as a finite state machine.  The states it can be in are:

  • ChatOffline
  • ChatOnline

By default, ChatManager is in the ChatOffline state.  Upon receiving the CreateChat message, it transitions to the ChatOnline state.  Receiving StopChat and StartChat messages will cause ChatManager to transition to ChatOffline and ChatOnline, respectively, if not already in the target state.

Given this, there's a negligible hiccup that occurs because, in response to a CreateChat message.  ChatManager will create a UserActor, then can send it a Begin message just before transitioning to ChatOnline.  What this means is, for a very short but existent period of time, the UserActor can send a Speak message while the state is still ChatOffline, which would consequently get ignored.  Akka provides you a way to specify something to occur during a particular transition.  In this case, ChatManager sends out the Begin message on the transition from ChatOffline to ChatOffline.


Finite State Machine Data


Okay, I lied, there's one more complexity to at least Akka's version of FSM, which I used.  Akka works very cleanly if you adhere to the design and don't use anything that's "shared".  By this, I mean you're not supposed to let things write information/data to the same place at the same time, or even read the same data if it could change at any point.  The way Akka actors (which all those Actors mentioned before, plus ChatManager are) can safely communicate are through messages.  Just like the Begin message wasn't sent out until in the ChatOnline state, it's possible to also ensure that a piece of data changes at the same time the state changes.  ChatManager uses this data-handling to manage its list of chat participants, and the chat history.


The Code


The source code for BuddyChat is available at:
To start, we'll look at the first thing that does something...

The BuddyChat Object


The first line shows how, in Akka, an actor is created.  "manager" is a unique name you can use to refer to the actor later.  It's not meant to look pretty, and adheres to a number of restrictions, such as having no spaces, but I use it for display purposes in this demo so I don't have to bother with storing a more visually appealing name.  The second line is sending a basic message to ChatManager, to tell it to get things started.  It's quite possible to send just Strings as messages, such as:

manager ! "create chat"

However, by having a specific message class "CreateChat", the compiler can warn you about typos.

ChatManager


ChatManager starts off as follows:

ChatManager inherits the functionality of Akka's Actor, and it's given the FSM trait, which allows it to operate as a finite state machine.  The number of automated participants is controlled by this hard-coded constant.  ChatManager is initialized as being in the ChatOffline state, and with no users and no chat history.  Not even empty lists, which is why it's simply Uninitialized.

Akka's structure for handling messages when in a state is quite intuitive.  It follows the paradigm: "When in state A, handle messages of type 1 this way and messages of type 2 that way."  See ChatManager's logic in the ChatOffline state:

As you can see, when offline, ChatManager can handle a CreateChat message and a StartChat message.  I won't dive too much into how case classes work in Scala, but I will point out that you don't just see "case CreateChat" here.  You see "case Event(some message type, some state data)".  This is being used not only to respond to a particular incoming message, but also to read in the state data.  It's possible to also have it respond to a message type differently depending on what your data is.  In this case, we know we only want to respond to CreateChat messages when the data is Uninitialized, so we specify this.  This ensures that if we erroneously get a CreateChat message after the chat has been created, the message will be ignored, because although the message type matches CreateChat, the state data does not match Uninitialized.

Upon reception of CreateChat, ChatManager instantiates the sole UserActor, named "user", and the three BuddyActors.  The combination of the two,

user :: list

becomes the new state data upon transitioning (going to) the ChatOnline state.  CreateChat is one message, when there is no state data, that can provoke this transition.  The other is StartChat, but only if the chat participants are already created.  That stipulation is reflected by ChatData(chatters, _).  The underscore is a placeholder for the chat history, used to convey indifference to what, if any, chat history exists.  Checking the list of chatters alone is sufficient to ensure StartChat is processed only when it should be.  Upon processing a StartChat message, ChatManager will transition to the ChatOnline state, retaining the list of chatters, and creating a new, empty chat history (List[String]()).

As mentioned before, ChatManager has some logic for immediately after transitioning from offline to online, to avoid the window of time when a UserActor can send a Speak message when ChatManager is still offline (and thus being ignored):

While the automated BuddyActors ultimately ignore the Begin message, because they only send messages in response to the user anyway, the UserActor, upon receiving a Begin message, will instruct the ConsoleActor to start receiving keyboard input.  One more quirk here.  This part:

(Uninitialized, ChatData(chatters, _)) <- Some(stateData,nextStateData)

What that is doing is ensuring the Begin message is only sent out when the chat participants are first created.  The state data goes from completely uninitialized to existing state data complete with a list of chatters.  If the change in state data doesn't match that, then nothing happens during the transition.

While in the ChatOnline state, ChatManager uses this message handling logic:


In this state, ChatManager can now accept Speak messages.  Upon receiving a Speak message, ChatManager will forward the message to all chat participants except (different from) the sender, which is where the "diff" is applied.  "forward" is used to re-send the messages rather than the typical ! because forward will send the message as if it were from the same "sender".  Akka allows you to, upon receiving a message, access the sender of that message, and if ChatManager used !, it would appear that ChatManager originated the message.  This allows the message receiver to handle a message in a different way based on who sent it.

When writing BuddyChat, I initially allowed BuddyActor to respond to all incoming messages, but ultimately the problem arose where all the BuddyActors responded to other BuddyActors repeatedly and endlessly.  By only responding to messages where the sender has the name "user", the BuddyActor is assured to avoid this issue.

Note Speak does not cause a transition.  ChatManager will "stay" at its current state.  However, it uses updated state data (ChatData) which has a chat history that includes the new message.

ChatManager also can receive a StopChat method while in ChatOnline state.  This will cause ChatManager to go to "ChatOffline" state, and while the list of chatters are preserved in the new ChatData, the chat history is replaced by an empty list of messages.

When there is no case that matches the message in the handler for the particular state, the message is dealt with in the whenUnhandled block:

In either state, ChatManager should be able to handle the KillChat message, so it makes sense to receive it here.  While whenUnhandled certainly can deal with messages that are unexpected in the current state, the fall-through logic that leads messages to whenUnhandled makes it a perfect place to handle messages that are treated the same in any state.  ChatManager does not have to clean up any resources upon shutdown, so it can call context.system.shutdown to end the application immediately.  Just for demonstration's sake, ChatManager prints out the entire chat history first, summarizing who said what.  Note that when ChatManager stores text from Speak messages, it prepends the name of the actor that generated the message.

If a message is actually unexpected, there is a catch-all handler that will log the message with current state data as a warning, but otherwise do nothing.

UserActor


A UserActor is constructed by ChatManager when it receives a CreateChat message.  Upon creation, the UserActor will create a ConsoleActor.  Very soon after UserActor is created, ChatManager will enter ChatOnline state then pass it a Begin message.  UserActor is not a finite state machine.  It will respond to the same set of messages the same way no matter the circumstances.  The messages are handled by UserActor's receive method:

Upon receiving a Begin message, UserActor sends an EnableConsole message to ConsoleActor it created.  If the UserActor tried to wait for user input directly (which I initially tried to do), it would not be able to receive any further messages.  Why is this?
An actor in Akka has a message queue which is processed one message at a time.  Waiting for keyboard input is a "blocking" operation, which means that execution ceases until keyboard input is received.  Because you need to repeatedly wait for the next line of input in a loop, the Begin message handler would never exit.  It would just repeatedly end up waiting for keyboard input.
The solution is to let ConsoleActor handle it.  If ConsoleActor receives one message and then endlessly waits for user input, this is okay, because it's running in another "thread of execution".

UserActor, after enabling the console input, will wait for an incoming MessageFromConsole.  If the text encapsulated by this message is one of the following, there is special handling:

  • "done" - Upon receiving this, UserActor will send ChatManager a KillChat message to shut down the chat system.
  • "stop" - UserActor will send ChatManager a StopChat message to disable the chatting and clear the chat history.
  • "start" - UserActor will send ChatManager a StartChat message to re-enable chatting.

If the text does not match any of those, UserActor will encapsulate the text in a Speak message and send it to ChatManager, allowing the user to communicate with the other chat participants.

From the ChatManager, UserActor can receive Speak messages which would have originated from other chat participants (BuddyActors) and then been forwarded by ChatManager.  Because the Speak message  was forwarded rather than resent, the sender is the actor that generated the message, not the ChatManager that directly sent it to the UserActor.  This allows the UserActor to pull out the originator's name to identify the sender of the message for display purposes (labeledText).

There's one more nifty thing to mention about this "matching" methodology in receive.  Later you'll see the declaration of the messages that are passed around between actors.  If all of the messages that an actor can receive have a "sealed trait", then whenever you are handling a message with this trait, Scala can confirm that you have handled every possible message that has this trait.  This is called "checking for completeness" in a pattern match.

ConsoleActor


ConsoleActor's sole purpose is to accept input from the keyboard and send it to the UserActor in a MessageFromConsole message.

It receives one message, EnableConsole, and then displays instructions enters the loop that accepts lines of input from the keyboard.  For each line, a MessageFromConsole message is sent to the UserActor, which ConsoleActor identifies as its "parent", since UserActor created it.  The only thing that can exit this loop, is when "done" is typed.  That fancy getLines.takeWhile is generating a "stream", which is a feature in Scala.

A stream can be iterated over just like a list, and each element is generated on the fly.  The takeWhile, upon detecting a value that doesn't meet a condition, will make the for loop think it's just reached the end of the list, instead of processing the nonconforming value from the stream.

After the loop has terminated, "done" is sent to UserActor to shut down the chat.

BuddyActor


BuddyActor's sole purpose is to respond to messages from UserActor.

testJust to make BuddyActor interchangeable with a fully functional UserActor, BuddyActor handles all the messages that a ChatManager might send to any other chat participant, such as UserActor:  Speak and Begin, although it will ignore the Begin message.  In the Speak message handler, the message is also ignored if the sender's name is not "user".  This prevents a BuddyActor from endlessly conversing with another BuddyActor.  When responding to a Speak message, BuddyActor will randomly generate one of three silly responses, including the text from the received message in the reply.  This inclusion is mainly to prove that BuddyActor is successfully receiving the forwarded message from the UserActor.

The random number generator, "rand", uses a "seed" that is affected by the current time in milliseconds along with the "path" of the actor, which must be unique amongst actors.  Without a random number seed, the random number generator would generate the same sequence of numbers.

Messages


The messages passed between actors are defined as follows:

The messages are given traits such that all possible messages an actor can receive share a common trait. If you accidentally remove the handling for a message in that set, the Scala compiler will warn you.  The "sealed" keyword means that all the possible classes that use that sealed trait are in the same file.  This allows the programmer to guarantee that all messages which use the trait are accounted for.

There are two subtleties used here while defining these traits:


  • A message class can have more than one trait.  The Speak message is a ChatParticipantSystemMessage and a ChatManagementSystemMessage.  That means, respectively, that it's one of the messages that a chatter can receive, and also one of the messages that ChatManager handles.
  • A trait can have another trait.  By saying that a ChatParticipantSystemMessage has the UserSystemMessage, you're saying that the set of messages with the UserSystemMessage trait is equal to or greater than the set of messages with the ChatParticipantSystemMessage trait.  Any message with the ChatParticipantSystemMessage trait also has the UserSystemMessage trait, so the set of user system messages are at least that set, and perhaps more.  In this case, there's one additional message that a UserActor can receive that the other chatters (the BuddyActors) can't receive.  The MessageFromConsole is from ConsoleActor.  ConsoleActor only communicates with UserActor, so this makes sense.


Conclusion


The BuddyChat system certainly is only meant to serve educational purposes.  However, it demonstrates many very useful technologies within both Akka, and Scala as well.  Programmers no longer need to fear multi-threaded programming as long as they properly use an actor system such as provided by Akka.  Akka's FSM can simplify the implementation of a complex system by grouping its behaviors by its possible states.  While the significant overhead of the actor framework is not suitable for applications requiring maximum performance (such as handling billions of tweets or time-sensitive stock ticker updates), in which case lower-level handling of parallel execution is recommended, Akka actors are amazingly easy to deal with and should be used otherwise.


Notes


I'm unsure if there's a way to do some form of completeness checking in the FSM handlers.  I'd guess not, but please let me know if there's a way.
I tried implementing the check for the name "user" as a guard in the pattern match:

case Speak(msg) if "user".equals(sender.path.name)

I had a case Speak(msg) after that to catch the other Speak messages and ignore them.  However, this disabled the completeness checking.  I saw in older versions of Scala that guards were handled improperly and this had been fixed, but perhaps the change was reverted, or, more likely, I'm doing something wrong.

Thursday, June 27, 2013

The Optimization of Java's HashMap class

Yesterday I was on Quora.com sifting through some Q&A and I ran across someone describing an optimization that was made in Java's HashMap class, according to the poster around version 1.4.  It was simple, yet it amazed me.  I didn't understand how it could work at first, but with a little digging, I figured it out, and it's simple yet very clever.  First I'll briefly explain some of how a hash map works, for the laymen (I think everyone can understand most of this), then I'll go on to describe the change.


Description of What a Hash Map is

A hash map is a way a computer can store a set of things in memory for quick access.  Picture I had a function that took a word, let's say "bird", and converted it to a number, such as 7.  As long as you had the same input, you'd always get the same output.  So when you wanted to access a bunch of information with the label "bird", you can find it in storage bin number 7.  You only have to look in one bucket, so it's super-fast.

Optimally, your function will have a unique number for every unique word.  Ideally it would, but the function might not be perfect, and if "bird" and "potato" both produce a 7, then if you want to look up either, you might have to check two spots in memory instead of one, which takes longer.  This is called a "collision", and you want a function that avoids them as much as possible.

Now, it's true that if you had a billion words, it's unrealistic that your computer could have a billion separate spots in memory to hold it.  But your function produces unique numbers for nearly all of them, so you ultimately want the hash map to have a place for each number.  What a HashMap will do is take the number of spots in memory it DOES have (let's say 16), and divide the number output of the function by it, and use the remainder instead.  This is the "modulo operation", represented by the percent (%) sign.  That way, you're never trying to put something in a memory location that your hash map can't support.  So if your function said "banana" should go in spot 39, then you'd see 39 % 16 = 7.

Certainly you're going to have plenty of collisions, but there are a couple of key optimizations that can be made.  First, you want the function to spit out numbers that are as evenly distributed as possible, so you don't have a bad scenario where you're searching through most of the words because they all resulted in, for instance, the number 7.  There are formulas provided by others who have thought this through already, so just use those.  Secondly, when the hash map gets too full, it will increase the number of spaces available, and move all the old words to their new locations based on the new number of "spots".

Just so you can talk the talk, the spots in memory a hash map has available are called "buckets".  The function that converts words to numbers is called a "hash function".  The numbers are called "hash codes".  The words are called "keys", and the "bunch of information" attached to a key is called a "value".


Java's Hash Map Optimization


The above modification shows the change, but it's dependent on a couple of other behaviors of the Java hash map.  First, I'll review what's going on.  I mentioned how modulo is used to determine what bucket a specific hash code maps to.  This is replacing that modulo with a "bitwise AND".  I'm not going to review too much about binary here, but it's all 1's and 0's instead of 0-9 like the base-10 (decimal) numbers you're used to.  So if you have 1 & 1, you get 1.  But if either or both is a 0, you get 0.  Picture converting the hash code and the number of buckets to a bunch of 1 and 0 "bits", then doing this AND operation on each bit, from right (least significant/smallest) to left.

If you think about it, you might wonder how this works, because it's not the same thing as modulo.  If you have 5 buckets, you're converting 4 to binary -- 100 (google "4 in binary").  That means whatever your hash code is, only the third bit will matter because the other bits will be ANDed to 0.  indexFor will always output either a 0 or a 4.  That will be a crazy amount of collisions.

First Trick


There will never be 5 buckets.  Java's hash map implementation, when expanding, multiplies the number of buckets by 2.  You'll always have a power of 2 (1, 2, 4, 8, 16, etc).  When you convert a power of 2 to binary, you only have one bit as a 1.  When you subtract 1 from a power of 2 and convert that to binary, that bit is a 0, and all the bits to the right of it are 1.  Try ANDing a bunch of 1's with anything and you get the modulo of what those 1's represent in decimal plus 1.  ANDing bits like this is much faster than doing a modulo, which requires division and subtraction.

Second Trick


There's also a concern which might not be obvious, but if you are relying on only the smallest bits of your hash code, you can easily get an uneven distribution of keys in your buckets unless you have a really good hash function.  What Java's hash map implementation does is to "rehash" the hash code.  Check this out:


This scary thing takes your mostly unique hash code and randomizes it in a way that has a relatively even distribution in the "lower bits".  For curiosity's sake, I'll mention that the >>> is shifting the bits in your hash code to the right... so if you had a 4, or 100 in binary, and you did 4 >>> 2, you'd end up with 001, because it's been right-shifted twice.  The ^ is an "exclusive OR" operation, which is similar to the AND operation, but it outputs a 1 if the two bits are different (one's a 1, and the other is 0).  Essentially this thing is ensuring that the more significant bits in your hash code are affecting the least significant bits that you're ultimately going to use to choose each bucket.


Hope you found this all as righteous as I did!

Monday, June 17, 2013

The Option Design Pattern

When starting to learn Scala, front and center was the utility of the Option design pattern.  I think it's useful, but at first it's fairly unwieldy, and it's much more useful when you know how to reasonably work with it.
The problem the Option pattern attempts to solve is the frequency of the NPE (null pointer exception), certainly a constant thorn in the side of every Java programmer. The problem is that you're mixing the valid range for a value with something that is invalid, "null". By allowing this combination, anyone who uses your provided value must be aware and provide accommodation for the possibility that this "I am invalid!" placeholder can occur.  There are no safeguards indigenous to a language such as Java, so if you forget to handle this, your software can exhibit an error at runtime.
The Option pattern removes the placeholder from the range of possible values by wrapping it in an "Option" object. This object can be one of two derivative classes: Some, or None.  If it's a "Some" object, it has a value that's guaranteed to be in the valid range.  If it's a None object, it represents the "absence of a valid value".
Scala cleanly handles Option objects via pattern matching.  For example, talkAboutValue is a simple method that takes an Option object, and displays a value if it's something, and doesn't attempt to display a value if it's nothing:

Scala displays a compile-time warning if None is not handled in talkAboutValue's pattern matching, encouraging comprehensive handling of the input. The input for the talkAboutString method is not an Option, so it's expected that the input will be a valid String.  This allows the programmer to confidently call the length method, without worrying about an NPE.  You can still input a null to talkAboutString, and handle the null value the Java-way (e.g. if(str==null) {... ) but Scala discourages this.
A very inescapable instance where Scala makes use of the Option object is with its implementation of Maps.  When you query a value, it's either in the map or it's not.  If it's not, rather than returning a null value like you may have been accustomed to in a language like Java, Scala returns a value of None.

Unfortunately, even for a lookup resulting in a valid value, you still have the Option object "wrapper" to deal with.  That means you have to do not only the "get" for the lookup, but another to get the actual value. An "if(val != null)" seems much easier than doing a pattern match every time.
Fortunately, Scala alleviates this via facilities in its core API. The most obvious is "getOrElse".

This doesn't alter the handling of the value if a lookup is unsuccessful, but it does at least provide a default value, which may be appropriate in many situations such as a default configuration setting. Another very common use case is handling a list of Options resulting from iterating over a collection:
It's not so bad in this single-use instance, but if you plan on using a collection of Options repeatedly, you may wish to preprocess it, to remove the wrapper objects:

Flatten results in a list of just the unwrapped values in the Some objects.

Flatten is the same method that can concatenate the lists in a list to a single list. E.g. List(List(1,2),List(3,4)).flatten results in List(1,2,3,4). If you care, the way flatten is able to operate on a list of Options is because of an implicit method, option2Iterable. An option can be converted to a list of 0 or 1 elements (0 for None, 1 for Some) with its toList method. This implicit method is called by flatten, resulting in the same treatment as a list of lists:
implicit def option2Iterable[A](xo: Option[A]): Iterable[A] =
  xo.toList
Scala, despite its infamously steep learning curve, is beautiful in the way that its implicits provide for such ease of use for common programming tasks. Along those lines, it's also common for one to have a list of values that must be passed to a method which results in an Option. If you only want to handle the iterations with successful results, such as values successfully retrieved from a map, there is another accommodation called "flatMap", which replaces a sequence of flatten then map.

You can see that the function passed to flatMap is only run on the last names that are successfully found in the map.

Two more nifty things to know.  If you pass a Java object to the constructor of Option, it will automatically wrap non-null values with Some() and null values are replaced by None. For instance, try going to your Scala REPL and type:
Option(null)

Now try:
Option(3)

And lastly, just to demonstrate how easy working with Options can be, please check out Tony Morris's nifty cheat sheet.  If you notice yourself handling an Option in a certain way, there's a very good chance Scala, or at least the scalaz library, provides you a shortcut you can replace it with:

Conclusion
In summary, I agree the Option pattern seems to get in the way when you're starting out with Scala, but in the end, it results in much safer code, free from one of the most ruthlessly frequent runtime errors of our time. Scala makes it not only available, but also easy to work with, so learn to love it!

Self Introduction

Hello internet people,
I've been a computer programmer since my parents bought me an Apple IIc when I was 7.  I'm 36 now, and my path in life, since then, went like this:
  • ProDOS BASIC, for choose your own adventure games on the Apple IIc
  • Labview for Windows, at an AT&T Bell Labs internship
  • MudOS LPC, when I ran my own MUD
  • Java, for developing a legend of Zelda-like game for Software Engineering class
  • Perl, for an AT&T e-billing system
  • Perl, PL/SQL and Java, for the backend functionality at Register.com
  • J2EE, for enterprise-networking software at Avaya
  • C, Java, Visual C++, and C#, for simulation software at CSC
  • Visual C++ and Java, for operational awareness software at Viecore FSD and then Future Skies
  • Java and C, for flight simulation software at MIT Lincoln Laboratory
  • Javascript/CSS for front end and Java with Spring for backend, transferring and accessing broadcast video at Reuters
  • Python, Flex/Actionscript, and Java, for portfolio accounting software at Hedgeserv
  • Scala, Java, Python, and Objective C, for web and mobile publishing at New York Magazine
At this point in my career, I have three main interests that serve as the motivation for this blog:
  • I am invigorated by the recent push in the world of software development toward functional, non-blocking programming.  In particular, I've absolutely loved learning about Scala recently, and plan to work towards greater expertise leveraging its capabilities.
  • I have become more attuned to the need for adherence to established design patterns, and want to better familiarize myself with them, in an effort to better exploit their capabilities given an opportunity.
  • It is difficult to stay abreast of all immediately-relevant open source technologies.  For nearly any challenge that exists in programming, I've found that someone has developed some sort of solution that will at least partially alleviate its inherent difficulties.
So, in general, that's what I'll be posting about.  Nice to make your acquaintance, don't be a stranger, and feel free to point out anything I wrote that you think is good, bad, right, wrong, misguided or silly.
Thanks for reading!