MarzhillMusings

Learning Erlang

Published On: 2007-09-17 03:21:21

I've taken on the task of learning erlang. I was trying to decide between learninng Haskell, OCaml, or Erlang. OCaml, I decided against since it had too close a similarity to C and I wanted to really stretch myself. Haskell and Erlang both fit that bill however I found the Erlang Documentation to be far better for someone completely new to the functional programming world. Haskell's idea of a tutorial tried to cover too many concepts at once and took too long to get to the hands on stuff. Also erlang offered the opportunity to learn Distributed programming concepts along the way so erlang it was. You can see my first erlang project etap here.

Error handling (Erlang vs Other languages)

Published On: 2009-04-11 09:59:12

When I'm in Perl, Javascript, Java, or any other programming language I prefer to throw exceptions rather than return errors. This is because I've long since gotten tired of losing errors 5 calls deep in the code because I forgot to check the return and handle it. Nothing is more annoying than trying to debug a problem that is actually caused somewhere else, but you don't know because the error vanished into the that Great Heap in the Sky around about 5 calls down. You've been there before. That's when you start adding print statements followed by an exit or, if your lucky enough to have one, firing up the debugger and using break statements to narrow down the actual source of the problem. This process could take days depending on how far removed from the breaking code the actual problem is. In erlang, however, returning errors actually turns out to be useful. This is because in erlang returning errors actually has the desired effect. Usually, when you return errors in an app, it is because you don't want to kill the whole program when something breaks. What you intend is for the caller to inspect the return and do the appropriate thing. This however runs smack into the whole

programmers are fallible people, who sometimes stay up late coding at 3am, when they can hardly see the screen anymore
problem. In short you are depending on the caller to honor your contract and do the right thing even though we often do exactly the wrong thing. Even when you are the caller, sometimes you don't honor that contract. Then a month later you are doing that print statement and die or perhaps the debugger dance again. All of this because of one night when your judgement lapsed. Companies will often develop elaborate style guides, testing strategy, and code-review cultures to prevent this, but in the end most developers I know come to love throwing exceptions... unless they are coding in erlang. This is because of two elements of the erlang language design:
  • Pattern Matching
  • and Fail Fast.
In erlang returning errors requires the caller to handle them. If I try to store the return of a function and it doesn't match what I told it to expect then bang, an automatic exception. However, if I try to store the return and explicitely handle the error case then no exception is thrown. This has the wonderful effect of forcing me to think about exactly what I expect this function to return, and handling or ignoring at my choice. The big benefit is that I had to think about it. The below example illustrates the difference.

The combination of Pattern Matching and Fail Fast in erlang forces the programmer to honor the contract, whether he wants to or not. This is one case where Erlang follows the "Do What I Need Not What I Want" principle in a language properly.

Demo of Iterate! erlang project number two is up

Published On: 2009-04-11 22:08:25

Iterate! is my Scrum style project management tool. Inspired by my dislike for XPlanners UI. Iterate! was started about a month ago and is coded in erlang using mochiweb, and nitrogen. Kick the tires and whatnot if you want to see it in action: http://iterate.marzhillstudios.com:8001/

Mnesia and Schema upgrades.

Published On: 2009-04-16 19:41:41

I had an epiphany or sorts the other day. While working on iterate I realized that I was going to need to upgrade the schema of my mnesia tables. Schema changes on databases often mean bringing down the application. At least they usually have in my experience anyway. I hate to upgrade databases. That is I did until I met erlang and mnesia. The issue is that my mnesia schema for some tables was using a user provided name for the primary key. This was fine while it was just a prototype but now it was time for it to grow up. The record describing the table had to change and all the records in a table had to change. Now no one is really using this right now so I had a choice.

  • Blow away the database and rebuild it.
  • Be all erlang'y and stuff and do it live.
Wait a minute did he just say "live"? You can't update the schema and convert all the records live. That's crazy! Ahhh but this is erlang we do things different here. Witness the glory of iterate's dbmigratetools:

Notice, the transform_stories function. It defines an anonymous fun it uses to transform the mnesia table with. Currently this function only has one signature. There is no reason it can't have more thoug. Since, erlang allows multiple signatures for anonymous functions, I can specify a signature for the next version of the mnesia table if/when it changes again. Here's the epiphany part. I can keep updating that fun with more signatures for each version of the table. Theoretically ,if I were to end up with a table that had records of multiple different historical types in it, I would be able to use this one transform function to get them all updated to the new record type. And I can do this all live without taking down the database or app. I can ship each iterate version with a module capable of updating the database live from any previous version. Now that's power that's useful. Try doing that with another platform.

Functional Programming vs OO Programming

Published On: 2009-04-26 20:52:39

I've been thinking lately about the differences between OO and FP. FP languages don't really support the OO model because of a difference in design. Some try but the "true" functional languages make no such effort and for good reason. One of the primary principles of OO programming is the black box. An object is meant to represent some entity in the system. All the state and valid actions for that entity are encapsulated in the Object and the only visibility you have into them is the interface the object provides to the outside world. Programs tend to be defined as a set of interactions between objects. FP takes a different approach. In FP data is not modifiable only transformable by functions. In FP the functions expect certain input and give back certain output for that input. They certainly don't maintain any state on their own. You can't have an object if you can't have modifiable internal state. In OO you are encouraged to group together state and activity on that state. In OO you don't think so much about state as you do about entities. Person, Car, ATM machine. All of these are commonly referenced objects in an OO tutorial or textbook. Consumers of your object are encouraged not to think about the state of a person or a car or an ATM machine. Instead they think in terms of allowable interactions with that object: Talk, Drive, Withdraw Money. Within OO code there are a huge number of possible orders of various interactions possible. So large they are just about impossible to completely test or even visualize. For example say I'm programming a person object. I've given the person object a handshake method. However, depending on the internal state of the person object that method may or may not work the same way or be supposed to be called. Maybe the person object is in a bad mood, in which case the handshake method is non-functional. How do we handle that? Hrmm, so first before calling handshake on the person object we should call the offer hand method. No wait, before we call the offer hand method, perhaps we should look at their face first to gauge their mood. This could get complicated pretty quickly. Furthermore there is nothing in the OO language that allows us to specify that the offer hand method should happen first. We obviously need to know quite a bit about the state of that person object in order to properly interact with it. Contrast that with an FP approach. This gets a little bit simpler for some people to visualize suddenly. Rather than an object, they see state and a set of possible transformations of that state. the state may be something like this. person1 mood, person2 mood. and there is an interact function. If the person1 and person2 mood is good then the interact function offers hand for handshake and the two shake hands then interact returns the new person1 mood and person2 mood. Or if the mood of one of them is bad then do some other action then return new person1 mood and person 2 mood. By placing the emphasis on the state involved the coder has reduced the problem to a set of possible transformations based on that state. In OO, an object's methods define the interface. but passing the same input to an object will not always result in the same output. Most of the time methods modify internal state and the return depends on the internal state. At any time in your code the internal state of an object must be treated as an unknown. This means the return of your objects method must also be treated as an unknown. Every object has to treat every other object like it has some sort of mental disease and could have a psychotic break any moment. It could do just about anything and if you didn't define the proper response to what they do then who knows what might happen. In FP you are encouraged to think in terms of state transformations. You are forced to consider what the state you are dealing with is and then transform that state appropriately. Since the state is of primary importance after a while FP feels more natural than OO to certain mindsets. I'm discovering that I rather like the FP mindset and miss OO less and less these days.


Glossary:
FP
Functional Programming
OO
Object Oriented