Translate

domingo, 9 de noviembre de 2014

Introducción a la programación en C

Quiero compartir este libro sobre C, aunque este en Ingles, es muy fácil de leer y les va a ser muy útil.

Dejo link:
http://www.geekboots.com/c/intro

jueves, 6 de noviembre de 2014

Immutable.js

Como sabrán Javascript es un lenguaje muy influenciado por lenguajes funcionales. Clausuras, Curryng, etc.

Con Immutable.js tienes la característica de los inmutables en javascript!!

El framework permite generar listas y luego no poder modificarlas. Dando le una mayor seriedad al lenguaje.

Veamos un ejemplo:

var list1 = Immutable.List.of(1, 2);
var list2 = list1.push(3, 4, 5);
var list3 = list2.unshift(0);
var list4 = list1.concat(list2, list3);
assert(list1.size === 2);
assert(list2.size === 5);
assert(list3.size === 6);
assert(list4.size === 13);
assert(list4.get(0) === 1);
Dejo link! https://github.com/facebook/immutable-js




miércoles, 5 de noviembre de 2014

¿Cuáles serán los 7 empleos del futuro?

Go, un caso raro?

Me asombra muchísimo el éxito que esta teniendo go, hablan de el nuevo java, etc... Porque me asombra? Básicamente porque es un lenguaje no orientado a objeto. Mi primer pensamiento fue que es un lenguaje que viene a reemplazar a c, pero no fue solo el caso. Esta ganando espacio en diferentes ámbitos.

Lo que podemos deducir es que tal vez existe un lugar para olvidarnos de los objetos y  programar de forma procedural, pero siguiendo este lineamiento de pensamiento, decanta la pregunta: No le habremos dado mucha importancia a la programación orientada a objetos?

Sin duda el mercado esta cambiando, mirando con más atención el paradigma funcional. La programación orientada a objetos esta en su atardecer? Que opinan?

viernes, 31 de octubre de 2014

Scala Best Practices




Quiero compartir un link con un manual o escrito, la verdad no se como llamarlo, de buenas practicas
en scala. Esta muy bueno, tienen consejos simples como no usar la palabra return, hasta más complejos.

Dejo link:
https://github.com/alexandru/scala-best-practices

miércoles, 29 de octubre de 2014

Recursos sobre Clojure


Gracias a un grupo de google plus sobre Clojure, he conseguido y quiero compartir un montón de recursos sobre clojure que acá les dejo.

Dejo link: https://clojure.zeef.com/vlad.bokov

martes, 28 de octubre de 2014

Que son las aplicaciones Reactivas?

Una pequeña infografia que describe muy bien los principios de las aplicaciones reactivas:

Ojo! se que no se ve, solo tienen que hacer click en la imagen. 

sábado, 25 de octubre de 2014

La evolución de windows

Esta es una imagen que describe de forma muy clara la evolución del sistema operativo de microsoft:




Primeros pasos en Qt: Emitir una señal

En los post anteriores estuvimos viendo el mecanismo de signals y slots que permitían manejar una señal emitida por un componente.

Además estuvimos haciendo una ventana de dialogo que permitía, para buscar un texto determinado. Este dialogo no puede hacer la acción porque no conoce el texto donde se debe realizar la búsqueda.

Resumiendo:

  • Tenemos 2 ventanas una con todo el texto donde se debe realizar la búsqueda y la otra que permite ingresar el texto a buscar. 
  • Por lo tanto la ventana main o padre debe realizar la búsqueda.
  • La ventana de dialog debe enviar una señal con el texto ingresado.
  • Esta señal va a ser procesada por la ventana main que realizará la búsqueda.
Vamos a conectar las ventana como dijimos:

connect(ventanaBusqueda, SIGNAL(aceptar(QString)), this, SLOT(busqueda(QString));

En la ventana padre debemos conectar nuestra ventana de búsqueda con el proceso de búsqueda. Noten el detalle de que indicamos el tipo de parámetro de las funciones.

Si probamos esto no va a suceder nada porque nuestra pantalla de dialog no emite la señal, veamos como podemos hacer esto:

emit aceptar(text)

En el botón del dialog debemos emitir la señal. Con emit emitimos una señal, en este caso emitimos la señal aceptar y le pasamos un testo como parámetro.

Dejo link:
http://qt-project.org/doc/qt-4.8/signalsandslots.html


jueves, 23 de octubre de 2014

Java VS Properties


Les quiero dejar un link de un tema muy interesante, las properties en Java. Yo recuerdo que Delphi (Object Pascal) hace 15 años más o menos ya tenia properties. Las properties te permitían acceder a propiedades privadas sin romper la encapsulación y sin escribir métodos para acceder.

Es una lucha entre el tedio de escribir métodos que el 90% de la veces son iguales, y a nadie le importa contra el encapsulamiento.


Dejo el link: http://betterunspoken.com/java-vs-properties-why-we-should-be-sad-about-getters-setters/?utm_source=google+plus&utm_medium=link&utm_campaign=java-getter-setter-post

miércoles, 22 de octubre de 2014

Compiladores e interpretes: teoría y práctica



Quiero compartir este excelente libro sobre compiladores e interpretes totalmente gratuito y en español.

Dejo link:
http://www.infotutoriales.info/2014/10/compiladores-e-interpretes-teoria-y.html

Node.js vs Play

Un muy buen resumen sobre las diferencias de estos Frameworks y muchas cosas que no sabia, por ejemplo que coursera esta hecho en play.


sábado, 18 de octubre de 2014

Estructuras de datos recursivas en Haskell y Scala, segunda parte


Vamos a ejemplificar lo que vimos en el post anteríor con un ejemplo de árbol binario de búsqueda. Si no estás familiarizado con los árboles binarios de búsqueda de otros lenguajes como C, aquí tienes una explicación de lo que son: un elemento apunta a otros dos elementos, uno esta a la izquierda y otro a la derecha. El elemento a la izquierda es más pequeño y el segundo es más grande. Cada uno de estos dos elementos puede apuntar a otros dos elementos (o a uno o a ninguno). En efecto, cada elemento tienen sus propios sub-árboles. Lo bueno de los árboles binarios de búsqueda es que sabemos que todos los elementos que están en el sub-árbol de la izquierda de, 5, por ejemplo, son menores que 5. Lo elementos que están en el sub-árbol de la derecha son mayores. Así que si estamos buscando el elemento 8 en nuestro árbol, empezamos comparándolo con 5, como vemos que es menor que 5, nos vamos al sub-árbol de la derecha. Ahora estaríamos en 7, como es menor que 8 continuaríamos hacia la derecha. De esta forma encontraríamos el elemento en tres pasos. Si estuviéramos usando una lista (o un árbol no balanceado), nos hubiera costado unos 7 pasos encontrar el 8.

Los conjuntos y diccionario de Data.Set y Data.Map de Haskell están implementandos utilizando árboles, solo que en lugar de árboles binarios de búsqueda, utilizan árboles binarios de búsqueda balanceados, de forma que estén siempre balanceados. Ahora implementaremos simplemente árboles binarios de búsqueda normales.

Vamos a decir que: un árbol es o bien un árbol vacío o bien un elemento que contiene un elemento y otros dos árboles. Tiene pinta de que va a encajar perfectamente con los tipos de datos algebraicos.

data Tree a = EmptyTree | Node a (Tree a) (Tree a) deriving (Show, Read, Eq)

Esto en Scala podríamos implementarlo con Clases Case, o con herencia también funcionaría pero voy a utilizar  Clases Case:

abstract class Tree
case class EmptyTree extends Tree
case class Node (nro: Int, left: Tree, rigth: Tree) extends Tree

En lugar de construir manualmente un árbol, vamos a crear una función que tome un elemento y un árbol e inserte dicho elemento en su posición adecuada dentro del árbol. Hacemos esto comparando el elemento que queremos insertar con la raíz del árbol y si es menor, vamos a la izquierda y si no a la derecha. Hacemos lo mismo para coda nodo siguiente hasta que alcanzamos un árbol vacío. Cuando lo hagamos simplemente insertamos el elemento en lugar del árbol vacío.

En lenguajes como C, realizamos esta tarea modificando los punteros y valores del árbol. En Haskell, no podemos modificar nuestro árboles, así que tenemos que crear un nuevo sub-árbol cada vez que decidamos si vamos a la derecha o a la izquierda y al final la función de inserción devolver un árbol completamente nuevo, ya que Haskell no tiene el concepto de puntero. Así pues la declaración de tipo de nuestra función será algo como a -> Tree a - > Tree a. Toma un elemento y un árbol y devuelve un nuevo árbol que posee en su interior dicho elemento.

Aquí tienes dos funciones. Una de ellas es una función auxiliar para crear un árbol unitario (que solo contiene un elemento) y la otra es una función que inserta elementos en un árbol.

singleton :: a -> Tree a
singleton x = Node x EmptyTree EmptyTree

treeInsert :: (Ord a) => a -> Tree a -> Tree a
treeInsert x EmptyTree = singleton x
treeInsert x (Node a left right)
    | x == a = Node x left right
    | x < a  = Node a (treeInsert x left) right
    | x > a  = Node a left (treeInsert x right)

La función singleton es forma rápida de crear un árbol que contenga un elemento y dos sub-árboles vacíos. En la función de inserción, tenemos como primer patrón el caso base. Si hemos alcanzado un sub-árbol vacío, esto significa que estamos donde queríamos y en lugar de un árbol vacío, queremos un árbol unitario que contenga el elemento a insertar. Si no estamos insertando el elemento en un árbol vacío tenemos que comprobar varias cosas. Primero, si el elemento que vamos a insertar es el mismo que la raíz del sub-árbol, simplemente devolvemos el árbol como estaba. Si es menor, devolvemos un árbol que tenga la misma raíz, el mismo sub-árbol derecho pero en lugar de su sub-árbol izquierdo, ponemos el árbol que va a contener dicho elemento. Lo mismo ocurre (pero en sentido contrario) para los valores que son mayores que el elemento raíz.

En Scala podemos hacer un método que con pattern matching saber que clase es:

  def treeInsert(nro:Int, tree: Tree) : Tree = tree match {
    case EmptyTree => Node (nro, EmptyTree(), EmptyTree())
    case Node (nroTree, left, right) => if (nroTree == nro)  Node (nro, left, right)
                                                           else if (nro < nroTree)  Node (nroTree, treeInsert(nro, left), right)
                                                           else Node (nroTree, left, treeInsert(nro, right))  
  }

A continuación vamos a crear una función que compruebe si un elemento pertence a un árbol. Primero vamos a definir el caso base. Si estamos buscando un elemento en un árbol vacío, obviamente el elemento no está ahí. Vale, fíjate que esto es básicamente lo mismo que el caso base de la búsqueda en listas: si estamos buscando un elemento en una lista vacía, obviamente el elemento no está ahí. De todos modos, si no estamos buscando el elemento en un árbol vacío, entonces tenemos que hacer varias comprobaciones. Si el elemento que estamos buscando es el elemento raíz ¡Genial! ¿Y si no lo es? Bueno, tenemos la ventaja de que sabemos que todos los elementos menores que la raíz están en el sub-árbol izquierdo. Así que si el elemento que estamos buscando es menor que la raíz, comprobamos si el elemento está en el sub-árbol izquierdo. Si es mayor, comprobamos el sub-árbol derecho.

treeElem :: (Ord a) => a -> Tree a -> Bool
treeElem x EmptyTree = False
treeElem x (Node a left right)
    | x == a = True
    | x < a  = treeElem x left
    | x > a  = treeElem x right

En Scala:

  def treeElem(nro:Int, tree: Tree) : Boolean = tree match {
    case EmptyTree => false
    case Node (nroTree, left, right) => if (nroTree == nro)  true
                                                           else if (nro < nroTree)  treeElem(nro, left)
                                                           else treeElem(nro, right)
  }

¡Vamos a divertirnos con nuestro árboles! En lugar de construir manualmente un árbol (aunque podríamos), usaremos un pliegue para construir un árbol a partir de una lista. Recuerda, casi cualquier cosa que recorra una lista elemento a elemento y devuelve alguna especie de valor puede ser implementado con un pliegue. Empezaremos con un árbol vacío y luego recorreremos la lista desde la derecha e iremos insertando elementos a nuestro árbol acumulador.

ghci> let nums = [8,6,4,1,7,3,5]
ghci> let numsTree = foldr treeInsert EmptyTree nums
ghci> numsTree
Node 5 (Node 3 (Node 1 EmptyTree EmptyTree) (Node 4 EmptyTree EmptyTree)) (Node 7 (Node 6 EmptyTree EmptyTree) (Node 8 EmptyTree EmptyTree))

En este foldr, treeInsert es la función de pliegue (toma un árbol y un elemento de la lista y produce un nuevo árbol) y EmptyTree es el valor inicial. Por supuesto, nums es la lista que estamos plegando.
No es muy legible el árbol que se muestra por la consola, pero si lo intentamos, podemos descifrar su estructura. Vemos que el nodo raíz es 5 y luego tiene dos sub-árboles, uno que tiene como elemento raíz a 3, y otro a 7.

ghci> 8 `treeElem` numsTree
True
ghci> 100 `treeElem` numsTree
False
ghci> 1 `treeElem` numsTree
True
ghci> 10 `treeElem` numsTree
False

Vamos que comprobar la pertenencia de un elemento a un árbol funciona perfectamente. Genial.
Como puede ver los tipos de datos algebraicos en Haskell son un concepto muy interesante a la vez potentes. Podemos utilizarlos desde para representar valores booleanos hasta enumeraciónes de los días de la semana, e incluso árboles binarios de búsquedas.

Estructuras de datos recursivas en Haskell y Scala

Una estructura de datos en Haskell o una clase en java o scala puede contener atributos esos atributos tienen un tipo determinado si ese tipo es igual a la clase contenedora tenemos una estructura recursiva.

Piensa en la lista en Haskell [5]. Es lo mismo que 5:[]. A la izquierda del : hay un valore, y a la derecha hay una lista. En este caso, una lista vacía. ¿Qué pasaría con la lista [4,5]? Bueno, es lo mismo que 4:(5:[]). Si miramos el primer :, vemos que también tiene un elemento a su izquierda y una lista a su derecha (5:[]). Lo mismo sucede para la lista 3:(4:(5:6:[])), que también podría escribirse como 3:4:5:6:[] (ya que : es asociativo por la derecha) o [3,4,5,6].

Podemos decir que una lista es o bien una lista vacia o bien un elemento unido con un : a otra lista (que puede ser una lista vacía o no).

Podemos usar los tipo de datos algebraicos para implementar nuestra propia lista:
data List a = Empty | Cons a (List a) deriving (Show, Read, Eq, Ord)

Se lee de la misma forma que se leía nuestra definición de lista en un párrafo anterior. Es o bien una lista vacía o bien una combinación de un elemento y otra lista. Si estás confundido con esto, quizás te sea más fácil entenderlo con la sintaxis de registro:

data List a = Empty | Cons { listHead :: a, listTail :: List a} deriving (Show, Read, Eq, Ord)

Puede que también estes confundido con el constructor Cons. Cons es otra forma de decir :. En realidad, en las listas, : es un constructor que toma un valor y otra lista y devuleve una lista. En otras palabras, tiene dos campos. Uno es del tipo a y otro es del tipo [a].

ghci> Empty
Empty
ghci> 5 `Cons` Empty
Cons 5 Empty
ghci> 4 `Cons` (5 `Cons` Empty)
Cons 4 (Cons 5 Empty)
ghci> 3 `Cons` (4 `Cons` (5 `Cons` Empty))
Cons 3 (Cons 4 (Cons 5 Empty))

Si hubiésemos llamado a nuestro constructor de forma infija podrías ver mejor como es simplemente :. Empty es como [] y 4 `Cons` (5 `Cons` Empty) es como 4:(5:[]).

Podemos definir funciones que automáticamente sean infijas si las nombramos únicamente con caracteres especiales. Podemos hacer lo mismo con los constructores, ya que son simplemente funciones que devuelve un tipo de dato concreto. Mira esto:
infixr 5 :-:
data List a = Empty | a :-: (List a) deriving (Show, Read, Eq, Ord)

Antes de nada, vemos que hay una nueva construcción sintáctica, una declaración infija. Cuando definimos funciones como operadores, podemos usar esta cosntrucción para darles un determinado comportamiento (aunque no estamos obligados a hacerlo). De esta forma definimos el orden de precedencia de un operador y si asociativo por la izquierda o por la derecha. Por ejemplo, * es infixl 7 * y + es infixl 6 +. Esto siginifica que ambos son asociativos por la izquierda de forma que (4 * 3 * 2) es (4 * 3) * 2) pero * tiene un orden de precedencia mayor que +, por lo que 5 * 4 + 3 es equivalente a (5 * 4) + 3.

De qualquier modo, al final acabamos escribiendo a :-: (List a) en lugar de `` Cons a (List a)``. Ahora podemos escribir las listas así:

ghci> 3 :-: 4 :-: 5 :-: Empty
(:-:) 3 ((:-:) 4 ((:-:) 5 Empty))
ghci> let a = 3 :-: 4 :-: 5 :-: Empty
ghci> 100 :-: a
(:-:) 100 ((:-:) 3 ((:-:) 4 ((:-:) 5 Empty)))

Haskell seguirá mostrando el constructor como una función prefija cuando derivemos Show, por este motivo aparecen los paréntesis alrededor del constructor (recuerda que 4 + 3 es igual que (+) 4 3).

Vamos a crear una función que una dos de nuestras listas. Así es como está definida la función ++ para listas normales:

infixr 5  ++
(++) :: [a] -> [a] -> [a]
[]     ++ ys = ys
(x:xs) ++ ys = x : (xs ++ ys)

Así que copiamos esta definición y la aplicamos a nuestras listas:

infixr 5  .++
(.++) :: List a -> List a -> List a
Empty .++ ys = ys
(x :-: xs) .++ ys = x :-: (xs .++ ys)

Y así es como funciona:

ghci> let a = 3 :-: 4 :-: 5 :-: Empty
ghci> let b = 6 :-: 7 :-: Empty
ghci> a .++ b
(:-:) 3 ((:-:) 4 ((:-:) 5 ((:-:) 6 ((:-:) 7 Empty))))


Fíjate que hemos utilizado un ajuste de patrón (x :-: xs). Esto función ya que el ajuste de patrones en realidad funciona ajustando constructores. Podemos ajustar un patrón :-: porque es un constructor de nuestro tipo de la misma forma que : es un constructor de las listas estándar. Lo mismo sucede para [].

Ya que el ajuste de patrones funciona (solo) con constructores de datos, podemos ajustar patrones como los constructores prefijos normales, constructores infijos o cosas como 8 o 'a', que al fin y al cabo son constructores de tipos numéricos y caracteres.

Tutorial de Ceylon



Si quieres aprender Ceylon rápidamente este tutorial es para vos :  http://lmauzaize.developpez.com/tutoriels/ceylon/typage/