from ruby to scala
DESCRIPTION
Introduction of Ruby and ScalaTRANSCRIPT
TEST
HELLO
Hello, is there Rubyist?
From Ruby to
Scala
@todeskinghttps://www.flickr.com/photos/7armyjmtc/14249465709
(When I moved)
Who:
@todeskinguses twitter and GitHub
web: todesking.com
Platinum Sponsor
Working at
My background
• Sistem Integrator(2008-2012)• Buisiness batches• Recommendation system• With Java
• Social game servicer• Browser based social game server• With Rails
• DSP servicer• Adverting technology(Real-time bidding, user trakcing,
machine learning)• With Scala
• Vim
What is DSP
• "Demand Side Platform"• You can find detailed description in at
Internet.
Ad Client
sDSP SSP
real time bidding(RTB)
Web PagesI'm here
Today I NOT talk to:
• How to build high-performance system• DO THE RIGHT THING and KEEP GOING,
thats all.• How to speed up compilation time
• BUY FASTER MACHINE• Whitch is greatest language
• Every language has own good things• 😃😃😃BE PEACEFUL😃😃😃
I moved from Rubyto Scala, in this April
• That is smoother than I thought.• Basically, Ruby and Scala has common
attributes• object-oriented and functional paradigm• Modern features for productivity and fun
Ruby and Scala is Class-based Object Oriented language
• Class based object oriented language
class Person < Struct.new(:name, :age) def hello puts "Hello there, my name is #{name}." endend
class Person(val name:String, val age:Option[Int]) { def hello():Unit = { println(s"Hello there, my name is ${name}.") }}
At first: Common attributes of Ruby and Scala
• Class based object oriented language with functional features
def sumOfAge(people:Seq[Person]):Int = { people.map(_.age).flatten.foldLeft(0)(_ + _)}
def sum_of_age(people) people.map(&:age).compact.reduce(0, &:+)end
At first: Common attributes of Ruby and Scala
• "Fun" language• "Ruby をキメると気持ちいい "(Matz)
• I can't translate it...• → 💉 😋😊😆
• "Maybe most important is that programming in Scala tends to be very enjoyable."
Today's theme:How these languages do things in different way
Class definition
class Person < Struct.new(:name, :age)end
person = Person.new("tode sking", 31)
class Person(val name:String, val age:Option[Int])val person = new Person("tode sking", Some(31))
Class definition in Ruby
class Person < Struct.new(:name, :age)
WHAT?!Creating new instance at class definition?!?!
"class" for class definition
"<" means "extends"
Create new instance of Struct
Let's begin most plain case
class Person def initialize(name, age) @name = name @age = age end def name; @name; end def name=(val); @name = val; end def age; @age; end def age=(val); @age = val; endend
"def" for method definition
method named "initialize" is treated as
ctor
"@name" is instance variable
getter and setter methods
Lot of boilerplate😩
Auto generating accessor method in Ruby
class Person def initialize(name, age) ... attr_reader :name attr_reader :ageend
"attr_reader" is keyword for generating accessor method
"attr_writer" and "attr_reader" is also
available
NO, actually it is not KEYWORD
It just a METHOD.
Auto generating accessor method in Ruby
attr_accessor :name
≒define_method("name") { @name }define_method("name=") {|val| @name = val }
def name; @name; enddef mane=(val); @name = val; end
≒
Ruby is DYNAMIC language
• EVERYTHING is object• Class is object too• o = Object.new; o.class => Object• If you want to create new class, try A =
Class.new• (assign constant A to fresh class object)
• To define a method to A, try A.define_method(:foo){...}• (actually, define_method is "private". You
should use A.instance_eval { define_method(:foo) ... })
It called "Macro" in Ruby
• Such method called "macro"(Actually, it is just a method!!)
• Ruby has no "compile-time". all execution is in "runtime"
Defining accessor method: Ruby and Scala
• scala• var foo• roughly equal to { private[this] var foo_;
def foo = foo_ }• specialized syntax for accessor
• Ruby• attr_*• Enhance class definition with DSLs
Auto generating accessor method in Ruby
class Person < Struct.new(:name, :age)
Create a new instance of Struct
Struct is a kind of Class
PersonBase = Struct.new(:name, :age)class Person < PersonBase
≒
Auto generating accessor method in Ruby
Struct.new(:name, age) returns class that like
class (unnamed) def initialize(name, age) @name, @age = name, age end attr_accessor :name attr_accessor :age # other utility methods...end[
Class definition
class Person < Struct.new(:name, :age)end
person = Person.new("tode sking", 31)
class Person(val name:String, val age:Option[Int])val person = new Person("tode sking", Some(31))
Function as value
• Scala:• val f:Int => Int = _ + 1• f(1) //=> 2• val g:Any => String = _.toString
• Ruby• f = ->(x){x + 1}• f.call(1) or f[1] or f.(1)• mehod and value is strongly separated• g = ->(x){x.to_s}
Functions as value in other languages
• Scheme: f, (f a b)• javascript: f, f(a, b)• Common Lisp: #'f, (f a b), (funcall #'f (list
arg1 arg2))
Use function as value: Scala case
• def foo(x:Int):String• val f = foo // not works• val f = foo _ // works• def bar(f:Int => String)• bar(foo) // works• bar(x => x.toString)• bar { x => x.toString }• bar(_.toString)
Use function as value: Ruby case
• def foo(x)• f = method(:foo)• f = ->(x){ foo(x) }• def bar1(f)• def bar2(&f)• bar1(f)• bar2 {|x| foo(x) }• bar2(&f)
Use any object as function
• [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"]• map(&:to_s) • It behave like Scala's map(_.toString)• If block value is given, Ruby runtime call its
"to_proc" method and use the result value as block.
• Ruby's Symbol class has to_proc method• :to_s.to_proc #=> {|obj| obj.to_s }
Collections
• Literals• Ruby: {}, []• Scala: ()
• Neither list nor hash literals
Collections
TupleN
Map HashMapLinkedHashM
apHashMap
Seq
immutable
LinkedHashMap
List
Stack
mutable
Buffer
Traversable
Array
Hash
Enumerable
{key => value}
[1, 2, 3]
(a, b)
Ruby has "Big" classes
• "Array" is generic, mutable data structure, it can, push/pop, shift/pop, insert, indexed and sequential access, and also used as tuple
• "Hash" is generic, mutable (and only) key-vakue map structure in Ruby standard library
Transform collection in Big-class style
• [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"]• Ruby has few Big collection classes.
Everything goes simple.
Transform collection in Scala
• Iterator[A].map(f:A => B):Iterator[B]• List[A].map(f:A => B):List[B]• BitSet.map(f:Int => Int):BitSet• BitSet.map(f:Int =>
String):SortedSet[String]• Magic "CanBuildFrom" implicit argument is
used to solve this problem.• def map[B, That](f: (Int) ⇒ B)(implicit bf:
CanBuildFrom[A, B, That]): That• Scala used types VERY MUCH.It's cool.
How to ehnahce existing class in Scala
• implicit conversion• subclassing
How to ehnahce existing class in Ruby
• subclassing• direct modification(simplly
overwrite/alias_method_chain)• define singleton method• include/extend• refinements
How to handle "non-existens value"
• Scala: Option[T]• Ruby: ♥nil♥
• false and nil is "falsy". Other values are "truthy".
• obj.foo if obj # call obj.foo if obj is not nil• obj.try(:foo) # same (ActiveSupport
feature)
Conclusion
• Ruby and Scala is very different, but they share same goal: be productive, be fun.
• There are many different approach to solve problems.We can learn things and achieve fresh surprise from other culture.
Have a fun with various programming!!
Today I want talk to:• Libraries
• rubygems: High accessibility• Source distribution• Easy to publish
• maven repo: Top on Java ecosystem• Some impedance missmatch• Binary distribution• Bit difficult to publish, especially official repo.
• Build/Task system• Rake: Simple scripting with internal DSL• Sbt: Type-safe and immutable dependency graph construction with cool := ++=
<<= s• It's Scala's way!!
• Community• Ruby: Humanity
• Love emotional context• Scala: Types
• Love Monads !!!!