appengine ja-night-10

69
Mirah & Dubious Mirah & Dubious Tuesday, August 31, 2010

Upload: john-woodell

Post on 20-May-2015

2.286 views

Category:

Technology


0 download

DESCRIPTION

JohnさんはJRubyおよびApp Engineに関連するオープンソース開発プロジェクトで積極的な活動を進めており、日本国内におけるSlim3(App Engine対応フレームワーク)の急速な普及に注目しています。そこでイベントの第一部では、Google社員の方々や一般の方に向けてSlim3をより知ってもらうため、Slim3の開発者であるひがやすをさんを招いて解説していただきます。さらに今回はJRubyの開発者Charles Nutterさんを招き、同氏が開発を進めている新しい言語Mirahについて解説いただくほか、Johnさんが開発するMirahベースのApp Engine対応WebフレームワークDubiousについて紹介します。

TRANSCRIPT

Page 1: Appengine ja-night-10

Mirah & DubiousMirah & Dubious

Tuesday, August 31, 2010

Page 2: Appengine ja-night-10

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

Page 3: Appengine ja-night-10

MirahA pragmatic blend of Ruby and Java

Tuesday, August 31, 2010

Page 4: Appengine ja-night-10

Me

• Charles Oliver Nutter

• Engine Yard, Inc

[email protected]

• @headius

• JRuby core developer

• Mirah creator

Tuesday, August 31, 2010

Page 5: Appengine ja-night-10

Ruby

• Beautiful language

• Clean syntax

• Easy-to-use closures

• Nice core libraries

• “Slow” language

• Very dynamic == hard to optimize

Tuesday, August 31, 2010

Page 6: Appengine ja-night-10

Java

• High-performance language

• Mostly static typing

• Full system optimizations

• Primitive math operations

• Ugly language

• (C++)-- of 1995

Tuesday, August 31, 2010

Page 7: Appengine ja-night-10

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

Page 8: Appengine ja-night-10

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

Page 9: Appengine ja-night-10

...Could Be Thisclass Foo def initialize(a) @a = a end

def show puts @a endend

Tuesday, August 31, 2010

Page 10: Appengine ja-night-10

Mirahclass Foo def initialize(a:int) @a = a end

def show puts @a endend

Tuesday, August 31, 2010

Page 11: Appengine ja-night-10

“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

Page 12: Appengine ja-night-10

Features From Ruby

• Optional arguments ✓

• Internal iteration ✓

• Closures ✓

• Literals ✓

• String interpolation ✓

• Mixins, “open” classes (soon)

Tuesday, August 31, 2010

Page 13: Appengine ja-night-10

Features From X

• (Coming Soon)

• Extension methods (C#ish, but nicer)

• Implicit type conversions (Scala)

• Pattern matching?

• Case classes?

Tuesday, August 31, 2010

Page 14: Appengine ja-night-10

Ruby

puts “Hello, world!”

Tuesday, August 31, 2010

Page 15: Appengine ja-night-10

Mirah

puts “Hello, world!”

Tuesday, August 31, 2010

Page 16: Appengine ja-night-10

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

Page 17: Appengine ja-night-10

Ruby

def fib(a) if a < 2 a else fib(a - 1) + fib(a - 2) endend

Tuesday, August 31, 2010

Page 18: Appengine ja-night-10

Mirah

def fib(a:int) if a < 2 a else fib(a - 1) + fib(a - 2) endend

Tuesday, August 31, 2010

Page 19: Appengine ja-night-10

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

Page 20: Appengine ja-night-10

Ruby

def foo(a = 1, b = 2) puts a + bend

Tuesday, August 31, 2010

Page 21: Appengine ja-night-10

Mirah

def foo(a:int = 1, b:int = 2) puts a + bend

Tuesday, August 31, 2010

Page 22: Appengine ja-night-10

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

Page 23: Appengine ja-night-10

Ruby

a = [5,4,3,2,1]a.each do |x| puts xend

Tuesday, August 31, 2010

Page 24: Appengine ja-night-10

Mirah

a = [5,4,3,2,1]a.each do |x| puts xend

Tuesday, August 31, 2010

Page 25: Appengine ja-night-10

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

Page 26: Appengine ja-night-10

Ruby

t = Thread.new do puts “in thread”end

Tuesday, August 31, 2010

Page 27: Appengine ja-night-10

Mirah

t = Thread.new do puts “in thread”end

Tuesday, August 31, 2010

Page 28: Appengine ja-night-10

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

Page 29: Appengine ja-night-10

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

Page 30: Appengine ja-night-10

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

Page 31: Appengine ja-night-10

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

Page 32: Appengine ja-night-10

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

Page 33: Appengine ja-night-10

Open Class (usage)

str = “hello\ngoodbye\nworld”

str.each {|s| ... }

Tuesday, August 31, 2010

Page 34: Appengine ja-night-10

Open Class (Java usage)

String str = “hello\ngoodbye\nworld”;

StringExtension.each(str, new StringFunc() { public void apply(String s) { ... }});

Tuesday, August 31, 2010

Page 35: Appengine ja-night-10

Open Class (Java usage)

String str = “hello\ngoodbye\nworld”;

StringExtension.each(str, new StringFunc() { public void apply(String s) { ... }}); YUCK!

Tuesday, August 31, 2010

Page 36: Appengine ja-night-10

Type Conversion

str = “hello\ngoodbye\nworld”

# no “map” method on String...str.map {|s| # ERROR

Tuesday, August 31, 2010

Page 37: Appengine ja-night-10

Type Conversion(by hand)

str = “hello\ngoodbye\nworld”

# without type conversionArrays.asList(str.split).map { ...

Tuesday, August 31, 2010

Page 38: Appengine ja-night-10

Type Conversion(by hand)

str = “hello\ngoodbye\nworld”

# without type conversionArrays.asList(str.split).map { ...

Tuesday, August 31, 2010

Page 39: Appengine ja-night-10

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

Page 40: Appengine ja-night-10

Type Conversion (usage)

str = “hello\ngoodbye\nworld”

# with type conversion!str.map { ... # OK!!

Tuesday, August 31, 2010

Page 41: Appengine ja-night-10

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

Page 42: Appengine ja-night-10

But It Feels Like Ruby!

• Clean, lightweight syntax

• Iteration, closures

• Far less “ceremony” than Java

• Performance equivalent to Java

Tuesday, August 31, 2010

Page 43: Appengine ja-night-10

mirah.org

Tuesday, August 31, 2010

Page 44: Appengine ja-night-10

Tuesday, August 31, 2010

Page 45: Appengine ja-night-10

DubiousDubiousはMirahのWebフレームワーク

Tuesday, August 31, 2010

Page 46: Appengine ja-night-10

Me

• John Woodell

• Web developer at Google

• Dubious creator

• App Engine JRuby maintainer

• @JohnWoodell

Tuesday, August 31, 2010

Page 47: Appengine ja-night-10

47

Thank you for using"AppEngine/Java”

いつも"AppEngine/Java"をご利用頂きありがとうございます

Tuesday, August 31, 2010

Page 48: Appengine ja-night-10

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

Page 49: Appengine ja-night-10

49

Spin-up?Yes, this is a problem...

そうですね。使い物にならないですよね

Tuesday, August 31, 2010

Page 50: Appengine ja-night-10

50

...but now you can useMirah and Dubious

ならば "Mirah/Dubious" だ

Tuesday, August 31, 2010

Page 51: Appengine ja-night-10

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

Page 52: Appengine ja-night-10

52

Write Rails-style code,

it runs on Google App Engine

ターゲットはGoogleAppEngine

Railsっぽく書けます

Tuesday, August 31, 2010

Page 53: Appengine ja-night-10

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

Page 54: Appengine ja-night-10

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

Page 55: Appengine ja-night-10

55

Here’s code from Dubious(this is not Rails)

これらはRailsではなくDubiousのコードです

Tuesday, August 31, 2010

Page 56: Appengine ja-night-10

Dubious controllers will be familiar

Tuesday, August 31, 2010

Page 57: Appengine ja-night-10

Mirah can use ERb templates

Tuesday, August 31, 2010

Page 58: Appengine ja-night-10

The generated Java source can be inspected

Tuesday, August 31, 2010

Page 59: Appengine ja-night-10

The ERb is transformed into method calls

Tuesday, August 31, 2010

Page 60: Appengine ja-night-10

Your model definition is very concise

Tuesday, August 31, 2010

Page 61: Appengine ja-night-10

Code generation based on defined properties

Tuesday, August 31, 2010

Page 62: Appengine ja-night-10

All the basic methods you need are generated

Tuesday, August 31, 2010

Page 63: Appengine ja-night-10

63

It really works,

and spins-up in ~1sec

ちゃんとうごきます。しかも、爆速Spinup.

Tuesday, August 31, 2010

Page 64: Appengine ja-night-10

64

It isn’t "Dubious"あやしくないよ。

http://dubious-demo.appspot.com

Tuesday, August 31, 2010

Page 65: Appengine ja-night-10

The Framework(coding in Mirah)

Tuesday, August 31, 2010

Page 66: Appengine ja-night-10

Method signatures enforce types

Tuesday, August 31, 2010

Page 67: Appengine ja-night-10

Return type can be enforced also

Tuesday, August 31, 2010

Page 68: Appengine ja-night-10

Code is very concise

Tuesday, August 31, 2010

Page 69: Appengine ja-night-10

Thank YouThank You

Tuesday, August 31, 2010