Introducción a Clojure
Upcoming SlideShare
Loading in...5
×

Like this? Share it with your network

Share

Introducción a Clojure

  • 494 views
Uploaded on

Una introducción a Clojure y por qué usar programación funcional. ...

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.

More in: Technology
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
494
On Slideshare
493
From Embeds
1
Number of Embeds
1

Actions

Shares
Downloads
1
Comments
0
Likes
0

Embeds 1

http://www.linkedin.com 1

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 1. Introducción a CloIntroducción a ClojjureureUna intro a Clojure y por qué usar programación funcionalUna intro a Clojure y por qué usar programación funcionalDenis Fuenzalida – Junio de 2013Denis Fuenzalida – Junio de 2013denis.fuenzalida@gmail.comdenis.fuenzalida@gmail.com
  • 2. ““Martin Fowler hace la siguienteMartin Fowler hace la siguienteobservació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...
  • 3. ...ahora mismo, hay más de 200...ahora mismo, hay más de 200lenguajes que corren sobre la JVMlenguajes que corren sobre la JVMyy es inevitable que uno de elloses inevitable que uno de ellosllegue a superar a Javallegue a superar a Java como lacomo lamejor 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
  • 4. # db/seeds.rb# db/seeds.rbUser.find_each(&User.find_each(&:destroy:destroy))User.create(User.create(emailemail:: user@example.orguser@example.org,, passwordpassword:: l33tl33t))User.find_each(&:User.find_each(&:reset_authentication_token!reset_authentication_token!))// ApprovalService.groovy// ApprovalService.groovyapprovers.findAll{ it.userId == approval.userId }.each{approvers.findAll{ it.userId == approval.userId }.each{it.removable =it.removable = falsefalse}}
  • 5. 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 );});});
  • 6. ““Vale la pena aprender Lisp porVale la pena aprender Lisp porlala profunda experiencia deprofunda experiencia deiluminacióniluminación que obtendrásque obtendráscuando finalmente lo entiendas...cuando finalmente lo entiendas...
  • 7. ...esa experiencia te hará un mejor...esa experiencia te hará un mejorpor programador el resto de tuspor programador el resto de tusdías, incluso si en realidad nuncadías, incluso si en realidad nuncalo 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
  • 8. http://paulgraham.es/ensayos/la-venganza-de-los-nerds.htmlhttp://paulgraham.es/ensayos/la-venganza-de-los-nerds.html
  • 9. http://mitpress.mit.edu/sicp/http://mitpress.mit.edu/sicp/https://github.com/sarabander/sicp-pdfhttps://github.com/sarabander/sicp-pdf
  • 10. http://xkcd.com/297/http://xkcd.com/297/
  • 11. •• 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 mismohttp://clojure.org/http://clojure.org/rationalerationale
  • 12. ;; 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"
  • 13. $ clj$ cljClojure 1.5.1Clojure 1.5.1user=> (def editores [:vim :emacs :sublime])user=> (def editores [:vim :emacs :sublime])#user/editores#user/editoresuser=> (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]
  • 14. 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;}}}}
  • 15. $ psql myrailsapp_dev$ psql myrailsapp_devmyrailsapp_dev=# d projects;myrailsapp_dev=# d projects;Table "public.projects"Table "public.projects"Column | TypeColumn | Type------------+-----------------------------------------+-----------------------------id | integerid | integeruser_id | integeruser_id | integerenabled | booleanenabled | booleancreated_at | timestamp without time zonecreated_at | timestamp without time zoneupdated_at | timestamp without time zoneupdated_at | timestamp without time zone
  • 16. ““Place oriented programming”Place oriented programming”
  • 17. Programación funcionalProgramación funcional
  • 18. // 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;;}}}}
  • 19. // 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))
  • 20. Programación concurrenteProgramación concurrente
  • 21. •• Una secuencia de 1000 números repartidos en 100Una secuencia de 1000 números repartidos en 100vectores 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 dosvectores 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 ocurreninconsistencias (faltan números, deadlocks...)inconsistencias (faltan números, deadlocks...)http://en.wikipedia.org/wiki/Clojure#Exampleshttp://en.wikipedia.org/wiki/Clojure#Examples
  • 22. ((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 (repeatrepeatnthreads #(nthreads #(dotimesdotimes [_ niters] (swap)))))[_ niters] (swap)))))(report)))(report)))(run 100 10 10 100000)(run 100 10 10 100000)
  • 23. $ 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 1718 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 3233 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: 1000Todos los cambios en los vectores ocurren en transacciones queTodos los cambios en los vectores ocurren en transacciones queusan el sistema de memoria transaccional de Clojure, y por esousan el sistema de memoria transaccional de Clojure, y por esodespué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.
  • 24. Simbiosis con JavaSimbiosis con Javay projectosy projectos
  • 25. ;; 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)
  • 26. Plan de Dominación Mundial:Plan de Dominación Mundial:ClojureScriptClojureScript(demo)(demo)
  • 27. https://github.com/swannodette/chamberedhttps://github.com/swannodette/chambered
  • 28. https://github.com/dfuenzalida/todo-cljshttps://github.com/dfuenzalida/todo-cljs
  • 29. ConclusiónConclusión
  • 30. •• Python, Groovy y Ruby tienen elementosPython, Groovy y Ruby tienen elementosfuncionales, 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 problemascomplejoscomplejos
  • 31. •• Cuando es práctico, se puede interoperar conCuando es práctico, se puede interoperar contodo 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*
  • 32. Como aprender ClojureComo aprender Clojure
  • 33. $ clj$ cljClojure 1.5.1Clojure 1.5.1user=>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
  • 34. FinFin
  • 35. 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/89490Rick Hichey en el SF Clojure Users Group por Howard Lewis Shiphttp://www.flickr.com/photos/hlship/3603090614Rich Hickey “State, youre doing it wrong” por Pedro Teixeirahttp://static.intelie.com.br/qconsp2010/presentation.html