Hello Mirahnese folks.
I've been using Mirah for my Android app and have been keeping notes
about the pain points I come across. So here's a "from the trenches"
report on Mirah usage.
0) The biggest issue for me has been instance var resolution in blocks.
class Foo
def bar
@a = 10
Thread.new { puts @a }.start
end
end
Foo.new.bar
Inference Error:
foo.mirah:4: Unable to infer type.
Thread.new{ puts @a }.start
^^^
Since blocks get compiled to anonymous inner classes, @a is
interpreted as being an instance var on the block's inner class. The
point of having blocks compile this way is to shield the user from the
unpleasantness of Java inner classes, so it's unlikely the user would
ever need to look up fields on those classes; instance vars should
just resolve to the containing class. The same problem applies to
resolving self references.
Oddly enough, this works:
class Foo
def bar
@a = 10
[2, 3].each {|x| puts @a }
end
end
In this case I assume the block is compiled into a for loop which does
not introduce any other classes. This makes sense for performance
reasons, but it is good to remember that blocks don't always mean
inner classes. I think this makes a strong case for Mirah doing as
much as it can to hide the fact that inner classes are involved.
Anyhow, this is easy to work around, but it adds unnecessary verbosity
and awkwardness. It sounds like this could be fairly involved to fix
satisfactorily.
I raised this issue on the mailing list:
http://groups.google.com/group/mirah/browse_thread/thread/595ff2dae2dc2fc2
1) Type inference doesn't seem to look into superclasses.
class Bar
def initialize
@hi = "hi"
end
end
class Foo < Bar
def foo
@hi
end
end
Foo.new.foo
# Inference Error:
# foo.mirah:9: Unable to infer type.
# @hi
I don't know how tricky this would be to fix; it may be something
simple missing in the inference engine.
There's a issue for this: https://github.com/mirah/mirah/issues#issue/50
2) Objects pulled out of ArrayLists and HashMaps lose typing information.
def f(x:String)
puts "x is a String"
end
l = ["a"]
f(l.get(0))
Inference Error:
foo.mirah:25: Cannot find static method f(java.lang.Object) on Foo
f(l.get(0))
^^^^^^^^^^^
This forces you to cast every time you pull objects out of data
structures, which is very cumbersome. From what I understand fixing it
requires implementing generics, which is probably a huge task.
3) Constant assignments aren't implemented.
class Foo
BAR = "hi"
end
foo.mirah:20: undefined method `transform_const_assign' for #<Mirah::AST::TransformHelper:0x3b961a84>
BAR = "hi"
^^^^^
Constants would make Mirah feel more like Ruby. It's probably not too
hard to implement.
This has been discussed on the mailing list:
http://groups.google.com/group/mirah/browse_thread/thread/61ca5f5cb41e48fa
4) Class variables may not be set in class bodies.
class Foo
@@bar = "hi"
def say_hello
puts @@hi
end
end
Inference Error:
foo.mirah:5: Unable to infer type.
puts @@hi
^^^^^
This has also been discussed in the above thread. Again, it sounds
like just a matter of wiring things up.
5) Unnecessary distinctions are made between various numeric types.
def print_number(x:Double)
puts x
end
print_number(0.0)
Inference Error:
foo.mirah:5: Cannot find static method print_float(double) on Foo
print_number(0.0)
^^^^^^^^^^^^^^^^
Making the user box numerics like this is an annoyance. I understand
there are circumstances in which autoboxing carries significant
performance penalties, so there should be a way to warn whenever it
happens, but it would be very convenient to allow the compiler to help
with this.
Charlie says this would not be particularly hard.
There are also places where floats could be converted to doubles
automatically. I'm not sure about the reverse since doing that safely
may involve overflow checks, which could be a huge can of worms.
6) Case statements have not been implemented.
There are a few places in Android apps where this would simplify
things a lot. This is probably really easy to implement.
7) The compiler could be faster.
Just sayin'. =)
All in all developing with Mirah is fairly pleasant, but once some of
these issues are taken care of it will really shine. I can create
Github issues for these if desired.
-Phil
Yes I agree. It's great to be able to jump back to pure java. I don't know a whole lot of ruby yet but where I'm trying to head with my gae app is to use pure java for the model and mirah for the controllers and views, where using java really sucks :-)
I am hoping as I get more confident with ruby/mirah I'll start to use it for the whole app.
Andrew
I may be biased since I don't know Java myself, but I believe that may
change in the future.
It's been the case so far that it's been used primarily by Java devs
since Mirah hasn't had very wide exposure, but I think as it begins to
take off among Rubyists and fans of other dynamic languages we will
see Mirah used by people who want to target Java the platform without
bothering to spend time learning Java the language.
-Phil