Archive for the 'erlang' Category

On Erlang and Strings…

Friday, May 11th, 2007

I said in a recent comment that the way Erlang handles strings is wonkey, and I would like to clarify. Take [97, 97] and "aa". My brains says these are two different values, but in erlang they are the same. Type them into an erl shell and what the result of both be “aa”.

This works because it is internally consistent, and as the developer you can easily reason whether a given list of bytes is actually a string of characters. It works because in a closed erlang system, none of the code cares whether it is a string of characters or a list of bytes, it just works.

The problem occurs when you break out erlang and communicate with a language that discerns between the two. In ruby, [?a, ?a] is different than "aa". Now here is the tricky part, Erlang can encode a List in one of 3 ways:

  1. NIL_EXT: a single byte denoting an empty list []
  2. STRING_EXT: lists are encoded to this when they are less that 65535 elements in length and only contain SMALL_INT values(0-255).
  3. LIST_EXT: any other list of elements

This info can be found in the OTP source distribution in the file “erts/internal_doc/erl_ext_dist.txt”. With these semantics, [1,2,3] would be encoded as a string, and it would be totally surprising to a Ruby programmer to have that value pop out as '\001\002\003' on the ruby side. So, it’s a bit of a juggling act, and with Erlectricity I decided to take a consistent, simple road. Any erlang list, regardless of how it is encoded by erlang, gets spit out as an Array on the ruby side. Likewise, any binary value in erlang will come out as a string on the ruby side. This makes for easy use of unpack if you need to extract value, but if you are wanting a string, nothing else is needed.

This situation is less than ideal, and is one of the confusing pieces that I would like to eliminate. To do this, a framework to ease conversion and guide understanding on the Erlang side is needed. Good thing that such a framework was already planned! By putting a thin veneer over the Erlang ports, we can build upon the erlang distribution format (or build away from if needed) to find a happy equilibrium between the two differing type systems. Stay tuned for more discussion on how I approach a solution to the problem!

Erlectricity: Hi Ruby, I’m Erlang.

Tuesday, May 8th, 2007

update: this pre-release is up and running on rubyforge:

sudo gem install erlectricity

As I said in my previous article, I’m very stoked about working with Erlang. Usually most forays into new languages mean new projects and new explorations: Erlang has been no different. I usually end up in some middle ground where I try to improve the current language I’m working in with the new language: With C# -> Ruby it was a code generator written in Ruby that produced the cookie cutter DALs that I was plagued with, and this time around I immediately started to gravitate towards interoperation between erlang and ruby.

I’m not the only one with this idea (I’ve never claimed to be original), with several others working on using JSON to bridge the gap. That is all well and good, but considering how good erlang is at expressing itself across networks, I’d rather see something closer to the erlang-way. And that is why I set about creating what I call Erlectricity.

Before I go further, a code sample is in order. The following code is a passthrough daemon to Tinder, (the Campfire API gem) that lets you post to campfire from erlang. Even more before I show you the code, here is the google code site: http://code.google.com/p/erlectricity/, with the source being: http://erlectricity.googlecode.com/svn/trunk/. And now…

The Ruby:

require 'rubygems'
require 'erlectricity'
require 'tinder'

domain, email, password, roomname = *ARGV campfire = Tinder::Campfire.new domain campfire.login email, password room = campfire.findroombyname room_name

receive do match(:speak, string(:comment)) do room.speak comment receive_loop end

match(:paste, string(:comment)) do room.paste comment receive_loop end end

room.leave if room

And some erlang to call it (i’m omitting some code, please see the tinderl.erl example in the source to see the code that enables the calls below):
tinder:start("thedomain", "myemail@gmail.com", "mypassword", "theroom"),
tinder:speak("hey, hey kids!"),
tinder:paste("Im Krusty the Klown!").
At first, this was going to be a JRuby layer over JInterface, the Java -> Erlang bridge. That was all well and good, and worked fine, but it had a major flaw: It was tied to JRuby, leaving out the majority of Rubyists. JRuby is super exciting, and I was super stoked the first time I got ruby running inside a prototype game using The JMonkey Engine, but I didn’t want to be the person to exclude. I decided at this initial stage to use the Erlang port system, a means of starting and communicating with a separate process. As a consequence, I implemented most of the Erlang distribution format. Why re-invent the wheel when erlang has termtobinary and binarytoterm? Plus, it’s fun investigating the Erlang distribution format, even though only a subset is used for termtobinary.

As an aside, one reason to re-implement termtobinary and its sibling is because of the limited nature of Erlang’s type system.

You’ll also notice in the example directory ‘gruff’: 2 hours of hacking invested into rendering Gruff graphs through Erlectricity. Below is a graph generated using the stat_writer example to graph memory usage while running ab against webtool:

This was as a response to Yariv, and his desire for a graphing library in erlang like gruff. The example isn’t by any means a real solution, merely a demostration that this could be a viable solution.

The goal of Erlectricity is two-fold: expose ruby code to erlang, such that erlang applications can take advantage of the breadth of ruby libraries, and secondly, expose the OTP to ruby such that fault-tolerant distributed systems will be easier to develop. Neither of those goals are realized in Erlectricity’s current form, but it is a good base to work from towards those goals. Also, the two examples included demonstrate the former, and I’m playing around with something meaningful to demonstrate the latter.

This post is already about 3-times too long, but let me real quickly describe the structure of an erlectric app on the ruby side. The programming model follows the concurrency model of erlang, so read up on how erlang processes messages if you get confused. I’ll also describe it in further detail in an additional post. So, the core of an app using erlectricity is the receive loop, which looks like:

receive do
  match(:hello, string(:yourname)) do
    send! :helloreceived, “You stink, #{yourname}”
    receiveloop
  end
  match(:goodbye){ }
end
The receive block says “get a message, blocking if there are none on the wire”. When a message is received in this state it is compared with each of the match blocks in turn. The match block in the example says “If the message looks like the symbol :hello, and a string, bind the string object to the variable yourname and run the block.” Normally, when receiving a message, the code would then jump out of the receive block, but since the return value of the match block is receiveloop, the program tries to process another message against the same supplied match blocks. You’ll also notice that if the process receives a message that is just the symbol :goodbye, the app will simply fall out of the receive loop.

Here are some tips if you would like to play around with Erlectricity:

  1. Email me if you have any trouble: nullstyle@gmail.com
  2. Pass strings as binaries to ruby. “haha” will come out as [104, 97, 104, 97] in ruby, but <<”haha”>> will come out as “haha” in ruby. See my comment above about the limited type system in erlang. I’ll make a separate post about this issue, because I want to talk more fully about why I made this choice.
  3. Make sure your port is created with the {packet, 4} and binary options. Creating a port with {packet, 2} will have your ruby process never receiving any messages. Not having binary responses enabled will cause trouble when you try binarytoterm to get the response. This is an area for further improvement.
  4. Its a good idea to include catch-all clauses while you are working out the interaction issues. It greatly sped up my debugging time when I had the program yell at me when I sent an improper message
I would like to do several things with Erlectricity. first of all I would like to remove the possibility of programmer error in as many places as possible. There isn’t much work to do in this regard on the ruby-side(as far as I can tell, feedback is always welcome), but the hoops you need to jump through on the erlang side should go away. I’m thinking about abstracting away the framework bits and creating a behavior that you can implement in a callback module, similar to how the OTP does things. Putting a layer on the erlang side between user code and the port will allow me to smooth out some of the type translation issues too.

You can install erlectricity with:

sudo gem install erlectricity --source http://gems.nullstyle.com/
I’m in process of opening up the rubyforge project, so you’ll be able to drop the –source in a couple days. Stay tuned for more info, examples, and improvements as time marches forward.

This would be great to simulate zombie infestations…

Sunday, May 6th, 2007

Erlang is getting a lot of press lately: from the new Pragmatic Programmers book to SlideAware guys and their “From Python to RoR to Erlang” series of blog posts, Erlang definitely appears to be picking up steam. I myself have just recently come around to its beauty, though it is not quite as enjoyable as ruby, but that is a subject for a different post.

Joe Armstrong’s new book on erlang is masterful; It is actually the first programming related book I have read cover to cover (well, in this case the entire pre-print pdf) since “AI for Game Developers”, and that was like 3 years ago. Something wasn’t clicking for me with when Erlang first piqued my interest around the start of the year. It has documentation, and it has tutorials, and the best I could find at the time was the “Getting Started with Erlang”. It does a good job of introducing the language, but I now realize why it failed at hooking me on Erlang: The OTP was only mentioned so far as to say that no info on it would be included in the tutorial. For those of you who don’t know, the OTP is a set of libraries and patterns (called behaviors) that work to enable all of the amazing capabilities of erlang such as cool-as-shit fault tolerance and seamless code upgrade with no downtime. When reading about the OTP in the new book I was hooked: The section that explains in plain detail the non-magic behind live code upgrade sent chills down my spine. I had one of those very desireable “a-ha!” moments when I found that by following this simply explained convention I could upgrade a server with no down time. That was what sold me on Erlang, and it’s a shame that those moments aren’t earlier in the pipeline.

Yet, I am having trouble exploring the Erlang landscape. There is so much to learn, and it seems like some of the interesting bits of Erlang are inaccessible to me. I think that it is mostly a presentation issue, and I would like to help out. Besides, this gives me a good excuse to really keep a blog going. As a challenge to myself, I am going to try and make one Erlang related post to this blog each week.