Don't fall in love with your theory
Over the weekend I was watching discovery channel, and a scientist said the following:
"Don't fall in love with your theory, be willing to modify it until it's proven."
People can have much more productive discussions when they don't fall in love with their theory.
A party I'm looking forward to 1
I have been busy preparing for the arrival of our first baby. Between working, doing things around the house and shopping, I have had little time for anything else. This is our most recent purchase:

JRuby Dilemma
I submitted the following code to JRuby mailing list, and I haven't received any reponse yet. Can you spot the problem?
package my;
import java.util.Vector;
public class MyClassInJava {
Vector vector;
public MyClassInJava(java.util.Vector vector) {
this.vector = vector;
}
public Object getVector() {
return vector;
}
}Here is my ruby code which calls the Java code above:
include Java
require 'my.jar'
class MyVector < java.util.Vector
def my_method
end
end
class MyRuby
def initialize
my_vec = MyVector.new
c = Java::my.MyClassInJava.new(my_vec)
vec_from_java = c.getVector()
if vec_from_java.respond_to?(:my_method)
puts "found"
else
puts "not found"
puts vec_from_java.java_class
end
end
end
r = MyRuby.newThe output from the ruby code :
not found
org.jruby.javasupport.proxy.gen.Vector$Proxy0
Implementing Interface in JRuby 1
Recently I decided to convert one of the tools I wrote in C# to JRuby. During the process I needed to implement a Java interface in JRuby. This sounds really weird to me because Ruby has no need for an interface because of the duck-typing system. The syntax for implementing an interface in JRuby is shown below:
class SomeClass
include javax.swing.tree.TreeCellEditor
# ...
endIn this case, SomeClass implements TreeCellEditor Java inteface. It uses mix-in like syntax. Prior to the 1.0 release, I believe it used ruby inheritance syntax instead of the current mix-in syntax. That would look even more weird because Ruby doesn't support multiple inheritance and it will be confusing when you are implemneting an interface and extending a class.
I don't know about you, but implementing an interface in Ruby still feels weird to me.
Time to go Functional
In my college days I avoided functional programming languages such as LISP and Prolog like the plague. Recently I decided to revisit and learn a functional language. My choice of language is Erlang (as you can see from my last post).
One of the primary reasons I chose Erlang over other functional languages is Erlang's ability to handle concurrency and distributed programming. Before I get into concurrent programming using Erlang I need to learn the basics. I started my Erlang adventure by reading Getting Started with Erlang. I would recommend anyone that is interesting in Erlang to start there. I found the reading was easy and helpful for someone who doesn't know anything about Erlang. Like many other dynamic lanaguages, Erlang comes with an interpreter. I found it very helpful to enter the code into the interpreter while I'm reading the examples. Next step is to read Joe Armstrong's book: Programming Erlang Maybe one day I can find a good use for Erlang.
Erlang in Action
I decided to see if I could rewrite the problem I solved in a previous post in Erlang. Here is the problem again:
A/BC + D/EF + G/HI = 1
-module(constraint).
-export([solve/0]).
solve() ->
solve(generate_unique()).
solve([A,B,C,D,E,F,G,H,I]) when A/(10 * B + C) +
D/(10 * E + F) +
G/(10 * H + I) /= 1 ->
solve();
solve([A,B,C,D,E,F,G,H,I]) ->
io:format("~w/~w~w + ~w/~w~w + ~w/~w~w = 1 ~n",
[A,B,C,D,E,F,G,H,I]).
generate_unique() ->
generate_unique(0, []).
generate_unique(9, List) ->
List;
generate_unique(N, List) ->
Number = random:uniform(9),
case lists:member(Number, List) of
true -> generate_unique(N, List);
false -> generate_unique(N + 1, [Number|List])
end.Gecode/r Under Mac OSX
I had a little bit of trouble getting gecode/r running at first. Gecode/r is a wrapper around Gecode, so you'll need to also install Gecode before installing Gecoder/r. I started out using the disk image for Mac OSX 10.4, but Gecode/r would produce the following error when I tried to require Gecode/r:
irb(main):002:0> require 'gecoder'
dyld: NSLinkModule() error
dyld: Symbol not found: __ZNK6Gecode9Exception4whatEv
Referenced from:
/usr/local/lib/ruby/gems/1.8/gems/gecoder-0.3.0/lib/gecode.bundle
Expected in: flat namespaceIt turns out, I have to download Gecode source and compile it on my Mac. After that, all I had to do is: gem install gecoder.
Gecode/r
Recently I solved my first constraint programming problem using C# (Steve Eichert also solved it via Ruby). I decided to poke around the Internet to see if there's an API for constraint programming. After all, there are real world problems that can be solved using constraint programming. I can't imagine people just hand roll there own API for complex problems.
After few searches in google, I came across Gecode. Gecode is an open source API implemented in C++ distributed under the BSD style license. I noticed there is also Gecode/J which is a Java interface to Gecode. I started to wonder, is there a Ruby version of Gecode? It turns out Andreas Launila recently started Gecode/r under Google Summer of Code.
Gecode/r is still at the early stage, but there is a downloadable alpha version. I tried to use it to solve the same problem, however, I ran into some difficulties. It currently only supports 3 mathematical operations: +, -, *. No division for now. Andreas suggested I rewrite the equation by removing the division. The only problem with rewriting is that the equation actually becomes more complex. I haven't been able to get my version to work yet.
For those who are interested in what Gecode/r looks like, below is an example of solving the classic send more money problem using gecode/r, which is taken from gecode/r's example page:
class SendMoreMoney < Gecode::Model
def initialize
s,e,n,d,m,o,r,y = @letters = int_var_array(8, 0..9)
(equation_row(s, e, n, d) + equation_row(m, o, r, e)).must ==
equation_row(m, o, n, e, y)
s.must_not == 0
m.must_not == 0
@letters.must_be.distinct
branch_on @letters, :variable => :smallest_size, :value => :min
end
def to_s
%w{s e n d m o r y}.zip(@letters).map do |text, letter|
"#{text}: #{letter.val}"
end.join(', ')
end
private
# A helper to make the linear equation a bit tidier. Takes a number of
# variables and computes the linear combination as if the variable
# were digits in a base 10 number. E.g. x,y,z becomes
# 100*x + 10*y + z .
def equation_row(*variables)
variables.inject{ |result, variable| variable + result*10 }
end
end
puts SendMoreMoney.new.solve!.to_sDoes your QA hate you?
DRY principal is probably the most fundamental philosophy in software development. It allows a programmer to flip a switch that takes effect across the whole system. While this is good for the programmer, it is bad for people in QA.
"You changed feature X, did that effect anything else in the app.", your QA asks. "Yeah, the whole app."
Brain Teaser: Constraint programming
I had never heard of constraint programming until a co-worker wrote the following problem on the board a few days ago:
A/BC + D/EF + G/HI = 1
All variables are unique digits from 1 - 9. Two variables next to each other is equivalent to 10 * var1 + var2. For example, if B = 2, C = 5 then the result is 10 * 2 + 5 which equals 25.
I decided to whip up a program to find out the answer.
class Program {
static List<int> ints = new List<int>();
static Random r = new Random();
static void Main(string[] args) {
double A = 0, B = 0, C = 0, D = 0, E = 0, F = 0, G = 0, H = 0, I = 0;
while (!(((A / (10 * B + C)) + (D / (10 * E + F)) + (G / (10 * H + I))) == 1)) {
GenerateUniqueInts();
A = ints[0]; B = ints[1]; C = ints[2];
D = ints[3]; E = ints[4]; F = ints[5];
G = ints[6]; H = ints[7]; I = ints[8];
}
Console.WriteLine(String.Format("{0}/{1}{2} + {3}/{4}{5} + {6}/{7}{8} = 1",
A, B, C, D, E, F, G, H, I));
}
public static void GenerateUniqueInts() {
ints.Clear();
int value = (r.Next() % 9) + 1;
while (!(ints.Count == 9)) {
if (!ints.Contains(value)) ints.Add(value);
value = (r.Next() % 9) + 1;
}
}
}It only takes a couple of seconds for the program to figure out the answer. It turns out there is only one solution to this problem. However, on my first implementation I instantiated the Random object in the GenerateUniqueInts() method. For some reason, that can take up 10 minutes to run. If you are interested in the answer, try the program out.
