3. The beating heart of Java is not the Java
programming language - it is the JVM and the
entire infrastructure built around it...
Maximus Decimus Meridius,
Roman General & Java Programmer
4. Езикът Java
Създаден да замени С++
Интегрира някои добри идеи от Lisp
Характеризира се с консервативен, но
практичен дизайн
5. Проблемите на езикът
Java
Не е чист обектно-ориентиран език
Няма никаква поддръжка за функционален
стил на програмиране
Не е особено експресивен
Развитието му е ограничено от
изискванията за обратна съвместимост
6. Че то алтернативи има
ли?
1996 - Java 1.0
1997 - 40 езика вече имат версия за JVM
2004 - 169 са JVM compatible
2011 - приблизително 300 езика се целят
в JVM
7. Причината?
The JVM is rock solid and heart touching at
the same time.
Отлична производителност и прекрасен
optimizer
Огромна база съществуващ Java код
Купища страхотни иструменти
8. Не всичко е ток и жица
Java (< 7) нямаше поддръжка за динамичен
метод dispatching
JVM не е оптимизиран за функционален стил
на програмиране
JVM пали относително бавно
JVM имплементациите на някои езици (като
Python) не са съвсем съвместими с native (C)
имплементациите им
9. Двете страни на
Силата
Езици портнати към JVM
Езици създадени специално за JVM
14. Hello, Ruby
# Output "I love Ruby"
say = "I love Ruby"
puts say
# Output "I *LOVE* RUBY"
say['love'] = "*love*"
puts say.upcase
# Output "I *love* Ruby"
# five times
5.times { puts say }
15. JRuby - Java & Ruby
sitting in a tree
Ruby е елегантен език с бавен runtime
JVM е много бърз runtime
JRuby дава възможност на Java
програмистите да използват технологии
като Rails
JRuby дава възможност на Ruby
програмистите да ползват Java
библиотеки
17. Ако прилича на
патица...
class Duck
def walk
puts "The duck walks"
end
def quack
puts "The duck quacks"
end
end
class Dog
def walk
puts "The dog walks"
end
def quack
puts "The dog quacks"
end
end
def test_animal(animal)
animal.walk
animal.quack
end
test_animal(Duck.new)
test_animal(Dog.new)
18. Java от Ruby
require 'java'
java_import 'java.lang.System'
java_import 'java.util.ArrayList'
java_import 'javax.swing.JOptionPane'
System.out.println("Feel the power of JRuby")
## using snake_names for Java method names
puts System.current_time_millis
## regular names work as well
puts System.currentTimeMillis
array_list = ArrayList.new
## the array list supports some common Ruby idioms
array_list << 1
array_list.add 2
array_list << 3
puts "List length is ##{array_list.length}"
array_list.each { |elem| puts elem }
## a glimpse of Swing
JOptionPane.show_message_dialog(nil, "This is a message from the future of Ruby!")
19. Ruby от Java
import org.jruby.embed.InvokeFailedException;
import org.jruby.embed.ScriptingContainer;
public class RubyFromJava {
public static void main(String[] args) {
ScriptingContainer container = new
ScriptingContainer();
container.runScriptlet("puts 'Ruby bridge
established successfully'" );
}
}
20. Стана ми интересно,
къде да науча повече?
http://batsov.com/articles/2011/05/18/jvm-
langs-jruby/
22. Хвала на Groovy
Groovy is like a super version of Java. It can
leverage Java's enterprise capabilities but also has
cool productivity features like closures, builders
and dynamic typing. If you are a developer, tester
or script guru, you have to love Groovy.
23. def name='World'; println "Hello $name!"
class Greet {
def name
Greet(who) { name = who[0].toUpperCase() +
who[1..-1] }
def salute() { println "Hello $name!" }
}
g = new Greet('world') // create object
g.salute() // output "Hello World!"
import static
org.apache.commons.lang.WordUtils.*
class Greeter extends Greet {
Greeter(who) { name = capitalize(who) }
}
new Greeter('world').salute()
groovy -e "println 'Hello ' + args[0]" World
26. Groovy & Java
Groovy програмите се компилират до Java
bytecode
Същите низове, същите регулярни изрази и т.н.
Същите API
Същия модел за сигурност, същия нишков
модел
Същите ОО концепции
27. // old school Java code, but also valid Groovy code
System.out.println("Hello, world!");
// idiomatic Groovy
println "Hello, world!"
// dynamic variable definition
def name = "Bozhidar"
// GString featuring string interpolation
println "Hello, $name" // => "Hello, Bozhidar"
// statically typed variable
String songName = "Coding in the Name of"
println "Now playing - $songName"
String multiline = """this is a multiline
string. There is not need to embed
newline characters in it"""
println multiline
// method definition
def greet(name) {
println "Hello, $name!"
}
// method invocation
greet "Bozhidar"
greet("Bozhidar")
28. showSize([1, 2, 3])
// this is the important part
showSize(null)
// a list
def beers = ["Zagorka", "Bolyarka", "Shumensko", "Ariana"]
// list access
println "My favourite beer is ${beers[1]}"
beers.each { beer -> println beer }
// imports can appear anywhere and support the creation of
aliases
import static java.util.Calendar.getInstance as now
import java.sql.Date as SDate
println now()
// java.util package is automatically imported in Groovy so this
is java.util.Date
println new Date()
println new SDate(2011, 5, 5)
29. // language support for regular expressions
if ("Hello, Groovy" =~ /w+,sw+/) {
println "It matches"
}
// range filtering with higher-order functions
(1..10).findAll { n -> n % 2 == 0}.each { n -> println n }
// map
def capitols = [Bulgaria: "Sofia", USA: "Washington", England:"London", France:"Paris"]
println capitols["Bulgaria"] // => Sofia
println capitols["France"] // => Paris
// class definition
class Person {
def name
def age
Person(name, age) {
this.name = name
this.age = age
}
@Override
String toString() {
return "Name {$name}, age {$age}"
}
}
def me = new Person("Bozhidar", 26)
println me
35. Приложения убийци
(killer apps)
Grails - модерна платформа за разработка
на уеб приложения, вдъхновена от Ruby on
Rails
Gradle - могъщ build tool, създаден да
наследи Maven
Griffon - модерна платформа за
разработка на Swing приложения
37. Where do we go now?
http://batsov.com/articles/2011/05/06/jvm-
langs-groovy/
38. Ride the eSCALAtor
If I were to pick a
language to use today
other than Java, it would
be Scala...
James Gosling, father of Java
39. Отмъщението на статично
типизираните езици
Scala е статично типизиран език (като
Java)
Scala използва type inference механизъм,
който сериозно намалява типовите
декларации
Кодът написан на Scala е толкова сигурен
и бърз, колкото този написан на Java
40. ООП и ФП могат да
съжителстват в мир и любов
Scala е чисто обектно-ориентиран език
Scala включва в себе си много елементи от
функционалното програмиране
higher order functions
function objects
pattern matching
tail recursion
42. Компактен код, без
излишна церемония
public boolean hasUpperCase(String word) {
if (word == null) {
return false;
Java }
int len = word.length();
for (int i = 0; i < len; i++) {
if (Character.isUpperCase(word.charAt(i))) {
return true;
}
}
return false;
}
Scala
def hasUppercase(word: String) = if (word != null) word.exists(_.isUpperCase) else false
43. Оптимизиран за
Java мързели
class Person {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
Scala
return name;
} class Person(var name: String, var age: Int)
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
44. Актьорско майсторство
import scala.actors.Actor._
case class Add(x: Int, y: Int)
case class Sub(x: Int, y: Int)
val mathService = actor {
loop {
receive {
case Add(x, y) => reply(x + y)
case Sub(x, y) => reply(x - y)
}
}
}
mathService !? Add(1, 3) // returns 4
mathService !? Sub(5, 2) // returns 3
45. Патоците на власт!
class Duck {
def quack = println("The duck quacks")
def walk = println("The duck walks")
}
class Dog {
def quack = println("The dog quacks (barks)")
def walk = println("The dog walks")
}
def testDuckTyping(animal: { def quack; def walk }) = {
animal.quack
animal.walk
}
scala> testDuckTyping(new Duck)
The duck quacks
The duck walks
scala> testDuckTyping(new Dog)
The dog quacks (barks)
The dog walks
46. Pimp my library
scala> implicit def intarray2sum(x: Array[Int]) = x.reduceLeft(_ + _)
intarray2sum: (x: Array[Int])Int
scala> val x = Array(1, 2, 3)
x: Array[Int] = Array(1, 2, 3)
scala> val y = Array(4, 5, 6)
y: Array[Int] = Array(4, 5, 6)
scala> val z = x + y
z: Int = 21
47. Малко повече екшън
scala> println("Hello, Scala")
Hello, Scala
scala> val name = "Bozhidar"
name: java.lang.String = Bozhidar
scala> Predef.println("My name is "+name)
My name is Bozhidar
scala> var someNumber: Int = 5
someNumber: Int = 5
scala> var names = Array("Superman", "Batman", "The Flash", "Bozhidar")
names: Array[java.lang.String] = Array(Superman, Batman, The Flash,
Bozhidar)
scala> names.filter(name => name.startsWith("B"))
res6: Array[java.lang.String] = Array(Batman, Bozhidar)
scala> names.length
res7: Int = 4
scala> name.length()
res8: Int = 8
48. ...
scala> import java.util.Date
import java.util.Date
scala> var currentDate = new Date
currentDate: java.util.Date = Wed May 11 15:03:20 EEST 2011
scala> println("Now is " + currentDate)
Now is Wed May 11 15:03:20 EEST 2011
scala> currentDate.toString
res10: java.lang.String = Wed May 11 15:03:20 EEST 2011
scala> currentDate.toString()
res11: java.lang.String = Wed May 11 15:03:20 EEST 2011
scala> currentDate toString
res12: java.lang.String = Wed May 11 15:03:20 EEST 2011
49. Closures
scala> var x = 10
x: Int = 10
scala> val addToX = (y: Int) => x + y
addToX: (Int) => Int = <function1>
scala> addToX(2)
res0: Int = 12
scala> addToX(6)
res1: Int = 16
scala> x = 5
x: Int = 5
scala> addToX(10)
res2: Int = 15
52. Pattern matching
scala> def testMatching(something: Any) = something match {
| case 1 => "one"
| case "two" => 2
| case x: Int => "an integer number"
| case x: String => "some string"
| case <xmltag>{content}</xmltag> => content
| case head :: tail => head
| case _ => "something else entirely"
| }
testMatching: (something: Any)Any
scala> testMatching(1)
res18: Any = one
scala> testMatching("two")
res19: Any = 2
scala> testMatching(2)
res20: Any = an integer number
scala> testMatching("matrix")
res21: Any = some string
scala> testMatching(<xmltag>this is in the tag</xmltag>)
res22: Any = this is in the tag
scala> testMatching(List(1, 2, 3))
res23: Any = 1
scala> testMatching(3.9)
res24: Any = something else entirely
53. Plain recursion
def length(list: List[Any]): Int = list match {
case head :: tail => 1 + length(tail)
case Nil => 0
}
Tail recursion
def length(list: List[Any]): Int = {
def lengthrec(list: List[Any], result: Int): Int =
list match {
case head :: tail => lengthrec(tail, result + 1)
case Nil => result
}
lengthrec(list, 0)
}
58. “Clojure feels like a general-purpose language
beamed back from the near future. Its support
for functional programming and software trans-
actional memory is well beyond current practice
and is well suited for multicore hardware. At the
same time, Clojure is well grounded in the past
and the present. It brings together Lisp and the
Java Virtual Machine. Lisp brings wisdom spanning
most of the history of programming, and Java
brings the robustness, extensive libraries, and
tooling of the dominant platform available today.”
59.
60. What happens when an
unstoppable force meets an
immutable object?
Clojure is dynamic
Clojure is functional
Clojure is a Lisp(1)
Clojure is designed for concurrency
Clojure is fighting accidental complexity
61. Стил
public boolean hasUpperCase(String word) {
if (word == null) {
return false;
}
int len = word.length();
for (int i = 0; i < len; i++) {
if (Character.isUpperCase(word.charAt(i))) {
return true;
}
}
return false;
}
(defn has-uppercase? [string]
(some #(Character/isUpperCase %) string))
62. Компактност
class Person {
private String name;
private int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name; (defrecord person [name age])
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
63. Силата е на ваша
страна
(defmacro and
"Evaluates exprs one at a time, from left to
right. If a form
returns logical false (nil or false), and returns
that value and
doesn't evaluate any of the other expressions,
otherwise it returns
the value of the last expr. (and) returns true."
{:added "1.0"}
([] true)
([x] x)
([x & next]
`(let [and# ~x]
(if and# (and ~@next) and#))))
64. ;;; Lists
;; list creation
user> (list 1 2 3)
(1 2 3)
Сърцето на Clojure
;; quoted list creation
user> (def a-list '(1 2 3 4 5 6 7 8 9 10))
#'user/a-list
;; find the size of a list
user> (count a-list)
10
user> (first a-list)
1
user> (rest a-list)
(2 3 4 5 6 7 8 9 10)
user> (last a-list)
10
;; find the elements of the list matching a predicate(boolean
function)
user> (filter even? a-list)
(2 4 6 8 10)
user> (filter odd? a-list)
(1 3 5 7 9)
;; map an anonymous(lambda) function to all elements of the list
user> (map #(* % 2) a-list)
(2 4 6 8 10 12 14 16 18 20)
;; add an element to the beginning of the list
user> (cons 0 a-list)
(0 1 2 3 4 5 6 7 8 9 10)
;; cons in a list specific function, conj is a general purpose one and
;; works on all collection (but in a different manner)
user> (conj a-list 0)
(0 1 2 3 4 5 6 7 8 9 10)