Tuesday, December 9, 2008

Result of ACK: Future

Wikipedia's definition of a Future in programming:
In computer science, futures and promises are closely related constructs used for synchronization in some concurrent programming languages. They both refer to an object that acts as a proxy for a result that is initially not known, usually because the computation of its value has not yet completed.
Yesterday evening a number of Rubyists from Amsterdam came together in the public library with our laptops to do cool computer stuff until the library closed.

Among the topics we discussed were new-ish programming languages such Ioke and Clojure. From here the discussion went to the languages that preceded them, like Self and IO.

I think that at some point someone asked "What can IO do that Ruby can't do?", so we started looking at the list of features of IO. There we discovered futures.

Futures look nifty: create an object that does not yet have a value and then move on and eventually do something with the object when you need its value. It will block if there is no value yet, which makes sense, but as long as you don't need the value, you can just move on with your business. This can be useful to do heavy computations or to initiate asynchronous interaction with a remote API. As long as you don't need the result immediately, a future can be useful.

Then I mentioned Ruby's Thread#value, which was new to people. So a bit of code was created that looked similar to:

# sleeps for 3 seconds, then prints 615
t = Thread.new { sleep 3; 123}
puts t.value * 5
Explicitly creating a Thread and calling its value does the trick, but it is not very elegant. If you read it, you will probably end think, "What is that Thread doing? Oh, there's a #value call there. Thread + #value is a future!". Or you don't make the connection and misunderstand what this code is doing.

How should it look then to be more elegant?
# sleeps for 3 seconds, then prints 615
f = future { sleep 3; 123}
puts f * 5
So, this is way more elegant! You see it is a future, because it says so! If you don't know about futures, there is Wikipedia or Google and you might figure out what it does.

In order to make this happen, we need to define a future method that returns an object that when called returns Thread#value for that future. A proxy object. This leads to the next implementation:
class Proxy
def initialize(&block)
@thread = Thread.new(&block)
end

def method_missing(*args, &block)
@thread.value.send(*args, &block)
end
end

def future(&block)
Proxy.new(&block)
end

f = future { sleep 3; 123}
puts f * 5
We created a Proxy class to do the threading logic and use method_missing to capture method calls, which we re-direct to Thread#value.

This works as long as you don't call methods defined on Object or Kernel, because you get those for free in every class. You need to either avoid using them or get rid of them. There is BlankSlate, but since we were just trying to make our idea work, we just un-defined most methods on the object. Then we had the crazy idea to drop the Proxy object altogether and make Thread function as its own Proxy object. Thread, say bye-bye to your methods!

Here is the final bit of code we produced:


Then the library closed so we went home, after which I polished it a bit and created a github project for it.

This morning my colleague, Filip Slagter, asked me if there wasn't already a library to do futures in Ruby. After a bit of searching, I found there is one. And it looks nice! Still, I like to re-invent the wheel. It is the best way to learn how something works.

Sunday, November 30, 2008

Adventures in Reia land, part 1: iteration

One of my current interests is the new Reia programming language, created by Tony Arcieri. The wiki contains most of the documentation, but but besides a simple "Hello, World!" and Fibonacci implementation, there is not much working code. Reia is a work in progress, so that makes sense.

Philipp Pirozhkov created Ryan, a web framework built on top of Reia and YAWS. For reasons I have yet to figure out, it does not want to build on my machine. At least there's more code to look at to learn the language. Ryan also has a RSpec-like syntax for writing tests, which look interesting.

Starting with web development might be a bit too ambitious for me. I actually managed to mess up a simple "Hello, world!" example, so I'm starting slow.
Note to self: methods in Reia have parentheses. It's not Ruby, where you can omit them.

Wrong hello world:
puts "Hello, world!"
Proper hello world:
puts("Hello, world!")
Sincy my brain still thinks in Ruby, let's start with a simple bit of Ruby code and convert it to Reia.

First, the Ruby code:
[1,2,3].each { |n| puts n }
This prints out three lines with 1, 2 and 3 on them.
Now the same code in Reia:
[1,2,3].each { |n| puts(n.to_s()) }
The two obvious differences:
  1. All method calls need their parentheses. So use "puts('String')" instead of "puts 'String'".
  2. The int has to be explicitly cast to a String.
Just like Ruby, Reia has multiple ways to write this code. Another Ruby-esque way to write it is by using the 'do' block notation instead of curly braces:
[1,2,3].each do |n|
puts(n.to_s())
Notice the puts() is indented and there is no "end": that is the Python-style indentation at work. A third way to write the code is by (ab)using List Comprehensions:
[puts(x.to_s()) | x in [1,2,3]]
This is the strangest form for me, since Ruby does not have something similar. The way I interpret it is by reading from right to left: for each x in [1,2,3], do the puts thingy left of the pipe.

With that, I conclude my first post on Reia. Now let's see if I can get Google's code prettify syntax highlighting to work.

Hello, World!

After complaining over and over that I should really get myself a blog, I finally have one! Now, let's be nice and let me introduce myself.

My name is Wes Oldenbeuving and I'm a programmer from Amsterdam, the Netherlands. My hobbies include reading books and blogs, playing video games, watching tv series and programming.

My interests cover a wide variety of topics like computer science, economic theory, history, (melodic) metal music, politics, philosophy, personal growth and cooking. I'm not a great chef, but I do try to improvise on recipes every once in a while.

I have been programming (in Ruby) since March 2006 for the Dutch company yoMedia. Ruby on Rails is what brought me to Ruby, but it is not the only thing keeping me. Ruby as a language is really nice to work with and works for both simple scripts, to automate mundane tasks, and to build complex applications. The people in the local Ruby communities are also nice, smart and full of crazy creative ideas.

We have a number of regular events that I attend 99% of the time: Amsterdam.rb, Utrecht.rb and the soon-to-start Amsterdam.rb screen-peeking diner thingy.

I expect my blog posts to mainly cover programming-related topics, though they will not necessarily be all about Ruby. In fact, expect the first posts to be about the new Reia programming language.