SlideShare una empresa de Scribd logo
1 de 44
Descargar para leer sin conexión
Introducción a CloIntroducción a Clojjureure
Una intro a Clojure y por qué usar programación funcionalUna intro a Clojure y por qué usar programación funcional
Denis Fuenzalida – Junio de 2013Denis Fuenzalida – Junio de 2013
denis.fuenzalida@gmail.comdenis.fuenzalida@gmail.com
““Martin Fowler hace la siguienteMartin Fowler hace la siguiente
observación:observación:
El verdadero legado de Java seráEl verdadero legado de Java será
la plataforma, no el lenguaje...la plataforma, no el lenguaje...
...ahora mismo, hay más de 200...ahora mismo, hay más de 200
lenguajes que corren sobre la JVMlenguajes que corren sobre la JVM
yy es inevitable que uno de elloses inevitable que uno de ellos
llegue a superar a Javallegue a superar a Java como lacomo la
mejor forma de programar la JVM.”mejor forma de programar la JVM.”
–– Neal Ford en “Neal Ford en “Java.nextJava.next””
http://nealford.com/pub.htmlhttp://nealford.com/pub.html
# db/seeds.rb# db/seeds.rb
User.find_each(&User.find_each(&:destroy:destroy))
User.create(User.create(emailemail:: 'user@example.org''user@example.org',, passwordpassword:: 'l33t''l33t'))
User.find_each(&:User.find_each(&:reset_authentication_token!reset_authentication_token!))
// ApprovalService.groovy// ApprovalService.groovy
approvers.findAll{ it.userId == approval.userId }.each{approvers.findAll{ it.userId == approval.userId }.each{
it.removable =it.removable = falsefalse
}}
varvar objobj = {= {
"flammable""flammable":: "inflammable""inflammable",,
"duh""duh":: "no duh""no duh"
};};
$$.each( obj,.each( obj, functionfunction(( keykey,, valuevalue ) {) {
alert( key +alert( key + ": "": " + value );+ value );
});});
““Vale la pena aprender Lisp porVale la pena aprender Lisp por
lala profunda experiencia deprofunda experiencia de
iluminacióniluminación que obtendrásque obtendrás
cuando finalmente lo entiendas...cuando finalmente lo entiendas...
...esa experiencia te hará un mejor...esa experiencia te hará un mejor
por programador el resto de tuspor programador el resto de tus
días, incluso si en realidad nuncadías, incluso si en realidad nunca
lo utilizas mucho.”lo utilizas mucho.”
–– Eric S. Raymond en “Eric S. Raymond en “Como convertirse en HackerComo convertirse en Hacker””
http://www.catb.org/esr/faqs/hacker-howto.htmlhttp://www.catb.org/esr/faqs/hacker-howto.html
http://paulgraham.es/ensayos/la-venganza-de-los-nerds.htmlhttp://paulgraham.es/ensayos/la-venganza-de-los-nerds.html
http://mitpress.mit.edu/sicp/http://mitpress.mit.edu/sicp/
https://github.com/sarabander/sicp-pdfhttps://github.com/sarabander/sicp-pdf
http://xkcd.com/297/http://xkcd.com/297/
•• Un Lisp, para programación funcionalUn Lisp, para programación funcional
•• Simbiótico con una plataforma probadaSimbiótico con una plataforma probada
•• Diseñado para programación concurrenteDiseñado para programación concurrente
…… pero no lo encontró,pero no lo encontró, así que lo hizo él mismoasí que lo hizo él mismo
http://clojure.org/http://clojure.org/rationalerationale
;; Esta linea es un comentario;; Esta linea es un comentario
(+ 1 2 3)(+ 1 2 3)
;= 6;= 6
(+ (* 2 3 4) 100)(+ (* 2 3 4) 100)
;= 124;= 124
((defdef colorescolores #{#{:blanco :azul :rojo:blanco :azul :rojo})})
(colores(colores :rojo:rojo))
;= :rojo;= :rojo
(colores(colores :verde:verde))
;= nil;= nil
((defdef numerosnumeros {{:one:one "uno""uno",, :two:two "dos""dos" })})
(numeros(numeros :two:two))
;= "dos";= "dos"
$ clj$ clj
Clojure 1.5.1Clojure 1.5.1
user=> (def editores [:vim :emacs :sublime])user=> (def editores [:vim :emacs :sublime])
#'user/editores#'user/editores
user=> (reverse editores)user=> (reverse editores)
(:sublime :emacs :vim)(:sublime :emacs :vim)
user=> (assoc editores 0 "notepad")user=> (assoc editores 0 "notepad")
["notepad" :emacs :sublime]["notepad" :emacs :sublime]
user=> editoresuser=> editores
[:vim :emacs :sublime][:vim :emacs :sublime]
public class Person {public class Person {
private String name;private String name;
private Integer age;private Integer age;
public Person() { }public Person() { }
public String getName() { return name; }public String getName() { return name; }
public Integer getAge() { return age; }public Integer getAge() { return age; }
public void setName(String name) {public void setName(String name) {
this.name = name;this.name = name;
}}
public void setAge(Integer age) {public void setAge(Integer age) {
this.age = age;this.age = age;
}}
}}
$ psql myrailsapp_dev$ psql myrailsapp_dev
myrailsapp_dev=# d projects;myrailsapp_dev=# d projects;
Table "public.projects"Table "public.projects"
Column | TypeColumn | Type
------------+-----------------------------------------+-----------------------------
id | integerid | integer
user_id | integeruser_id | integer
enabled | booleanenabled | boolean
created_at | timestamp without time zonecreated_at | timestamp without time zone
updated_at | timestamp without time zoneupdated_at | timestamp without time zone
““Place oriented programming”Place oriented programming”
Programación funcionalProgramación funcional
// Clase StringUtils de Apache Commons Lang v2.6 (2011)// Clase StringUtils de Apache Commons Lang v2.6 (2011)
public classpublic class StringUtils {StringUtils {
public staticpublic static boolean isBlank(String str) {boolean isBlank(String str) {
intint strLenstrLen;;
ifif (str ==(str == nullnull || (strLen = str.length()) == 0) {|| (strLen = str.length()) == 0) {
returnreturn truetrue;;
}}
forfor (int i = 0; i < strLen; i++) {(int i = 0; i < strLen; i++) {
ifif ((Character.isWhitespace(str.charAt(i)) ==((Character.isWhitespace(str.charAt(i)) == falsefalse)){)){
returnreturn falsefalse;;
}}
}}
returnreturn truetrue;;
}}
}}
// Clase StringUtils de Apache Commons Lang v2.6 (2011)// Clase StringUtils de Apache Commons Lang v2.6 (2011)
public classpublic class StringUtils {StringUtils {
public staticpublic static boolean isBlank(String str) {boolean isBlank(String str) {
intint strLenstrLen;;
ifif (str ==(str == nullnull || (strLen = str.length()) == 0) {|| (strLen = str.length()) == 0) {
returnreturn truetrue;;
}}
forfor (int i = 0; i < strLen; i++) {(int i = 0; i < strLen; i++) {
ifif ((Character.isWhitespace(str.charAt(i)) ==((Character.isWhitespace(str.charAt(i)) == falsefalse)){)){
returnreturn falsefalse;;
}}
}}
returnreturn truetrue;;
}}
}}
;; Implementación en Clojure;; Implementación en Clojure
(defn blank?(defn blank? [str][str]
((every?every? #(#(Character/isWhitespaceCharacter/isWhitespace %) str))%) str))
Programación concurrenteProgramación concurrente
•• Una secuencia de 1000 números repartidos en 100Una secuencia de 1000 números repartidos en 100
vectores de 10 números cada unovectores de 10 números cada uno
•• 1010 threadsthreads manipularán estos númerosmanipularán estos números
•• Cada thread selecciona 2 posiciones al azar entre dosCada thread selecciona 2 posiciones al azar entre dos
vectores elegidos al azar e intercambia los valoresvectores elegidos al azar e intercambia los valores
•• Correr 100.000 iteraciones y ver si ocurrenCorrer 100.000 iteraciones y ver si ocurren
inconsistencias (faltan números, deadlocks...)inconsistencias (faltan números, deadlocks...)
http://en.wikipedia.org/wiki/Clojure#Exampleshttp://en.wikipedia.org/wiki/Clojure#Examples
((defndefn runrun [nvecs nitems nthreads niters][nvecs nitems nthreads niters]
((letlet [vec-refs ([vec-refs (vecvec
((mapmap ((compcomp ref vec)ref vec)
((partitionpartition nitems (nitems (rangerange (* nvecs nitems)))))(* nvecs nitems)))))
swap #(swap #(letlet [v1 ([v1 (rand-intrand-int nvecs)nvecs)
v2 (v2 (rand-intrand-int nvecs)nvecs)
i1 (i1 (rand-intrand-int nitems)nitems)
i2 (i2 (rand-intrand-int nitems)]nitems)]
((dosyncdosync
((letlet [temp ([temp (nthnth @(vec-refs v1) i1)]@(vec-refs v1) i1)]
((alteralter (vec-refs v1)(vec-refs v1)
assoc i1 (assoc i1 (nthnth @(vec-refs v2) i2))@(vec-refs v2) i2))
((alteralter (vec-refs v2)(vec-refs v2)
assoc i2 temp))))assoc i2 temp))))
report #(report #(dodo
((prnprn ((mapmap deref vec-refs))deref vec-refs))
((printlnprintln "Distinct:""Distinct:"
((countcount ((distinctdistinct
((applyapply concat (concat (mapmap deref vec-refs))))))]deref vec-refs))))))]
(report)(report)
((dorundorun ((applyapply pcalls (pcalls (repeatrepeat
nthreads #(nthreads #(dotimesdotimes [_ niters] (swap)))))[_ niters] (swap)))))
(report)))(report)))
(run 100 10 10 100000)(run 100 10 10 100000)
$ clj concurrente.clj$ clj concurrente.clj
([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17
18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 3218 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32
33 34 35 ...33 34 35 ...
......
Distinct: 1000Distinct: 1000
([125 332 171 310 471 980 617 816 282 353]...([125 332 171 310 471 980 617 816 282 353]...
...[275 947 628 757 650 41 837 676 231 233])...[275 947 628 757 650 41 837 676 231 233])
Distinct: 1000Distinct: 1000
Todos los cambios en los vectores ocurren en transacciones queTodos los cambios en los vectores ocurren en transacciones que
usan el sistema de memoria transaccional de Clojure, y por esousan el sistema de memoria transaccional de Clojure, y por eso
después de 100.000 iteraciones, no se pierde ningún número.después de 100.000 iteraciones, no se pierde ningún número.
Simbiosis con JavaSimbiosis con Java
y projectosy projectos
;; project.clj (Leinengen.org);; project.clj (Leinengen.org)
((defprojectdefproject lotjm-s3-uploadlotjm-s3-upload "0.0.1""0.0.1"
:description:description "A tool to upload files to S3""A tool to upload files to S3"
:url:url "http://example.com/FIXME""http://example.com/FIXME"
:license:license {:name{:name "Eclipse Public License""Eclipse Public License"
:url:url ""http://eclipse.org/legal/epl-v10.htmlhttp://eclipse.org/legal/epl-v10.html""}}
:dependencies:dependencies [[org.clojure/clojure[[org.clojure/clojure "1.4.0""1.4.0"]]
[org.clojure/java.jdbc[org.clojure/java.jdbc "0.2.3""0.2.3"]]
[mysql/mysql-connector-java[mysql/mysql-connector-java "5.1.6""5.1.6"]]
[net.java.dev.jets3t/jets3t[net.java.dev.jets3t/jets3t "0.9.0""0.9.0"]]]]
:main:main lotjm-s3-upload.core)lotjm-s3-upload.core)
Plan de Dominación Mundial:Plan de Dominación Mundial:
ClojureScriptClojureScript
(demo)(demo)
https://github.com/swannodette/chamberedhttps://github.com/swannodette/chambered
https://github.com/dfuenzalida/todo-cljshttps://github.com/dfuenzalida/todo-cljs
ConclusiónConclusión
•• Python, Groovy y Ruby tienen elementosPython, Groovy y Ruby tienen elementos
funcionales, Java 8 incluirá lambdasfuncionales, Java 8 incluirá lambdas
→→ Clojure tiene eso y más disponible hoyClojure tiene eso y más disponible hoy
• Rápido como Java y soluciona problemas• Rápido como Java y soluciona problemas
complejoscomplejos
•• Cuando es práctico, se puede interoperar conCuando es práctico, se puede interoperar con
todo el ecosistema de Java y sus libreríastodo el ecosistema de Java y sus librerías
• Corre donde corra Java: apps de escritorio,• Corre donde corra Java: apps de escritorio,
Tomcat, AWS, Heroku, Google App Engine, etc.Tomcat, AWS, Heroku, Google App Engine, etc.
•• ClojureScriptClojureScript, Datomic* y Pedestal*, Datomic* y Pedestal*
Como aprender ClojureComo aprender Clojure
$ clj$ clj
Clojure 1.5.1Clojure 1.5.1
user=>user=> ((defndefn palin?palin? [x] (= ([x] (= (applyapply str (str (reversereverse x)) x))x)) x))
#'user/palin?#'user/palin?
user=>user=>((defndefn both-palin? [n]both-palin? [n]
((andand
(palin? ((palin? (strstr n))n))
(palin? ((palin? (Integer/toBinaryStringInteger/toBinaryString n))))n))))
#'user/both-palin?#'user/both-palin?
user=>user=> ((applyapply + (+ (filterfilter both-palin? (both-palin? (rangerange 1 1000000)))1 1000000)))
872187872187
FinFin
CréditosCréditos
Fondo “Concrete Texture” por Ember Studio
http://www.flickr.com/photos/emberstudio/7597659330/
Foto de Paul Graham por Niall Kennedy
http://www.flickr.com/photos/niallkennedy/137275735/
Sasha Grey con el libro de SICP por Ayanami_Rei
http://canv.as/p/1i1pr/reply/89490
Rick Hichey en el SF Clojure Users Group por Howard Lewis Ship
http://www.flickr.com/photos/hlship/3603090614
Rich Hickey “State, you're doing it wrong” por Pedro Teixeira
http://static.intelie.com.br/qconsp2010/presentation.html

Más contenido relacionado

Similar a Introducción a Clojure

Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en C
degarden
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que tú
Agile Spain
 
Anatomía de un ataque a tns listener
Anatomía de un ataque a tns listenerAnatomía de un ataque a tns listener
Anatomía de un ataque a tns listener
yt f
 

Similar a Introducción a Clojure (20)

Jruby On Rails. Ruby on Rails en la JVM
Jruby On Rails. Ruby on Rails en la JVMJruby On Rails. Ruby on Rails en la JVM
Jruby On Rails. Ruby on Rails en la JVM
 
MODELO PASO DE MENSAJES
MODELO PASO DE MENSAJESMODELO PASO DE MENSAJES
MODELO PASO DE MENSAJES
 
The Original Hacker número 11.
The Original Hacker número 11.The Original Hacker número 11.
The Original Hacker número 11.
 
Jerónimo López | Introducción a GraalVM | Codemotion Madrid 2018
Jerónimo López | Introducción a GraalVM | Codemotion Madrid  2018  Jerónimo López | Introducción a GraalVM | Codemotion Madrid  2018
Jerónimo López | Introducción a GraalVM | Codemotion Madrid 2018
 
Workshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a RubyWorkshop Camp México 09 - Introducción a Ruby
Workshop Camp México 09 - Introducción a Ruby
 
Abel Valero - VM + VFS = The Wooden Horse [rooted2018]
Abel Valero - VM + VFS = The Wooden Horse [rooted2018]Abel Valero - VM + VFS = The Wooden Horse [rooted2018]
Abel Valero - VM + VFS = The Wooden Horse [rooted2018]
 
Javascript
JavascriptJavascript
Javascript
 
Quasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en CQuasi - Practicas de Programacion en C
Quasi - Practicas de Programacion en C
 
Porqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que túPorqué Cervantes programaba mejor que tú
Porqué Cervantes programaba mejor que tú
 
Por qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que túPor qué Cervantes programaba mejor que tú
Por qué Cervantes programaba mejor que tú
 
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONAPARADIGMAS FP  Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
PARADIGMAS FP Y OOP USANDO TÉCNICAS AVANZADAS DE PROGRAMACIÓN ASÍNCRONA
 
Seguridad so pii_2011
Seguridad so pii_2011Seguridad so pii_2011
Seguridad so pii_2011
 
Curso android studio
Curso android studioCurso android studio
Curso android studio
 
Curso android studio
Curso android studioCurso android studio
Curso android studio
 
Manual de android
Manual de androidManual de android
Manual de android
 
De 0 A Python En 40 Minutos
De 0 A Python En 40 MinutosDe 0 A Python En 40 Minutos
De 0 A Python En 40 Minutos
 
HTML Tour - Programación de Videojuegos HTML5
HTML Tour - Programación de Videojuegos HTML5HTML Tour - Programación de Videojuegos HTML5
HTML Tour - Programación de Videojuegos HTML5
 
Node Js & 3D Printer
Node Js & 3D PrinterNode Js & 3D Printer
Node Js & 3D Printer
 
Anatomía de un ataque a tns listener
Anatomía de un ataque a tns listenerAnatomía de un ataque a tns listener
Anatomía de un ataque a tns listener
 
Metaprogramación (en Ruby): programas que escriben programas
Metaprogramación (en Ruby): programas que escriben programasMetaprogramación (en Ruby): programas que escriben programas
Metaprogramación (en Ruby): programas que escriben programas
 

Último

Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
AnnimoUno1
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
FagnerLisboa3
 

Último (11)

Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
Resistencia extrema al cobre por un consorcio bacteriano conformado por Sulfo...
 
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdfRefrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
Refrigerador_Inverter_Samsung_Curso_y_Manual_de_Servicio_Español.pdf
 
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptxEL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
EL CICLO PRÁCTICO DE UN MOTOR DE CUATRO TIEMPOS.pptx
 
Avances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvanaAvances tecnológicos del siglo XXI 10-07 eyvana
Avances tecnológicos del siglo XXI 10-07 eyvana
 
Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21Innovaciones tecnologicas en el siglo 21
Innovaciones tecnologicas en el siglo 21
 
Modulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdfModulo-Mini Cargador.................pdf
Modulo-Mini Cargador.................pdf
 
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptxPROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
PROYECTO FINAL. Tutorial para publicar en SlideShare.pptx
 
Avances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estosAvances tecnológicos del siglo XXI y ejemplos de estos
Avances tecnológicos del siglo XXI y ejemplos de estos
 
How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.How to use Redis with MuleSoft. A quick start presentation.
How to use Redis with MuleSoft. A quick start presentation.
 
EPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial UninoveEPA-pdf resultado da prova presencial Uninove
EPA-pdf resultado da prova presencial Uninove
 
pruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNITpruebas unitarias unitarias en java con JUNIT
pruebas unitarias unitarias en java con JUNIT
 

Introducción a Clojure

  • 1. Introducción a CloIntroducción a Clojjureure Una intro a Clojure y por qué usar programación funcionalUna intro a Clojure y por qué usar programación funcional Denis Fuenzalida – Junio de 2013Denis Fuenzalida – Junio de 2013 denis.fuenzalida@gmail.comdenis.fuenzalida@gmail.com
  • 2.
  • 3. ““Martin Fowler hace la siguienteMartin Fowler hace la siguiente observación:observación: El verdadero legado de Java seráEl verdadero legado de Java será la plataforma, no el lenguaje...la plataforma, no el lenguaje...
  • 4. ...ahora mismo, hay más de 200...ahora mismo, hay más de 200 lenguajes que corren sobre la JVMlenguajes que corren sobre la JVM yy es inevitable que uno de elloses inevitable que uno de ellos llegue a superar a Javallegue a superar a Java como lacomo la mejor forma de programar la JVM.”mejor forma de programar la JVM.” –– Neal Ford en “Neal Ford en “Java.nextJava.next”” http://nealford.com/pub.htmlhttp://nealford.com/pub.html
  • 5. # db/seeds.rb# db/seeds.rb User.find_each(&User.find_each(&:destroy:destroy)) User.create(User.create(emailemail:: 'user@example.org''user@example.org',, passwordpassword:: 'l33t''l33t')) User.find_each(&:User.find_each(&:reset_authentication_token!reset_authentication_token!)) // ApprovalService.groovy// ApprovalService.groovy approvers.findAll{ it.userId == approval.userId }.each{approvers.findAll{ it.userId == approval.userId }.each{ it.removable =it.removable = falsefalse }}
  • 6. varvar objobj = {= { "flammable""flammable":: "inflammable""inflammable",, "duh""duh":: "no duh""no duh" };}; $$.each( obj,.each( obj, functionfunction(( keykey,, valuevalue ) {) { alert( key +alert( key + ": "": " + value );+ value ); });});
  • 7. ““Vale la pena aprender Lisp porVale la pena aprender Lisp por lala profunda experiencia deprofunda experiencia de iluminacióniluminación que obtendrásque obtendrás cuando finalmente lo entiendas...cuando finalmente lo entiendas...
  • 8. ...esa experiencia te hará un mejor...esa experiencia te hará un mejor por programador el resto de tuspor programador el resto de tus días, incluso si en realidad nuncadías, incluso si en realidad nunca lo utilizas mucho.”lo utilizas mucho.” –– Eric S. Raymond en “Eric S. Raymond en “Como convertirse en HackerComo convertirse en Hacker”” http://www.catb.org/esr/faqs/hacker-howto.htmlhttp://www.catb.org/esr/faqs/hacker-howto.html
  • 12. •• Un Lisp, para programación funcionalUn Lisp, para programación funcional •• Simbiótico con una plataforma probadaSimbiótico con una plataforma probada •• Diseñado para programación concurrenteDiseñado para programación concurrente …… pero no lo encontró,pero no lo encontró, así que lo hizo él mismoasí que lo hizo él mismo http://clojure.org/http://clojure.org/rationalerationale
  • 13. ;; Esta linea es un comentario;; Esta linea es un comentario (+ 1 2 3)(+ 1 2 3) ;= 6;= 6 (+ (* 2 3 4) 100)(+ (* 2 3 4) 100) ;= 124;= 124 ((defdef colorescolores #{#{:blanco :azul :rojo:blanco :azul :rojo})}) (colores(colores :rojo:rojo)) ;= :rojo;= :rojo (colores(colores :verde:verde)) ;= nil;= nil ((defdef numerosnumeros {{:one:one "uno""uno",, :two:two "dos""dos" })}) (numeros(numeros :two:two)) ;= "dos";= "dos"
  • 14. $ clj$ clj Clojure 1.5.1Clojure 1.5.1 user=> (def editores [:vim :emacs :sublime])user=> (def editores [:vim :emacs :sublime]) #'user/editores#'user/editores user=> (reverse editores)user=> (reverse editores) (:sublime :emacs :vim)(:sublime :emacs :vim) user=> (assoc editores 0 "notepad")user=> (assoc editores 0 "notepad") ["notepad" :emacs :sublime]["notepad" :emacs :sublime] user=> editoresuser=> editores [:vim :emacs :sublime][:vim :emacs :sublime]
  • 15.
  • 16. public class Person {public class Person { private String name;private String name; private Integer age;private Integer age; public Person() { }public Person() { } public String getName() { return name; }public String getName() { return name; } public Integer getAge() { return age; }public Integer getAge() { return age; } public void setName(String name) {public void setName(String name) { this.name = name;this.name = name; }} public void setAge(Integer age) {public void setAge(Integer age) { this.age = age;this.age = age; }} }}
  • 17. $ psql myrailsapp_dev$ psql myrailsapp_dev myrailsapp_dev=# d projects;myrailsapp_dev=# d projects; Table "public.projects"Table "public.projects" Column | TypeColumn | Type ------------+-----------------------------------------+----------------------------- id | integerid | integer user_id | integeruser_id | integer enabled | booleanenabled | boolean created_at | timestamp without time zonecreated_at | timestamp without time zone updated_at | timestamp without time zoneupdated_at | timestamp without time zone
  • 18. ““Place oriented programming”Place oriented programming”
  • 20. // Clase StringUtils de Apache Commons Lang v2.6 (2011)// Clase StringUtils de Apache Commons Lang v2.6 (2011) public classpublic class StringUtils {StringUtils { public staticpublic static boolean isBlank(String str) {boolean isBlank(String str) { intint strLenstrLen;; ifif (str ==(str == nullnull || (strLen = str.length()) == 0) {|| (strLen = str.length()) == 0) { returnreturn truetrue;; }} forfor (int i = 0; i < strLen; i++) {(int i = 0; i < strLen; i++) { ifif ((Character.isWhitespace(str.charAt(i)) ==((Character.isWhitespace(str.charAt(i)) == falsefalse)){)){ returnreturn falsefalse;; }} }} returnreturn truetrue;; }} }}
  • 21. // Clase StringUtils de Apache Commons Lang v2.6 (2011)// Clase StringUtils de Apache Commons Lang v2.6 (2011) public classpublic class StringUtils {StringUtils { public staticpublic static boolean isBlank(String str) {boolean isBlank(String str) { intint strLenstrLen;; ifif (str ==(str == nullnull || (strLen = str.length()) == 0) {|| (strLen = str.length()) == 0) { returnreturn truetrue;; }} forfor (int i = 0; i < strLen; i++) {(int i = 0; i < strLen; i++) { ifif ((Character.isWhitespace(str.charAt(i)) ==((Character.isWhitespace(str.charAt(i)) == falsefalse)){)){ returnreturn falsefalse;; }} }} returnreturn truetrue;; }} }} ;; Implementación en Clojure;; Implementación en Clojure (defn blank?(defn blank? [str][str] ((every?every? #(#(Character/isWhitespaceCharacter/isWhitespace %) str))%) str))
  • 23. •• Una secuencia de 1000 números repartidos en 100Una secuencia de 1000 números repartidos en 100 vectores de 10 números cada unovectores de 10 números cada uno •• 1010 threadsthreads manipularán estos númerosmanipularán estos números •• Cada thread selecciona 2 posiciones al azar entre dosCada thread selecciona 2 posiciones al azar entre dos vectores elegidos al azar e intercambia los valoresvectores elegidos al azar e intercambia los valores •• Correr 100.000 iteraciones y ver si ocurrenCorrer 100.000 iteraciones y ver si ocurren inconsistencias (faltan números, deadlocks...)inconsistencias (faltan números, deadlocks...) http://en.wikipedia.org/wiki/Clojure#Exampleshttp://en.wikipedia.org/wiki/Clojure#Examples
  • 24. ((defndefn runrun [nvecs nitems nthreads niters][nvecs nitems nthreads niters] ((letlet [vec-refs ([vec-refs (vecvec ((mapmap ((compcomp ref vec)ref vec) ((partitionpartition nitems (nitems (rangerange (* nvecs nitems)))))(* nvecs nitems))))) swap #(swap #(letlet [v1 ([v1 (rand-intrand-int nvecs)nvecs) v2 (v2 (rand-intrand-int nvecs)nvecs) i1 (i1 (rand-intrand-int nitems)nitems) i2 (i2 (rand-intrand-int nitems)]nitems)] ((dosyncdosync ((letlet [temp ([temp (nthnth @(vec-refs v1) i1)]@(vec-refs v1) i1)] ((alteralter (vec-refs v1)(vec-refs v1) assoc i1 (assoc i1 (nthnth @(vec-refs v2) i2))@(vec-refs v2) i2)) ((alteralter (vec-refs v2)(vec-refs v2) assoc i2 temp))))assoc i2 temp)))) report #(report #(dodo ((prnprn ((mapmap deref vec-refs))deref vec-refs)) ((printlnprintln "Distinct:""Distinct:" ((countcount ((distinctdistinct ((applyapply concat (concat (mapmap deref vec-refs))))))]deref vec-refs))))))] (report)(report) ((dorundorun ((applyapply pcalls (pcalls (repeatrepeat nthreads #(nthreads #(dotimesdotimes [_ niters] (swap)))))[_ niters] (swap))))) (report)))(report))) (run 100 10 10 100000)(run 100 10 10 100000)
  • 25. $ clj concurrente.clj$ clj concurrente.clj ([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17([0 1 2 3 4 5 6 7 8 9] [10 11 12 13 14 15 16 17 18 19] [20 21 22 23 24 25 26 27 28 29] [30 31 3218 19] [20 21 22 23 24 25 26 27 28 29] [30 31 32 33 34 35 ...33 34 35 ... ...... Distinct: 1000Distinct: 1000 ([125 332 171 310 471 980 617 816 282 353]...([125 332 171 310 471 980 617 816 282 353]... ...[275 947 628 757 650 41 837 676 231 233])...[275 947 628 757 650 41 837 676 231 233]) Distinct: 1000Distinct: 1000 Todos los cambios en los vectores ocurren en transacciones queTodos los cambios en los vectores ocurren en transacciones que usan el sistema de memoria transaccional de Clojure, y por esousan el sistema de memoria transaccional de Clojure, y por eso después de 100.000 iteraciones, no se pierde ningún número.después de 100.000 iteraciones, no se pierde ningún número.
  • 26. Simbiosis con JavaSimbiosis con Java y projectosy projectos
  • 27. ;; project.clj (Leinengen.org);; project.clj (Leinengen.org) ((defprojectdefproject lotjm-s3-uploadlotjm-s3-upload "0.0.1""0.0.1" :description:description "A tool to upload files to S3""A tool to upload files to S3" :url:url "http://example.com/FIXME""http://example.com/FIXME" :license:license {:name{:name "Eclipse Public License""Eclipse Public License" :url:url ""http://eclipse.org/legal/epl-v10.htmlhttp://eclipse.org/legal/epl-v10.html""}} :dependencies:dependencies [[org.clojure/clojure[[org.clojure/clojure "1.4.0""1.4.0"]] [org.clojure/java.jdbc[org.clojure/java.jdbc "0.2.3""0.2.3"]] [mysql/mysql-connector-java[mysql/mysql-connector-java "5.1.6""5.1.6"]] [net.java.dev.jets3t/jets3t[net.java.dev.jets3t/jets3t "0.9.0""0.9.0"]]]] :main:main lotjm-s3-upload.core)lotjm-s3-upload.core)
  • 28. Plan de Dominación Mundial:Plan de Dominación Mundial: ClojureScriptClojureScript (demo)(demo)
  • 32. •• Python, Groovy y Ruby tienen elementosPython, Groovy y Ruby tienen elementos funcionales, Java 8 incluirá lambdasfuncionales, Java 8 incluirá lambdas →→ Clojure tiene eso y más disponible hoyClojure tiene eso y más disponible hoy • Rápido como Java y soluciona problemas• Rápido como Java y soluciona problemas complejoscomplejos
  • 33. •• Cuando es práctico, se puede interoperar conCuando es práctico, se puede interoperar con todo el ecosistema de Java y sus libreríastodo el ecosistema de Java y sus librerías • Corre donde corra Java: apps de escritorio,• Corre donde corra Java: apps de escritorio, Tomcat, AWS, Heroku, Google App Engine, etc.Tomcat, AWS, Heroku, Google App Engine, etc. •• ClojureScriptClojureScript, Datomic* y Pedestal*, Datomic* y Pedestal*
  • 34. Como aprender ClojureComo aprender Clojure
  • 35.
  • 36.
  • 37.
  • 38.
  • 39. $ clj$ clj Clojure 1.5.1Clojure 1.5.1 user=>user=> ((defndefn palin?palin? [x] (= ([x] (= (applyapply str (str (reversereverse x)) x))x)) x)) #'user/palin?#'user/palin? user=>user=>((defndefn both-palin? [n]both-palin? [n] ((andand (palin? ((palin? (strstr n))n)) (palin? ((palin? (Integer/toBinaryStringInteger/toBinaryString n))))n)))) #'user/both-palin?#'user/both-palin? user=>user=> ((applyapply + (+ (filterfilter both-palin? (both-palin? (rangerange 1 1000000)))1 1000000))) 872187872187
  • 40.
  • 41.
  • 42.
  • 44. CréditosCréditos Fondo “Concrete Texture” por Ember Studio http://www.flickr.com/photos/emberstudio/7597659330/ Foto de Paul Graham por Niall Kennedy http://www.flickr.com/photos/niallkennedy/137275735/ Sasha Grey con el libro de SICP por Ayanami_Rei http://canv.as/p/1i1pr/reply/89490 Rick Hichey en el SF Clojure Users Group por Howard Lewis Ship http://www.flickr.com/photos/hlship/3603090614 Rich Hickey “State, you're doing it wrong” por Pedro Teixeira http://static.intelie.com.br/qconsp2010/presentation.html