SlideShare a Scribd company logo
Модерни езици за
програмира за JVM
  JRuby, Groovy, Scala и Clojure.
Що е Java?


Програмен език

Виртуална машина

Стандартна библиотека
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
Езикът Java


Създаден да замени С++

Интегрира някои добри идеи от Lisp

Характеризира се с консервативен, но
практичен дизайн
Проблемите на езикът
       Java
 Не е чист обектно-ориентиран език

 Няма никаква поддръжка за функционален
 стил на програмиране

 Не е особено експресивен

 Развитието му е ограничено от
 изискванията за обратна съвместимост
Че то алтернативи има
         ли?
 1996 - Java 1.0

 1997 - 40 езика вече имат версия за JVM

 2004 - 169 са JVM compatible

 2011 - приблизително 300 езика се целят
 в JVM
Причината?

The JVM is rock solid and heart touching at
the same time.

Отлична производителност и прекрасен
optimizer

Огромна база съществуващ Java код

Купища страхотни иструменти
Не всичко е ток и жица
 Java (< 7) нямаше поддръжка за динамичен
 метод dispatching

 JVM не е оптимизиран за функционален стил
 на програмиране

 JVM пали относително бавно

 JVM имплементациите на някои езици (като
 Python) не са съвсем съвместими с native (C)
 имплементациите им
Двете страни на
      Силата


Езици портнати към JVM

Езици създадени специално за JVM
Претендентите
JRuby

Jython

Fantom

Groovy

Scala

Clojure
Ruby

динамичен език за програмиране

компактен и елегантен синтаксис

създаден да направи програмистите
щастливи

made in Japan
Преди Ruby
Сега (като Ruby
 програмист)
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 }
JRuby - Java & Ruby
  sitting in a tree
Ruby е елегантен език с бавен runtime

JVM е много бърз runtime

JRuby дава възможност на Java
програмистите да използват технологии
като Rails

JRuby дава възможност на Ruby
програмистите да ползват Java
библиотеки
Загрявка в jirb
jruby-1.6.1 :001 > puts "Hello, JRuby"
Hello, JRuby
 => nil
jruby-1.6.1 :002 > arr = ["Chuck", "Sarah", "Morgan", "Casey"]
 => ["Chuck", "Sarah", "Morgan", "Casey"]
jruby-1.6.1 :003 > arr.length
 => 4
jruby-1.6.1 :004 > arr.size
 => 4
jruby-1.6.1 :005 > arr.size()
 => 4
jruby-1.6.1 :006 > arr.each { |name| puts name }
Chuck
Sarah
Morgan
Casey
 => ["Chuck", "Sarah", "Morgan", "Casey"]
jruby-1.6.1 :007 > arr.each_with_index { |name, index| puts "##{index}:
#{name}"}
0: Chuck
1: Sarah
2: Morgan
3: Casey
 => ["Chuck", "Sarah", "Morgan", "Casey"]
Ако прилича на
   патица...
   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)
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!")
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'" );
    }
}
Стана ми интересно,
къде да науча повече?


http://batsov.com/articles/2011/05/18/jvm-
langs-jruby/
It’s a Groovy kind of
        love...
Хвала на 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.
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
Groovy e...

динамичен

изцяло обектно-ориентиран

вдъхновен от Ruby, Python и Smalltalk

със синтаксис много близък до този на
Java

създаден да улесни живота на Java
програмистите
Ключовите моменти

closures

attributes

duck typing

аритметика базирана на BigDecimal

улеснена работа с XML, SQL, Swing, etc
Groovy & Java
Groovy програмите се компилират до Java
bytecode

Същите низове, същите регулярни изрази и т.н.

Същите API

Същия модел за сигурност, същия нишков
модел

Същите ОО концепции
// 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")
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)
// 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
JDBC подобрения
import groovy.sql.Sql
sql = Sql.newInstance("jdbc:mysql://host/db", "username", "password",
"com.mysql.jdbc.Driver")
sql.eachRow("select * from tableName", { println it.id + " -- ${it.firstName} --"} )




                       Изход от програмата
                                 1   --   Bozhidar --
                                 2   --   Jim --
                                 3   --   Jack --
                                 4   --   Valentine --
XML
                 <books>
                     <book>
                         <title>Dune</title>
                         <author firstname="Frank" lastname="Herbert"/>
                     </book>
                     <book>
                         <title>Dune Messiah</title>
                         <author firstname="Frank" lastname="Herbert"/>
                     </book>
                     <book>
                         <title>Children of Dune</title>
                         <author firstname="Frank" lastname="Herbert"/>
                     </book>
                     <book>
                         <title>A Game of Thrones</title>
                         <author firstname="George" lastname="Martin"/>
                     </book>
                 </books>



def books = new XmlSlurper().parse("books.xml")
books.book.each {
    println "Title = ${it.title}, Author: ${it.author.@firstname} ${it.author.@lastname}"
}
Builders
import groovy.xml.*                   <html>
                                        <head>
def page = new MarkupBuilder()            <title>Hello, Groovy!</
page.html {                           title>
    head { title 'Hello, Groovy!' }     </head>
    body {                              <body>
        div {                             <div>
            3.times {                       <p>Groovy power!</p>
                p "Groovy power!"           <p>Groovy power!</p>
            }                               <p>Groovy power!</p>
        }                                 </div>
    }                                   </body>
}                                     </html>
Swing
import java.awt.FlowLayout

builder = new groovy.swing.SwingBuilder()
langs = ["Groovy", "Scala", "Clojure"]
gui = builder.frame(size: [290, 100], title: 'Groovy Swing') {
    panel(layout: new FlowLayout()) {
        panel(layout: new FlowLayout()) {
            for (lang in langs) {
                radioButton(text: lang)
            }
        }
        button(text: 'Perform Magic', actionPerformed: {
            builder.optionPane(message: "Feel the power of Groovy!").
                    createDialog(null, 'Message').show()
        })
        button(text: 'Quit',
                actionPerformed: {System.exit(0)})
    }
}
gui.show()
Инструментите на
      занаята

groovy - интерпретатор

groovysh - конзола

groovyc - компилатор

groovyconsole - графична конзола
Приложения убийци
   (killer apps)
Grails - модерна платформа за разработка
на уеб приложения, вдъхновена от Ruby on
Rails

Gradle - могъщ build tool, създаден да
наследи Maven

Griffon - модерна платформа за
разработка на Swing приложения
IDE-та, нещо?


IntelliJ IDEA - Bozhidar’s Choice

Eclipse

NetBeans
Where do we go now?



http://batsov.com/articles/2011/05/06/jvm-
langs-groovy/
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
Отмъщението на статично
  типизираните езици
 Scala е статично типизиран език (като
 Java)

 Scala използва type inference механизъм,
 който сериозно намалява типовите
 декларации

 Кодът написан на Scala е толкова сигурен
 и бърз, колкото този написан на Java
ООП и ФП могат да
съжителстват в мир и любов
  Scala е чисто обектно-ориентиран език

  Scala включва в себе си много елементи от
  функционалното програмиране

    higher order functions

    function objects

    pattern matching

    tail recursion
Expressive

scala> val romanToArabic = Map("I" -> 1, "II" -> 2, "III" -> 3, "IV" -> 4, "V" -> 5)
romanToArabic: scala.collection.immutable.Map[java.lang.String,Int] = Map((II,2),
(IV,4), (I,1), (V,5), (III,3))

scala> romanToArabic("I")
res2: Int = 1

scala> romanToArabic("II")
res3: Int = 2
Компактен код, без
            излишна церемония
                  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
Оптимизиран за
          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;
    }
}
Актьорско майсторство
   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
Патоците на власт!
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
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
Малко повече екшън
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
...
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
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
Свързани списъци
scala> 1 :: 2 :: 3 :: 4 :: 5 :: Nil
res3: List[Int] = List(1, 2, 3, 4, 5)

scala> val names = List("Neo", "Trinity", "Morpheus", "Tank", "Dozer")
names: List[java.lang.String] = List(Neo, Trinity, Morpheus, Tank,
Dozer)

scala> names.length
res4: Int = 5

scala> names.foreach(println)
Neo
Trinity
Morpheus
Tank
Dozer

scala> names.map(_.toUpperCase)
res6: List[java.lang.String] = List(NEO, TRINITY, MORPHEUS, TANK,
DOZER)

scala> names.forall(_.length > 5)
res7: Boolean = false

scala> names.forall(_.length > 2)
res8: Boolean = true
...
scala> names.filter(_.startsWith("T"))
res9: List[java.lang.String] = List(Trinity, Tank)

scala> names.exists(_.length == 3)
res10: Boolean = true

scala> names.drop(2)
res11: List[java.lang.String] = List(Morpheus, Tank, Dozer)

scala> names.reverse
res12: List[java.lang.String] = List(Dozer, Tank, Morpheus, Trinity, Neo)

scala> names.sortBy(_.length)
res13: List[java.lang.String] = List(Neo, Tank, Dozer, Trinity, Morpheus)

scala> names.sort(_ > _)
res14: List[java.lang.String] = List(Trinity, Tank, Neo, Morpheus, Dozer)

scala> names.slice(2, 4)
res16: List[java.lang.String] = List(Morpheus, Tank)
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
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)
}
Инвентара


scala - конзола/интерпретатор

scalac - компилатор

fsc - fast scala compiler
IDE-тата


IntelliJ IDEA - Bozhidar’s Choice

Eclipse - Official Scala IDE

NetBeans - на тоя етап е бран бостан
Убийците

Play! Framework

Lift

SBT (Simple Build Tool)

Akka
The full disclosure on
       Clojure
“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.”
Модерни езици за програмиране за JVM (2011)
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
Стил
 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))
Компактност
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;
    }
}
Силата е на ваша
         страна
(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#))))
;;; 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)
;; retrieve the first five items in a list
user> (take 5 a-list)
                                                     ...
(1 2 3 4 5)
;; retrieve all but the first five items in a list
user> (drop 5 a-list)
(6 7 8 9 10)
user> (take-while #(< % 3) a-list)
(1 2)
user> (drop-while #(> % 3) a-list)
(1 2 3 4 5 6 7 8 9 10)
user> (drop-while #(< % 3) a-list)
(3 4 5 6 7 8 9 10)

;;; Sets

user> (set '(1 2 3 4 5   1 2 3 4))
#{1 2 3 4 5}
user> (def a-set #{1 2   3 4 5})
#'user/a-set
user> (contains? a-set   3)
true
user> (contains? a-set   7)
false
user> (conj a-set 5)
#{1 2 3 4 5}
user> (conj a-set 6)
#{1 2 3 4 5 6}
user> (disj a-set 1)
#{2 3 4 5}
user> (get a-set 1)
1
user> (get a-set 7)
nil
Хешове

;;; Maps
user> (hash-map :Bozhidar :Batsov :Bruce :Wayne :Selina :Kyle)
{:Selina :Kyle, :Bozhidar :Batsov, :Bruce :Wayne}
user> (def a-map {:Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle})
#'user/a-map
user> a-map
{:Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle}
user> (get a-map :Bozhidar)
:Batsov
user> (contains? a-map :Bozhidar)
true
user> (contains? a-map :Clark)
false
user> (:Bozhidar a-map)
:Batsov
user> (assoc a-map :Lois :Lane)
{:Lois :Lane, :Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle}
user> (keys a-map)
(:Bozhidar :Bruce :Selina)
user> (vals a-map)
(:Batsov :Wayne :Kyle)
user> (dissoc a-map :Bruce)
{:Bozhidar :Batsov, :Selina :Kyle}
user> (merge a-map {:Alia :Atreides, :Arya :Stark})
{:Arya :Stark, :Alia :Atreides, :Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle}
Вектори
;;; Vectors

user> (vector 1 2 3 4)
[1 2 3 4]
user> [1 2 3 4]
[1 2 3 4]
user> (def a-vector [1 2 3 4 5])
#'user/a-vector
user> (count a-vector)
5
user> (conj a-vector 13)
[1 2 3 4 5 13]
;; random access is a constant time operation in
vectors
user> (nth a-vector 3)
4
user> (pop a-vector)
[1 2 3 4]
user> (peek a-vector)
5
Програмиране с refs
(def picked-numbers (ref #{})

(def secret-num (.nextInt (java.util.Random.) 10))

(defn guess-number [n]
        (print "Enter a guess between 1 and 10: ")
        (flush)
        (let [guess (java.lang.Integer/parseInt (read-line)) ]
             (cond
                (= guess n) (println "You guessed correctly")
                (contains? (deref picked-numbers) n) (println "Pick another number!
You already tried that one.")
                :else (dosync
                       (alter picked-numbers conj guess)))))

user=> (guess-number secret-num)
Enter a guess between 1 and 10: 1
#{1}
user=> (guess-number secret-num)
Enter a guess between 1 and 10: 3
#{1 3}
user=> (guess-number secret-num)
Enter a guess between 1 and 10: 5
#{1 3 5}
Атоми

(def picked-numbers (atom #{})

(def secret-num (.nextInt (java.util.Random.) 10))

(defn guess-number [n]
        (print "Enter a guess between 1 and 10: ")
        (flush)
        (let [guess (java.lang.Integer/parseInt (read-line)) ]
             (cond
                (= guess n) (println "You guessed correctly")
                (contains? (deref picked-numbers) n) (println "Pick another number!
You already tried that one.")
                :else (swap! picked-numbers conj guess))))

user=> (guess-number secret-num)
Enter a guess between 1 and 10: 1
#{1}
user=> (guess-number secret-num)
Enter a guess between 1 and 10: 3
#{1 3}
user=> (guess-number secret-num)
Enter a guess between 1 and 10: 5
#{1 3 5}
ООП по
           Лиспаджийски

(defmulti my-add (fn [x y] (and (string? x) (string? y))))

(defmethod my-add true [x y]
    (str x y))

(defmethod my-add false [x y]
    (+ x y))

user=> (my-add 3 4) ; => 7
user=> (my-add "3" "4") ; => "34"
Екстремист съм, какво
     ми трябва?
 Обичайните заподозрени

   Eclipse

   IntelliJ

   NetBeans

 Emacs + SLIME = Bozhidar’s Choice
Повече инфо, моля!



http://batsov.com/articles/2011/05/12/jvm-
langs-clojure/
Stay hungry,
stay foolish!
FIN

More Related Content

PDF
Testing Web Applications with GEB
KEY
Dispatch in Clojure
PDF
Backbone.js: Run your Application Inside The Browser
PPTX
Python mongo db-training-europython-2011
PDF
Oscon Java Testing on the Fast Lane
PDF
Moose workshop
PDF
Rest in flask
PDF
Clojure and the Web
Testing Web Applications with GEB
Dispatch in Clojure
Backbone.js: Run your Application Inside The Browser
Python mongo db-training-europython-2011
Oscon Java Testing on the Fast Lane
Moose workshop
Rest in flask
Clojure and the Web

What's hot (19)

PDF
RubyEnRails2007 - Dr Nic Williams - Keynote
PDF
Node.js in action
PDF
Introduction to Nodejs
PDF
Alfresco the clojure way -- Slides from the Alfresco DevCon2011
PDF
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
KEY
CouchDB on Android
PDF
Scala Frustrations
PDF
#살아있다 #자프링외길12년차 #코프링2개월생존기
PDF
The state of your own hypertext preprocessor
KEY
Building a real life application in node js
ODP
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
PPTX
KISSY 的昨天、今天与明天
PDF
kissy-past-now-future
KEY
Introduction to Ruby MagLev
PDF
Kickin' Ass with Cache-Fu (without notes)
 
PDF
BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
PDF
Py conkr 20150829_docker-python
PDF
From mysql to MongoDB(MongoDB2011北京交流会)
PDF
Coffeescript: No really, it's just Javascript
RubyEnRails2007 - Dr Nic Williams - Keynote
Node.js in action
Introduction to Nodejs
Alfresco the clojure way -- Slides from the Alfresco DevCon2011
RubyEnRails2007 - Dr Nic Williams - DIY Syntax
CouchDB on Android
Scala Frustrations
#살아있다 #자프링외길12년차 #코프링2개월생존기
The state of your own hypertext preprocessor
Building a real life application in node js
High Performance XQuery Processing in PHP with Zorba by Vikram Vaswani
KISSY 的昨天、今天与明天
kissy-past-now-future
Introduction to Ruby MagLev
Kickin' Ass with Cache-Fu (without notes)
 
BDD - Behavior Driven Development Webapps mit Groovy Spock und Geb
Py conkr 20150829_docker-python
From mysql to MongoDB(MongoDB2011北京交流会)
Coffeescript: No really, it's just Javascript
Ad

Similar to Модерни езици за програмиране за JVM (2011) (20)

PDF
OpenLogic
PDF
The Future of JVM Languages
KEY
Groovy & Grails
PDF
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
PDF
groovy
PDF
Groovy And Grails JUG Trento
PDF
Atlassian Groovy Plugins
PDF
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
PDF
Groovy Up Your Code
ZIP
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
PDF
Presentatie - Introductie in Groovy
PDF
淺談 Groovy 與 AWS 雲端應用開發整合
PPTX
Groovy And Grails Introduction
KEY
Grails TV : an introduction into Grails & Groovy
PDF
Groovy a Scripting Language for Java
ODP
Getting groovy (ODP)
KEY
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
PDF
What is new and cool j2se & java
PDF
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
PDF
JavaCro 2016 - From Java to Groovy: Adventure Time!
OpenLogic
The Future of JVM Languages
Groovy & Grails
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
groovy
Groovy And Grails JUG Trento
Atlassian Groovy Plugins
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy Up Your Code
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Presentatie - Introductie in Groovy
淺談 Groovy 與 AWS 雲端應用開發整合
Groovy And Grails Introduction
Grails TV : an introduction into Grails & Groovy
Groovy a Scripting Language for Java
Getting groovy (ODP)
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
What is new and cool j2se & java
Building Atlassian Plugins with Groovy - Atlassian Summit 2010 - Lightning Talks
JavaCro 2016 - From Java to Groovy: Adventure Time!
Ad

Recently uploaded (20)

PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Encapsulation theory and applications.pdf
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Review of recent advances in non-invasive hemoglobin estimation
PPTX
A Presentation on Artificial Intelligence
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
The Rise and Fall of 3GPP – Time for a Sabbatical?
Mobile App Security Testing_ A Comprehensive Guide.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Encapsulation theory and applications.pdf
Building Integrated photovoltaic BIPV_UPV.pdf
NewMind AI Weekly Chronicles - August'25 Week I
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
“AI and Expert System Decision Support & Business Intelligence Systems”
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
20250228 LYD VKU AI Blended-Learning.pptx
Reach Out and Touch Someone: Haptics and Empathic Computing
Advanced methodologies resolving dimensionality complications for autism neur...
Review of recent advances in non-invasive hemoglobin estimation
A Presentation on Artificial Intelligence
MYSQL Presentation for SQL database connectivity
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Digital-Transformation-Roadmap-for-Companies.pptx

Модерни езици за програмиране за JVM (2011)

  • 1. Модерни езици за програмира за JVM JRuby, Groovy, Scala и Clojure.
  • 2. Що е Java? Програмен език Виртуална машина Стандартна библиотека
  • 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
  • 11. Ruby динамичен език за програмиране компактен и елегантен синтаксис създаден да направи програмистите щастливи made in Japan
  • 13. Сега (като Ruby програмист)
  • 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 библиотеки
  • 16. Загрявка в jirb jruby-1.6.1 :001 > puts "Hello, JRuby" Hello, JRuby => nil jruby-1.6.1 :002 > arr = ["Chuck", "Sarah", "Morgan", "Casey"] => ["Chuck", "Sarah", "Morgan", "Casey"] jruby-1.6.1 :003 > arr.length => 4 jruby-1.6.1 :004 > arr.size => 4 jruby-1.6.1 :005 > arr.size() => 4 jruby-1.6.1 :006 > arr.each { |name| puts name } Chuck Sarah Morgan Casey => ["Chuck", "Sarah", "Morgan", "Casey"] jruby-1.6.1 :007 > arr.each_with_index { |name, index| puts "##{index}: #{name}"} 0: Chuck 1: Sarah 2: Morgan 3: Casey => ["Chuck", "Sarah", "Morgan", "Casey"]
  • 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/
  • 21. It’s a Groovy kind of love...
  • 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
  • 24. Groovy e... динамичен изцяло обектно-ориентиран вдъхновен от Ruby, Python и Smalltalk със синтаксис много близък до този на Java създаден да улесни живота на Java програмистите
  • 25. Ключовите моменти closures attributes duck typing аритметика базирана на BigDecimal улеснена работа с XML, SQL, Swing, etc
  • 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
  • 30. JDBC подобрения import groovy.sql.Sql sql = Sql.newInstance("jdbc:mysql://host/db", "username", "password", "com.mysql.jdbc.Driver") sql.eachRow("select * from tableName", { println it.id + " -- ${it.firstName} --"} ) Изход от програмата 1 -- Bozhidar -- 2 -- Jim -- 3 -- Jack -- 4 -- Valentine --
  • 31. XML <books> <book> <title>Dune</title> <author firstname="Frank" lastname="Herbert"/> </book> <book> <title>Dune Messiah</title> <author firstname="Frank" lastname="Herbert"/> </book> <book> <title>Children of Dune</title> <author firstname="Frank" lastname="Herbert"/> </book> <book> <title>A Game of Thrones</title> <author firstname="George" lastname="Martin"/> </book> </books> def books = new XmlSlurper().parse("books.xml") books.book.each { println "Title = ${it.title}, Author: ${it.author.@firstname} ${it.author.@lastname}" }
  • 32. Builders import groovy.xml.* <html> <head> def page = new MarkupBuilder() <title>Hello, Groovy!</ page.html { title> head { title 'Hello, Groovy!' } </head> body { <body> div { <div> 3.times { <p>Groovy power!</p> p "Groovy power!" <p>Groovy power!</p> } <p>Groovy power!</p> } </div> } </body> } </html>
  • 33. Swing import java.awt.FlowLayout builder = new groovy.swing.SwingBuilder() langs = ["Groovy", "Scala", "Clojure"] gui = builder.frame(size: [290, 100], title: 'Groovy Swing') { panel(layout: new FlowLayout()) { panel(layout: new FlowLayout()) { for (lang in langs) { radioButton(text: lang) } } button(text: 'Perform Magic', actionPerformed: { builder.optionPane(message: "Feel the power of Groovy!"). createDialog(null, 'Message').show() }) button(text: 'Quit', actionPerformed: {System.exit(0)}) } } gui.show()
  • 34. Инструментите на занаята groovy - интерпретатор groovysh - конзола groovyc - компилатор groovyconsole - графична конзола
  • 35. Приложения убийци (killer apps) Grails - модерна платформа за разработка на уеб приложения, вдъхновена от Ruby on Rails Gradle - могъщ build tool, създаден да наследи Maven Griffon - модерна платформа за разработка на Swing приложения
  • 36. IDE-та, нещо? IntelliJ IDEA - Bozhidar’s Choice Eclipse NetBeans
  • 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
  • 41. Expressive scala> val romanToArabic = Map("I" -> 1, "II" -> 2, "III" -> 3, "IV" -> 4, "V" -> 5) romanToArabic: scala.collection.immutable.Map[java.lang.String,Int] = Map((II,2), (IV,4), (I,1), (V,5), (III,3)) scala> romanToArabic("I") res2: Int = 1 scala> romanToArabic("II") res3: Int = 2
  • 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
  • 50. Свързани списъци scala> 1 :: 2 :: 3 :: 4 :: 5 :: Nil res3: List[Int] = List(1, 2, 3, 4, 5) scala> val names = List("Neo", "Trinity", "Morpheus", "Tank", "Dozer") names: List[java.lang.String] = List(Neo, Trinity, Morpheus, Tank, Dozer) scala> names.length res4: Int = 5 scala> names.foreach(println) Neo Trinity Morpheus Tank Dozer scala> names.map(_.toUpperCase) res6: List[java.lang.String] = List(NEO, TRINITY, MORPHEUS, TANK, DOZER) scala> names.forall(_.length > 5) res7: Boolean = false scala> names.forall(_.length > 2) res8: Boolean = true
  • 51. ... scala> names.filter(_.startsWith("T")) res9: List[java.lang.String] = List(Trinity, Tank) scala> names.exists(_.length == 3) res10: Boolean = true scala> names.drop(2) res11: List[java.lang.String] = List(Morpheus, Tank, Dozer) scala> names.reverse res12: List[java.lang.String] = List(Dozer, Tank, Morpheus, Trinity, Neo) scala> names.sortBy(_.length) res13: List[java.lang.String] = List(Neo, Tank, Dozer, Trinity, Morpheus) scala> names.sort(_ > _) res14: List[java.lang.String] = List(Trinity, Tank, Neo, Morpheus, Dozer) scala> names.slice(2, 4) res16: List[java.lang.String] = List(Morpheus, Tank)
  • 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) }
  • 54. Инвентара scala - конзола/интерпретатор scalac - компилатор fsc - fast scala compiler
  • 55. IDE-тата IntelliJ IDEA - Bozhidar’s Choice Eclipse - Official Scala IDE NetBeans - на тоя етап е бран бостан
  • 57. The full disclosure on Clojure
  • 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.”
  • 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)
  • 65. ;; retrieve the first five items in a list user> (take 5 a-list) ... (1 2 3 4 5) ;; retrieve all but the first five items in a list user> (drop 5 a-list) (6 7 8 9 10) user> (take-while #(< % 3) a-list) (1 2) user> (drop-while #(> % 3) a-list) (1 2 3 4 5 6 7 8 9 10) user> (drop-while #(< % 3) a-list) (3 4 5 6 7 8 9 10) ;;; Sets user> (set '(1 2 3 4 5 1 2 3 4)) #{1 2 3 4 5} user> (def a-set #{1 2 3 4 5}) #'user/a-set user> (contains? a-set 3) true user> (contains? a-set 7) false user> (conj a-set 5) #{1 2 3 4 5} user> (conj a-set 6) #{1 2 3 4 5 6} user> (disj a-set 1) #{2 3 4 5} user> (get a-set 1) 1 user> (get a-set 7) nil
  • 66. Хешове ;;; Maps user> (hash-map :Bozhidar :Batsov :Bruce :Wayne :Selina :Kyle) {:Selina :Kyle, :Bozhidar :Batsov, :Bruce :Wayne} user> (def a-map {:Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle}) #'user/a-map user> a-map {:Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle} user> (get a-map :Bozhidar) :Batsov user> (contains? a-map :Bozhidar) true user> (contains? a-map :Clark) false user> (:Bozhidar a-map) :Batsov user> (assoc a-map :Lois :Lane) {:Lois :Lane, :Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle} user> (keys a-map) (:Bozhidar :Bruce :Selina) user> (vals a-map) (:Batsov :Wayne :Kyle) user> (dissoc a-map :Bruce) {:Bozhidar :Batsov, :Selina :Kyle} user> (merge a-map {:Alia :Atreides, :Arya :Stark}) {:Arya :Stark, :Alia :Atreides, :Bozhidar :Batsov, :Bruce :Wayne, :Selina :Kyle}
  • 67. Вектори ;;; Vectors user> (vector 1 2 3 4) [1 2 3 4] user> [1 2 3 4] [1 2 3 4] user> (def a-vector [1 2 3 4 5]) #'user/a-vector user> (count a-vector) 5 user> (conj a-vector 13) [1 2 3 4 5 13] ;; random access is a constant time operation in vectors user> (nth a-vector 3) 4 user> (pop a-vector) [1 2 3 4] user> (peek a-vector) 5
  • 68. Програмиране с refs (def picked-numbers (ref #{}) (def secret-num (.nextInt (java.util.Random.) 10)) (defn guess-number [n] (print "Enter a guess between 1 and 10: ") (flush) (let [guess (java.lang.Integer/parseInt (read-line)) ] (cond (= guess n) (println "You guessed correctly") (contains? (deref picked-numbers) n) (println "Pick another number! You already tried that one.") :else (dosync (alter picked-numbers conj guess))))) user=> (guess-number secret-num) Enter a guess between 1 and 10: 1 #{1} user=> (guess-number secret-num) Enter a guess between 1 and 10: 3 #{1 3} user=> (guess-number secret-num) Enter a guess between 1 and 10: 5 #{1 3 5}
  • 69. Атоми (def picked-numbers (atom #{}) (def secret-num (.nextInt (java.util.Random.) 10)) (defn guess-number [n] (print "Enter a guess between 1 and 10: ") (flush) (let [guess (java.lang.Integer/parseInt (read-line)) ] (cond (= guess n) (println "You guessed correctly") (contains? (deref picked-numbers) n) (println "Pick another number! You already tried that one.") :else (swap! picked-numbers conj guess)))) user=> (guess-number secret-num) Enter a guess between 1 and 10: 1 #{1} user=> (guess-number secret-num) Enter a guess between 1 and 10: 3 #{1 3} user=> (guess-number secret-num) Enter a guess between 1 and 10: 5 #{1 3 5}
  • 70. ООП по Лиспаджийски (defmulti my-add (fn [x y] (and (string? x) (string? y)))) (defmethod my-add true [x y] (str x y)) (defmethod my-add false [x y] (+ x y)) user=> (my-add 3 4) ; => 7 user=> (my-add "3" "4") ; => "34"
  • 71. Екстремист съм, какво ми трябва? Обичайните заподозрени Eclipse IntelliJ NetBeans Emacs + SLIME = Bozhidar’s Choice
  • 74. FIN