Programación Funcional

¿Por qué debería empezar a usarla?

Miguel Angel Gordian

@ilcapitanozoek

¿Funcional?

  • Basado en funciones
  • No efectos secundarios
  • Valores inmutables
  • Favorece la recursividad
  • Depuración más fácil
  • Funciones de primera clase y de orden superior
  • Facilita la concurrencia de programas
  • Lenguaje declarativo

A cada valor de entrada le corresponde uno de salida

Favorece el uso de concurrencia

quicksort :: (Ord a) => [a] -> [a]  
quicksort [] = []  
quicksort (x:xs) =   
    let smallerSorted = quicksort [a | a <- xs, a <= x]  
        biggerSorted = quicksort [a | a <- xs, a > x]  
    in  smallerSorted ++ [x] ++ biggerSorted  
void quickSort(int arr[], int left, int right) {
      int i = left, j = right;
      int tmp;
      int pivot = arr[(left + right) / 2];
 
      /* partition */
      while (i <= j) {
            while (arr[i] < pivot)
                  i++;
            while (arr[j] > pivot)
                  j--;
            if (i <= j) {
                  tmp = arr[i];
                  arr[i] = arr[j];
                  arr[j] = tmp;
                  i++;
                  j--;
            }
      };
 
      /* recursion */
      if (left < j)
            quickSort(arr, left, j);
      if (i < right)
            quickSort(arr, i, right);
}

Nuevos conceptos, patrones y estruturas surgen

  • Functors
  • Aplicatives
  • Monoids
  • Monads
  • Curry
  • Partial Applicative

React Stateless Components

function HelloMessage(props) {
  return <div>Hello {props.name}</div>;
}

ReactDOM.render(<HelloMessage 
    name="Sebastian" />, mountNode);

Rxjs

var Rx = require('@reactivex/rxjs');

Rx.Observable.of('hello world')
  .subscribe(function(x) { 
    console.log(x); 
  });

Scala promueve el uso de FP

def listLength1(list: List[_]): Int = {
  if (list == Nil) 0
  else 1 + listLength1(list.tail)
}
 
var list1 = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
var list2 = List(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
1 to 15 foreach( x => list2 = list2 ++ list2 )
 
println( listLength1( list1 ) )
println( listLength1( list2 ) )

Pattern matching

  def matchTest(x: Int): String = x match {
    case 1 => "one"
    case 2 => "two"
    case _ => "many"
  }

  def f(x: Any): String = x match {
    case i:Int => "integer: " + i
    case _:Double => "a double"
    case s:String => "I want to say " + s
  }
  
  println(matchTest(3))

Aplicación parcial de funciones

from functools import partial

def power(base, exponent):
    return base ** exponent

square = partial(power, exponent=2)
cube = partial(power, exponent=3)

def test_partials():
    assert square(2) == 4
    assert cube(2) == 8
  • Objectos con estado inmutables.
  • No uses variables externas (uso de closures).
  • Implementa los conceptos en tu lenguaje o prueba nuevos lenguajes.
  • Para efectos secundarios usa Monads.
  • Usa FP cuando tengas requerimientos de concurrencia.

¿Preguntas?

Programación Funcional

By Miguel Angel Gordian

Programación Funcional

  • 864