Introducción a Clojure
-
Upload
denis-fuenzalida -
Category
Technology
-
view
330 -
download
0
description
Transcript of Introducción a Clojure
Introducción a CloIntroducción a Clo jj ureureUna 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 [email protected]@gmail.com
““ Martin Fowler hace la siguiente Martin Fowler hace la siguiente obser vación: obser vació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 JVM lenguajes que corren sobre la JVM
y y es inevitable que uno de ellos es inevitable que uno de ellos l legue a superar a Javallegue a superar a Java como la como 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: : '[email protected]''[email protected]', , 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}}
var var 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 por Vale la pena aprender Lisp por la la profunda experiencia de profunda experiencia de i luminacióniluminación que obtendrás que 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 tus por programador el resto de tus
días, incluso si en realidad nunca días, incluso si en realidad nunca lo uti l izas mucho.” lo uti l izas 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$ cljClojure 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 | Type Column | Type ------------+-----------------------------------------+----------------------------- id | integer id | integer user_id | integer user_id | integer enabled | boolean enabled | boolean created_at | timestamp without time zone created_at | timestamp without time zone updated_at | timestamp without time zone updated_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) { int int 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) { int int 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/isWhitespace Character/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 uno vectores de 10 números cada uno
• • 10 10 threadsthreads manipularán estos números manipulará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 valores vectores elegidos al azar e intercambia los valores
• • Correr 100.000 iteraciones y ver si ocurren Correr 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 ( (map map deref vec-refs))deref vec-refs)) ((printlnprintln "Distinct:""Distinct:" ((countcount ( (distinctdistinct ((applyapply concat ( concat (mapmap deref vec-refs))))))] deref vec-refs))))))] (report)(report) ((dorundorun ( (apply apply 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 32 18 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 que Todos los cambios en los vectores ocurren en transacciones que usan el sistema de memoria transaccional de Clojure, y por eso usan 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 Javay projectosy projectos
;; project.clj (Leinengen.org);; project.clj (Leinengen.org)
((defprojectdefproject lotjm-s3-upload lotjm-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:
ClojureS criptClojureS cript(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 elementos Python, Groovy y Ruby tienen elementos funcionales, Java 8 incluirá lambdas funcionales, 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 complejos complejos
• • Cuando es práctico, se puede interoperar conCuando es práctico, se puede interoperar con todo el ecosistema de Java y sus librerías todo 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$ cljClojure 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éditosFondo “Concrete Texture” por Ember Studiohttp://www.flickr.com/photos/emberstudio/7597659330/
Foto de Paul Graham por Niall Kennedyhttp://www.flickr.com/photos/niallkennedy/137275735/
Sasha Grey con el libro de SICP por Ayanami_Reihttp://canv.as/p/1i1pr/reply/89490
Rick Hichey en el SF Clojure Users Group por Howard Lewis Shiphttp://www.flickr.com/photos/hlship/3603090614
Rich Hickey “State, you're doing it wrong” por Pedro Teixeirahttp://static.intelie.com.br/qconsp2010/presentation.html