universalmente universalmente aceptada aceptada • • Funciones como elementos de primer nivel del lenguaje: Funciones como elementos de primer nivel del lenguaje: “ “First Class Functions First Class Functions” ” → → es posible almacenar es posible almacenar referencias referencias a funciones a funciones pasar funciones como → pasar funciones como → parámetros parámetros → → crear funciones que retornan crear funciones que retornan funciones funciones Definición Definición
más énfasis en el → más énfasis en el → qué qué y no en el y no en el cómo cómo → → menos código que comprender menos código que comprender → → a veces, código más genérico y re-utilizable a veces, código más genérico y re-utilizable • • En En Clojure Clojure se prefieren funciones puras* se prefieren funciones puras* son más fáciles de entender → son más fáciles de entender → → → más fáciles de testear más fáciles de testear → → se pueden guardar se pueden guardar en caché en caché y paralelizar y paralelizar fácilmente fácilmente Beneficios Beneficios
toSearch){ ){ when (toSearch) { when (toSearch) { for for (i = 0; i < str.length(); i++){ (i = 0; i < str.length(); i++){ ch ch = str.charAt(i); = str.charAt(i); when toSearch(ch) i; // Busca 'ch', retorna i when toSearch(ch) i; // Busca 'ch', retorna i } } } } } }
para iterar indexOfAny indexOfAny( (str str, , toSearch toSearch){ ){ when (toSearch) { when (toSearch) { for for ([i, ch] in indexed(str)){ ([i, ch] in indexed(str)){ when toSearch(ch) i; when toSearch(ch) i; } } } } } }
toSearch){ ){ when (toSearch) { when (toSearch) { for for ([i, ch] in indexed(str)){ ([i, ch] in indexed(str)){ when toSearch(ch) i; when toSearch(ch) i; } } } } } } ;; Version Clojure ;; Version Clojure ( (defn defn index-filter index-filter [coll pred] [coll pred] ( (when when pred pred ( (for for [[idx elt] (indexed coll) [[idx elt] (indexed coll) :when :when (pred elt)] idx))) (pred elt)] idx)))
de retorno 2 0 Variables 3 0 Ramificaciones 4 0 Operaciones booleanas 1 0 Llamadas a funciones 6 3 Total 18 4 Complejidad de cada versión Complejidad de cada versión
index-filter retorna una lista* de TODOS los calces! ;; Indices de 'cara' en una lista de tiradas de moneda: ;; Indices de 'cara' en una lista de tiradas de moneda: (index-filter [ (index-filter [:c :s :c :c :s :s :c :s :c :s :c :c :s :c :c :s :s :c :s :c :s :c] #{ ] #{:c :c}) }) ;; => (0 2 3 6 8 10) ;; => (0 2 3 6 8 10) ;; Cuál es el primer número de Fibonacci mayor que 1000? ;; Cuál es el primer número de Fibonacci mayor que 1000? ( (defn defn fibo fibo [] [] ( (map map first ( first (iterate iterate ( (fn fn [[a b]] [b (+ a b)]) [0 1]))) [[a b]] [b (+ a b)]) [0 1]))) ( (first first (index-filter (fibo) #(> % 1000))) (index-filter (fibo) #(> % 1000))) ;; => 17 ;; => 17 ( (nth nth (fibo) 17) (fibo) 17) ;; => 1597 ;; => 1597
Imperativa Funcional Busca dentro de Strings Busca en Secuencias Busca sólo caracteres Busca usando cualquier función predicado Retorna el primer calce Retorna una lista lazy de todos los calces
• • Número palíndromo: si es el mismo, escrito al revés Número palíndromo: si es el mismo, escrito al revés (1.234.321) (1.234.321) • • El mayor palíndromo que es producto de 2 números El mayor palíndromo que es producto de 2 números de 2 cifras es de 2 cifras es 9009 9009 = 91 x 99 = 91 x 99 • • Encontrar el mayor producto de números de 3 cifras Encontrar el mayor producto de números de 3 cifras que sea palíndromo que sea palíndromo
str str(x) == (x) == str str(x)[::-1] (x)[::-1] palins palins = [x*y = [x*y for for x x in in range(100, 1000) \ range(100, 1000) \ for for y y in in range(x, 1000) range(x, 1000) if if palin(x*y)] palin(x*y)] print(max(palins)) print(max(palins))
más énfasis en el → más énfasis en el → qué qué y no en el y no en el cómo cómo → → menos código que comprender menos código que comprender → → a veces, código más genérico y re-utilizable a veces, código más genérico y re-utilizable • • En En Clojure Clojure se prefieren funciones puras* se prefieren funciones puras* son más fáciles de entender → son más fáciles de entender → → → más fáciles de testear (no se necesita más fáciles de testear (no se necesita mocking mocking) ) → → se pueden guardar se pueden guardar en caché en caché (memoize f) (memoize f) → → se pueden paralelizar se pueden paralelizar fácilmente fácilmente (pmap f) (pmap f) Beneficios de PF Beneficios de PF
http://www.flickr.com/photos/cblue98/7254347346/sizes/l/ Fondo - “Gravel Background” por Ember Studio http://www.flickr.com/photos/48013511@N07/7685947954/ Ejemplos en Clojure basados en “Functional Thinking” por Neal Ford http://shop.oreilly.com/product/0636920030393.do