Sunday, November 30, 2008

La Consigna del Blog

Pensé que había un post sobre esto, pero me acabo de dar cuenta que no.
Este blog es donde yo (Nicolás, alias "Niv" en la internéssss) escribo lo que se me canta, pero básicamente hay una consigna detrás de él. La consigna es que trato de ser impersonal: no hablo sobre mi vida, hablo cosas genéricas. No pretende esto ser un diario. De esta manera, alguien que no me conoce lo puede leer.
Sobre que escribo? pues bien, las etiquetas que se ven en la barra de navegación derecha deberían darte una idea.

Saturday, November 29, 2008

El fino arte de contar historias (parte II)

Cada tanto me agarra el ataque de leer novelas, y empiezo a leer un montón, después dejo y vuelvo a leer papers o a simplemente escuchar la radio, chatear, o jugar a la play 2. Esto es anecdótico y va en contra de la consigna del blog, (la cual, recordemos, es no decir nada que tenga que ver con mi vida); pero en uno de mis últimos ataques lectoriles leí Ana Karenina, de León Tolstoi (O según wikipedia, "Lev Nikolayevich Tolstoy"). La leí hace tanto, que para que se den una idea cuando en febrero escribí el post El fino arte de contar historias (parte I), ya pensaba escribir este post, que recien ahora que llega diciembre 2008 me pongo a escribir. Ana Karenina es un libro genial, de lo mejorcito que leí en mi vida, escencialmente narra la historia de dos personajes, uno es Ana Karenina, el otro es Constantino Levin, no me quiero meter en detalles pero hay mil personajes secundarios y pasan montones de cosas, esencialmente es una historia de personas, que pertenecen a la aristocracia (como el mismo Tolstoi), pero personas al fin. Y el libro habla de todo: de la guerra, del amor, de la juventud, del matrimonio, de la economía, de la sociedad, y nunca deja de ser interesante, nunca se vuelve denso. Los dialogos son buenos, las descripciones son hermosas, las cosas que se cuentan son interesante... sin embargo, cuando lo leo, no me impresionan tanto las palabras que utilizó. Y esta es un poco la idea que quiero plantear con este post.

Una vez, una persona, de esas tantas que conozco por los foros, planteó la idea de que para él, un libro no puede atraer solamente por la historia, tiene que tener peso la LITERATURA, lo que está escrito. Es decir, la belleza de las palabras, en su punto más abstracto. Lo mismo podría argumentarse del cine, lo importante es el aspecto visual, no la historia que se narra. Y de leer un poco a Cortazar y Borges, alguna vez tuve la sensación de que ambos seguían esta línea de pensamiento, de que lo importante no reside en lo que se cuenta sino en como se lo cuenta. Ojo, no me quiero hacer el culto, no los leí mucho. No me gustan.

Esta línea de pensamiento es correcta, pero aquí llegamos a un punto en que nos debemos preguntar: si el arte del cine está en las imagenes, y el arte de la literatura está en las palabras, y el arte de la novela gráfica está en la gráfica; ¿que es entonces eso que está en todos lados y es lo que se mantiene entre cada medio? Si lo único que importa está en las palabras, que queda del arte del suspenso, del arte de inventar personajes, del arte de imaginar situaciones? Y la literatura de Tolstoi está en crear personajes de puta madre, no en pensar palabras locas (igual ojo que escribía de puta madre el flaco), y el cine de woody allen reside también en eso, en pensar situaciones, personajes, historias (lo que no quita que en su cine, lo visual no exista también). Y creo que el arte de contar historias existe en ambos en común, y creo la literatura de tolstoi y el cine de allen tienen más en común en cuanto a lo que son que Tolstoi con Borges o Allen con esos estudiantes de cine que hacen cortos que no se entienden.

Thursday, March 20, 2008

Experimentando con mónadas y el flujo de control

Alo! Amigos, hoy voy a hablarles de algo que es muy posible que les resulte complicado, ya que es sobre programacion (GASP!) y encima de haskell (super GASP!) y sobre monadas (WTF!?). Anyway lo voy a postear, porque mi blog se nutre de los googleadores que llegan por casualidad.
Para entender este articulo hace falta entender lo que son las monadas y como funcionan, esto lo voy a explicar algun dia en algun otro blogpost pero por ahora no voy a explicar nada.

Este experimento haskelliano es nada más y nada menos que mi intento de reproducir la macro (loop) de Common Lisp, un mini lenguaje de loopeo que posee lisp.
Ejemplo de codigo:


(loop for x from 1
for y in '(a b c d e f g h i j k)
until x < 5 do collect (list x y) if (!= x 3))

Esto lo que hace es itera x desde 1 hasta el infinito, itera y por todos los elementos de la lista '(a b c d e f g) y luego va acumulando mediante el "collect" pares de x y, siempre y cuando x sea distinto de 3.
Resultado de la evaluacion: ((1 a) (2 b) (4 d))
Este minilenguaje que es loop tiene varios de los patrones basicos de loopeo y los abstrae. Quiza este ejemplo no lo muestre pero podemos agregar otros collects, llamar a funciones de todo tipo, etc, es decir las palabras claves de loop son totalmente combinables.

Un defecto de loop sumamente criticado es que es una macro extremadamente compleja, tanto es asi que muchos lisperos detestan la macro. A mi me encanta, porque me permite expresar cualquier loopeo de la manera mas declarativa posible, simplemente escribiendo lo que estoy pensando.

En haskell, pues, lo más parecido a esto es las listas por comprension, pero no se puede hacer con ellas todo lo que se puede hacer con loop con tanta facilidad (aunque se puede verdaderamente hacer un montón). Asi que pues, quise implementar algo lo más parecido a loop (un subset na' mas) pero en haskell.

Si bien haskell tiene macros (via la extension Template Haskell), muchas de las cosas que en lisp se suelen implementar como macros en haskell se pueden implementar como monadas, cosas como computacion no determinstica, manejo de excepciones, et cetera.; dado que las monadas son un concepto mas puro y mas manejable en esto me parece que haskell es superior, aunque las macros de lisp son mucho mas completas (se puede hacer realmente cualquier cosa con ellas).

Pues bien, como se implementa esto? despues de pensar mil cosas distintas y experimentar muchas posibilidades, llegue a la conclusion de que una manera (ante todo sencilla de implementar :D) es utilizando una suerte de mezcla entre la monada State y la monada Maybe.

El tipo de dato abstracto de la monada State suele ser \ s -> (a,s), mientras que aqui es algo como \ s -> (Maybe a,s), a esta monada la llame LoopState. La idea de devolver Maybe es que si la funcion monadica llega a devolver Nothing, en ese momento se termina el loop. Además, y esto es por ahora para el for, además del estado guardado que dependera de que hagamos en el loop (si hacemos collecting o buscamos un valor único), se pasa el número de iteracion dentro del estado. Entonces puedo implementar una funcion monádica for :: [a] -> LoopState s a, que segun el número de iteracion, toma el primer elemento de la funcion, el segundo, etc y lo va pasando; pero si la lista no es suficientemente larga devolvera Nothing y eso terminará el loop (esto imita el comportamiento de la macro de lisp, que loopea hasta que se termina el for mas corto).

Para completar la idea, esta monada representa simplemente una secuencia de instrucciones que puede terminar por la mitad, nada más y nada menos. Para el loopeo utilizo una funcion externa que reciba esta monada y la haga loopear siempre y cuando devuelva (Just _), pero aumentando el numero de iteracion a medida que aumentamos el loopeo. Esa es toda la idea.

Algunos ejemplos de como se usa:

myloop = loopCollecting $ do x <- for [1..]
y <- for ['a'..'z']
untilLoop (x > 3)
collect (x,y)
when (y == 'a') $ collect (99, 'x')

myloop2 = loopFind $ do x <- for [1..]
y <- for ['a'..'z']
untilLoop (x > 3)
when (y == 'j') $ found x

myloop3 = loopFind $ do x <- for [1..]
y <- for ['a'..'z']
when (y == 'j') $ found x

Y los resultados de la evaluacion
*Test> myloop
[(1,'a'),(99,'x'),(2,'b'),(3,'c')]
*Test> myloop2
Nothing
*Test> myloop
[(1,'a'),(99,'x'),(2,'b'),(3,'c')]
*Test> myloop3
Just 10
*Test>


Obviamente esto asi como está le faltan un par de cosas. En primer lugar, tendria que hacer una version LoopStateT de la monada para que pueda interactuar con la monada IO para que realmente sea interesante la cosa, claro que todavia no termino de entender como funcionan las versiones "Transformer" de las monadas. Y por otro lado sigue sin tener toda la flexibilidad de (loop), que por ejemplo te permite acumular en varias listas, y hacer IO, todo al mismo tiempo. Aqui tan solo puedo acumular en un solo lugar, y sinceramente no se me ocurre por ahora como darle mas flexibilidad sin usar la monada IO en modo unsafe.

Notas: si ya existe algo parecido en haskell, no lo conozco... admito que no soy un experto ni nunca desarolle software demasiado complejo con haskell, entre otras cosas porque no trabajo profesionalmente con el lenguaje.
Bueh, el codigo:

---

module Test where
import Control.Monad

newtype LoopState s a = LoopState { runloopstate :: (Int,s) -> (Maybe a, (Int,s)) }

instance Monad (LoopState s) where
return a = LoopState $ \ s -> (Just a, s)
m >>= k = LoopState $ \ s -> let
(a, s') = runloopstate m s
in case a of Just x -> runloopstate (k x) s'
Nothing -> (Nothing, s')


numeroCorridas = LoopState $ \ (n,s) -> (Just n, (n,s))

terminate = LoopState $ \ s -> (Nothing, s)

maybeAt [] _ = Nothing
maybeAt (x:_) 0 = Just x
maybeAt (_:xs) n = maybeAt xs (n - 1)

for lista = do n <- numeroCorridas
case lista `maybeAt` (n-1) of
Just x -> return x
Nothing -> terminate

untilLoop True = terminate
untilLoop False = return ()

collect val = LoopState $ \ (n,l) -> (Just (), (n,val:l))
found val = LoopState $ \ (n, _) -> (Nothing, (n,Just val))

loopCollecting monad = reverse $ loopCollecting' monad 1 []

loopCollecting' monad n acc = let (val, (_, acc')) = runloopstate monad (n, acc)
in case val of Just _ -> loopCollecting' monad (n+1) acc'
Nothing -> acc'
loopFind monad = loopFind' monad 1
loopFind' monad n = let (val, (_, finding)) = runloopstate monad (n, Nothing)
in case val of Just _ -> loopFind' monad (n+1)
Nothing -> finding

Thursday, February 28, 2008

El fino arte de contar historias (parte I)

En un ataque cinefilo, me vi *todas* las películas de woody allen (que hayan salido, exceptuando en ese sentido Cassandra's Dream). En total, son unas 38 pelis, de las cuales ya me habia visto 16, asi que el rush filmico consistio en "solo" 22 peliculas, más unas cuantas que me vi de vuelta.
Es interesante ver todas las peliculas de un mismo director. Admito que me fascinan las pelis de woody, ya por el drama, ya por la comedia. IMHO, sus mejores peliculas son un interesante mixture de comedia y drama, aunque algunas me ganan mediante mares de risas. No todas sus peliculas son excelente, pero la mayoria son decentes y me gustaron, con una única excepción, Celebrity, que me pareció insipida cuando la vi por primera vez, y a pesar de verla de vuelta, sigue sin gustarme, aunque tampoco es mala.
Algunas impresiones sueltas:
* Love And Death, aka Vida y muerte de boris grushenko es fantástica, una de las pelis más graciosas que puede haber. Su peli anterior, la futurista Sleeper, es casi tan graciosa.
* Play It Again, Sam, si bien no la dirige, basada en una obra de teatro suya y el actúa, junto con Diane Keaton. Una historia de un loser tipicamente allanesco, mezclado con parodia de casablanca.
* Temí que Interiors fuera terriblemente pretenciosa, y resulto ser emocionalmente impactante. Está verdaderamente filmada en el estilo de Bergman (otro director con el que me estoy lentamente obsesionando, aunque dado que tiene casi 70 pelis no pienso verlas todas).
* La Rosa Purpura del Cairo tal vez sea la peli de allen que más me gusto de todas. Esto no es poco.
* Another Woman tiene muchísimos parecidos con Frutillas Silvestres (aka wild strawberries) de Ingmar Bergman, al punto de que los protagonistas sufren crisis similares, en ambos films se aplica la tecnica de poner un personaje en su edad adulta en el medio de un flashback de cuando era joven, los personajes en un momento DICEN LA MISMA FRASE CON EL MISMO SENTIDO EN LA MISMA SITUACION, y el tono con el que los protagonista narran en primera persona es EL MISMO. A pesar de esto ambas peliculas tocan topicos distintos y las recomiendo ambas.
* Deconstructing Harry tambien evoca a Frutillas Silvestres, pero de una manera muy distinta a Another Woman. En Husbands and Wives directamente un personaje menciona ver la pelicula en la tele.
* Don't Drink the Water es un especial para TV, pero es hilarante. Veanlo.
* El musical Everyone Says I Love You es genial, no acepto discusiones.
* La actuación de Samantha Morton en Sweet And Lowdown, donde hace de muda, me da gana de ver todas las películas donde haya actuado. 'nuff said.

Los dejo con un pedacito de Bananas, que si bien no es una de sus mejores, tiene partes muy graciosas. El ultimo minuto de este excerpt es genial.

asd

Friday, January 25, 2008

Bailarina

Genial bailarina de música electrónica. No sexy, sino simplemente divertido y creativo. El video esta acelerado, pero no quita mérito. Joy oh joy!


Y de yapa!: