introducción a clojure

Post on 14-Jun-2015

340 Views

Category:

Technology

0 Downloads

Preview:

Click to see full reader

DESCRIPTION

Una introducción a Clojure y por qué usar programación funcional. Mi experiencia al conocer Clojure luego de haber sido desarrollador de aplicaciones con Java, Grails y Rails.

TRANSCRIPT

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 2013denis.fuenzalida@gmail.comdenis.fuenzalida@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: : '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}}

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

top related