appengine ja-night-10
DESCRIPTION
JohnさんはJRubyおよびApp Engineに関連するオープンソース開発プロジェクトで積極的な活動を進めており、日本国内におけるSlim3(App Engine対応フレームワーク)の急速な普及に注目しています。そこでイベントの第一部では、Google社員の方々や一般の方に向けてSlim3をより知ってもらうため、Slim3の開発者であるひがやすをさんを招いて解説していただきます。さらに今回はJRubyの開発者Charles Nutterさんを招き、同氏が開発を進めている新しい言語Mirahについて解説いただくほか、Johnさんが開発するMirahベースのApp Engine対応WebフレームワークDubiousについて紹介します。TRANSCRIPT
Mirah & DubiousMirah & Dubious
Tuesday, August 31, 2010
Mirah & DubiousA bold and beautiful way to write Java, plus a new framework for App Engine
Charles NutterJohn WoodellAug 30, 2010
2
Tuesday, August 31, 2010
MirahA pragmatic blend of Ruby and Java
Tuesday, August 31, 2010
Me
• Charles Oliver Nutter
• Engine Yard, Inc
• @headius
• JRuby core developer
• Mirah creator
Tuesday, August 31, 2010
Ruby
• Beautiful language
• Clean syntax
• Easy-to-use closures
• Nice core libraries
• “Slow” language
• Very dynamic == hard to optimize
Tuesday, August 31, 2010
Java
• High-performance language
• Mostly static typing
• Full system optimizations
• Primitive math operations
• Ugly language
• (C++)-- of 1995
Tuesday, August 31, 2010
Mirah
• “Apparent features” of Ruby
• Syntax
• Closures and iterators
• Dynamic-feeling behaviors
• Performance, typing like Java
• As fast as Java for almost everything
Tuesday, August 31, 2010
What If This...public class Foo { private int a;
public Foo(int a) { this.a = a; }
public void show() { System.out.println(a); }}
Tuesday, August 31, 2010
...Could Be Thisclass Foo def initialize(a) @a = a end
def show puts @a endend
Tuesday, August 31, 2010
Mirahclass Foo def initialize(a:int) @a = a end
def show puts @a endend
Tuesday, August 31, 2010
“Java’s Ruby”
• A nicer way to write Java
• Ruby syntax with modifications
• Feels like Ruby
• Compiles to Java/JVM
• No runtime library
Tuesday, August 31, 2010
Features From Ruby
• Optional arguments ✓
• Internal iteration ✓
• Closures ✓
• Literals ✓
• String interpolation ✓
• Mixins, “open” classes (soon)
Tuesday, August 31, 2010
Features From X
• (Coming Soon)
• Extension methods (C#ish, but nicer)
• Implicit type conversions (Scala)
• Pattern matching?
• Case classes?
Tuesday, August 31, 2010
Ruby
puts “Hello, world!”
Tuesday, August 31, 2010
Mirah
puts “Hello, world!”
Tuesday, August 31, 2010
Mirah
// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println("Hello, world!"); }}
Tuesday, August 31, 2010
Ruby
def fib(a) if a < 2 a else fib(a - 1) + fib(a - 2) endend
Tuesday, August 31, 2010
Mirah
def fib(a:int) if a < 2 a else fib(a - 1) + fib(a - 2) endend
Tuesday, August 31, 2010
Mirah
// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { } public static int fib(int a) { return (a < 2) ? (a) : ((DashE.fib((a - 1)) + DashE.fib((a - 2)))); }}
Tuesday, August 31, 2010
Ruby
def foo(a = 1, b = 2) puts a + bend
Tuesday, August 31, 2010
Mirah
def foo(a:int = 1, b:int = 2) puts a + bend
Tuesday, August 31, 2010
Mirah public static java.io.PrintStream foo(int a, int b) { java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println((a + b)); return temp$1; } public static java.io.PrintStream foo() { return foo(1); } public static java.io.PrintStream foo(int a) { return foo(a, 2); }
Tuesday, August 31, 2010
Ruby
a = [5,4,3,2,1]a.each do |x| puts xend
Tuesday, August 31, 2010
Mirah
a = [5,4,3,2,1]a.each do |x| puts xend
Tuesday, August 31, 2010
Mirah// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { java.util.List a = java.util.Collections.unmodifiableList( java.util.Arrays.asList(1, 2, 3, 4, 5)); java.util.Iterator __xform_tmp_1 = a.iterator(); label1: while (__xform_tmp_1.hasNext()) { java.lang.Object x = __xform_tmp_1.next(); label2: { java.io.PrintStream temp$3 = java.lang.System.out; temp$3.println(x); } } }}
Tuesday, August 31, 2010
Ruby
t = Thread.new do puts “in thread”end
Tuesday, August 31, 2010
Mirah
t = Thread.new do puts “in thread”end
Tuesday, August 31, 2010
Mirah// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } }}
Tuesday, August 31, 2010
Mirah// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } }}
Tuesday, August 31, 2010
Mirah// Generated from DashEpublic class DashE extends java.lang.Object { public static void main(java.lang.String[] argv) { DashE.__xform_tmp_1 $binding = new DashE.__xform_tmp_1(); $binding.x = "in thread"; java.lang.Thread t = new java.lang.Thread(new DashE.__xform_tmp_2($binding)); } public static class __xform_tmp_1 extends java.lang.Object { java.lang.String x; } public static class __xform_tmp_2 extends java.lang.Object implements java.lang.Runnable { private DashE.__xform_tmp_1 binding; public __xform_tmp_2(DashE.__xform_tmp_1 binding) { this.binding = binding; } public void run() { DashE.__xform_tmp_1 $binding = this.binding; java.io.PrintStream temp$1 = java.lang.System.out; temp$1.println($binding.x); } }}
Tuesday, August 31, 2010
Open Class (proposal)interface StringFunc def apply(str:String)end
extend class String # java.lang.String def each(func:StringFunc) # String#split call from Java lines = split
# like “for (String str: strArray)” lines.each do |str| func.apply(str) end endend
Tuesday, August 31, 2010
Open Class (Java side)
public interface StringFunc { public void apply(String str);}
public class StringExtension { public void each(String str, StringFunc func) { for (String s: str.split()) { func.apply(str); } }}
Tuesday, August 31, 2010
Open Class (usage)
str = “hello\ngoodbye\nworld”
str.each {|s| ... }
Tuesday, August 31, 2010
Open Class (Java usage)
String str = “hello\ngoodbye\nworld”;
StringExtension.each(str, new StringFunc() { public void apply(String s) { ... }});
Tuesday, August 31, 2010
Open Class (Java usage)
String str = “hello\ngoodbye\nworld”;
StringExtension.each(str, new StringFunc() { public void apply(String s) { ... }}); YUCK!
Tuesday, August 31, 2010
Type Conversion
str = “hello\ngoodbye\nworld”
# no “map” method on String...str.map {|s| # ERROR
Tuesday, August 31, 2010
Type Conversion(by hand)
str = “hello\ngoodbye\nworld”
# without type conversionArrays.asList(str.split).map { ...
Tuesday, August 31, 2010
Type Conversion(by hand)
str = “hello\ngoodbye\nworld”
# without type conversionArrays.asList(str.split).map { ...
Tuesday, August 31, 2010
Type Conversion (proposal)
conversion(String => List) do |str| Arrays.asList(str.split)end
conversion(List => String) do |list| list.join(‘\n’)end
Tuesday, August 31, 2010
Type Conversion (usage)
str = “hello\ngoodbye\nworld”
# with type conversion!str.map { ... # OK!!
Tuesday, August 31, 2010
It’s Not Ruby
• Using Java’s libraries and type system
• No “eval”
• No runtime-mutable classes
• Ruby libraries will not work
Tuesday, August 31, 2010
But It Feels Like Ruby!
• Clean, lightweight syntax
• Iteration, closures
• Far less “ceremony” than Java
• Performance equivalent to Java
Tuesday, August 31, 2010
mirah.org
Tuesday, August 31, 2010
Tuesday, August 31, 2010
DubiousDubiousはMirahのWebフレームワーク
Tuesday, August 31, 2010
Me
• John Woodell
• Web developer at Google
• Dubious creator
• App Engine JRuby maintainer
• @JohnWoodell
Tuesday, August 31, 2010
47
Thank you for using"AppEngine/Java”
いつも"AppEngine/Java"をご利用頂きありがとうございます
Tuesday, August 31, 2010
48
Spin-up time can make scaling “painful”• The most critical issue to be resolved is spin-up time,
App Engine scales by adding new application instances.• Even if initialization could happen without affecting users
some apps will need to scale instantly.
Tuesday, August 31, 2010
49
Spin-up?Yes, this is a problem...
そうですね。使い物にならないですよね
Tuesday, August 31, 2010
50
...but now you can useMirah and Dubious
ならば "Mirah/Dubious" だ
Tuesday, August 31, 2010
51
Dubious is Web framework for Mirah
DubiousはMirahのWebフレームワーク
*du・bi・ous[ djbis | dj- ] [形]
[1] ((叙述))〈人が〉(…に)半信半疑の;怪しいと思う,疑う((of, about, as to ...)).
[2] 〈人・性質・行為が〉いかがわしい,怪しい;(真実性などが)疑問である,不審な;
〈称>号・栄誉などが〉ありがたくない
Tuesday, August 31, 2010
52
Write Rails-style code,
it runs on Google App Engine
ターゲットはGoogleAppEngine
Railsっぽく書けます
Tuesday, August 31, 2010
53
Benefits of Mirah on App Engine• Ruby syntax & apparent features + Java type system• Use Java or Ruby when Mirah lacks features you require• The generated Java source can be inspected at any time• Macros and plugins can be written in Ruby or Mirah• New instances always spin-up in about a second
Tuesday, August 31, 2010
54
Working with Dubious• Dubious framework uses familiar Rails conventions• Generate JSONs or work with ERb templates• MirahModel syntax is similar to DataMapper• Developers can create apps entirely in Rails,
then refactor URLs that need to scale quickly• Some important features are currently missing,
but “you” could have fun contributing them
Tuesday, August 31, 2010
55
Here’s code from Dubious(this is not Rails)
これらはRailsではなくDubiousのコードです
Tuesday, August 31, 2010
Dubious controllers will be familiar
Tuesday, August 31, 2010
Mirah can use ERb templates
Tuesday, August 31, 2010
The generated Java source can be inspected
Tuesday, August 31, 2010
The ERb is transformed into method calls
Tuesday, August 31, 2010
Your model definition is very concise
Tuesday, August 31, 2010
Code generation based on defined properties
Tuesday, August 31, 2010
All the basic methods you need are generated
Tuesday, August 31, 2010
63
It really works,
and spins-up in ~1sec
ちゃんとうごきます。しかも、爆速Spinup.
Tuesday, August 31, 2010
64
It isn’t "Dubious"あやしくないよ。
http://dubious-demo.appspot.com
Tuesday, August 31, 2010
The Framework(coding in Mirah)
Tuesday, August 31, 2010
Method signatures enforce types
Tuesday, August 31, 2010
Return type can be enforced also
Tuesday, August 31, 2010
Code is very concise
Tuesday, August 31, 2010
Thank YouThank You
Tuesday, August 31, 2010