lunes, 30 de marzo de 2009

JavaScript: El Lennguaje de Programación Más Malentendido del Mundo

(Aquí les dejo traducido, el primer texto que leí de Douglas Crockford, y con el que me introduje en el interesantisimo mundo de javascript)

Javascript tambien conocido como: Mocha, LiveScript, JScript, ECMAScript es uno de los lenguajes de programación más populares del mundo. Virtualmente todo computador personal en el mundo tiene, al menos, ún interprete de JavaScript instalado en él, y en uso activo. La popularidad de JavaScript se debe enteramente a su rol como lenguaje de scripting de la WWW.
A pesar de su popularidad, solo algunos saben que JavaScript es un muy buen lenguaje de programación dinámico, orientado a objetos, de proposito general. Cómo puede ser esto un secreto? Porqué este lenguaje es tan malentendido?

El Nombre

El prefijo Java sugiere que JavaScript está, de alguna manera, relacionado a Java, que es un sub conjunto o una version menos poderosa de Java. Resulta que el nombre fué intencionalmente seleccionado para crear confusión, y de la confusión viene el malentendimiento. JavaScript no es Java interpretado. Java es Java interpretado. JavaScript es un lenguaje diferente.

JavaScript tiene una similitud sintáctica con Java, tanto como Java la tiene con C. Pero no es un sub conjunto de Java, tanto como Java no es un sub conjunto de C. Es mejor que Java en la aplicación para la que Java (oak) fue creado.

JavaScript no fué desarrollado en Sun Microsystems, el hogar de Java. JavaScript fué desarrollado en Netscape. Fue originalmente llamado LiveScript. Pero el nombre no era lo suficientemente confuso.

el sufijo Script sugiere que no es un lenguaje de programación real, que un lenguaje de scripting es más que un lenguaje de programación. Pero en realidad es una cuestión de especialización. Comparado con C Javascript tiende al performance para poder expresivo y dinaminsmio.

Lisp vestido de C
La sintaxis parecida a C, incluyendo las llaves y la manca sentencia for, lo hacen parecer un oridinario lenguaje de programación procedural. Esto está malinterpretado, porque JavaScript tiene más en común con lenguajes funcionales, como Lisp o Scheme, que con C o Java. Tiene arreglos en vez de listas y objetos en lugar de listas de propiedades. Las funciones son de primera clase (first class). Tiene cerraduras (closures). Tiene lambdas sin tener que balancear todos esos parentecis.

Encasillamiento (Typecasting)
JavaScript fué diseñado para correr en Netscape Navigator. Su éxito allí lo llevó a convertirse en un equipamiento estandar de virtualmente todos los navegadores web. Esto lo llevó al encasillamiento. JavaScript es el George Reeves de los lenguajes de programación. JavaScript se ha adaptado bien a una gran cantidad de aplicaciones no relacionadas con la web.

Objetivo Cambiante
La primer versión de JavaScript fué muy debil. Carecía de manejo de excepciones, inner functions, y herencia. En su forma actual, es ahora un completo lenguaje de programación orientado a objetos. Pero muchas de las opiniones sobre el lenguaje estan basadas en sus comienzos inmaduros.

El comite ECMA, que tiene el control sobre el lenguaje, esta desarrollando extensiones que, aunque bien intencionadas, van a agrabar uno de los problemas más grandes del lenguaje: Ya existen actualmente demasiadas versiones. Esto crea confusión.

Errores de Diseño
Ningún lenguaje de programación es perfecto. JavaScript tiene su porción de errores de diseño, como la sobrecarga del operador + para significar ambos, la suma y la concatenacion con coerción de tipos y la errorosa (error-prone) sentencia with, que deben ser evitados. La política de palabras reservadas es muy estrícta. La insercion del punto y coma (;) fue un gran error, como lo es la notacion para literales de expresiones regulares. Estas equivocaciones han llevado a errores de programación, que han puesto en cuestionamiento todo el diseño del lenguaje. Afortunadamente, muchos de estos problemas pueden ser mitigados con un buen programa lint. El diseño del lenguaje en general es bastante cuestionado. Sorprendentemente el comite ECMA no parece estar interesado en corregir estos errores. Quizas estan más interesados unos cuantos más.

Malas implementaciones
Algunas de las primeras implementaciones de javascript estaban llenas de errores. Esto se reflejó en el lenguaje de mala manera. Para complementar esto, esas implementaciones estaban embebidas en navegadores web horriblemente llenos de errores.

Malos libros
Practicamente todos los libros acerca de JavaScript son muy malos. Contienen errores, malos ejemplos, y promueven malas prácticas. Las carateristicas importantes del lenguaje son pobremente explicadas o dejadas de lado. He revisado docenas de libros de JavaScript y solamente recomiendo uno: JavaScript: The Definitive Guide (5th Edition) de David Flanagan.

Un estandar por debajo de lo normal
La especificación oficial del lenguaje es publicada por el ECMA. La especificación es de extrema mala calidad. Es dificil de leer y muy dificil de entender. Esto ha sido una contribución al problema de los malos libros porque los autores han sido incapaces de usar la documentacion del estandar para mejorar su propio entendimiento del lenguaje. Los comités del ECMA y él TC39 deberían estar profundamente avergonzados.

Amateurs
La mayoria de las personas escribiendo en JavaScript no son programadores. No poseen el entrenamiento y la disciplina para escribir buenos programas. JavaScript tiene tanto poder de expresión que ellos son capaces de hacer cosas utiles en él de cualquier manera. Esto le ha dado a JavaScript la reputación de ser estrictamente para amateurs, y que no se adapta para programación prefesional. Ese, simplemente no es el caso.

Orientado a Objetos
Es JavaScript orientado a objetos? tiene objetos, que pueden contener datos y métodos que actuen sobre esos datos. Los objetos pueden contener otros objetos. No tiene clases, pero tiene constructores que hacen lo que las clases hacen, incluyendo actuar como contenedor para las variables de clase y los métodos. No tiene herencia orientada a clases, pero tiene herencia prototypal.
Los dos principales caminos para construir sistemas de objetos son herencia (es ún) y agregación (tiene ún). JavaScript hace ambos, pero su naturaleza dinámica le permite ser elegante en la agregación.
Algunos argumentan que JavaScript no es verdaderamente orientado a objetos porque no provee ocultación de la información. Eso es que los objetos no pueden tener variables privadas o métodos privados. Todos los miembros son públicos.
Pero resulta ser que los objetos de JavaScript pueden tener variables privadas y métodos privados (haz click aquí si quieres saber cómo). Por supuesto solo algunos van a entender esto, porque JavaScript es el lenguaje de programación más malentendido del mundo.
Algunos argumentan que JavaScript no es verdaderamente orientado a objetos porque no provee herencia. Pero resulta ser que JavaScript no solamente soporta herencia clásica, sino tambien otro tipo de patrones de reutilización de código

Copyright 2001 Douglas Crockford. All Rights Reserved Wrrrldwide.

Si quieres leer el original en ingles puedes encontrarlo aquí

jueves, 26 de marzo de 2009

currying functions

Currando funciones en javascript ja, esto es un tema avanzado asi que a todos los que se aburren mucho con mis otros post les comento que este les va a encantar.
que son las curried functions. Simple son funciones que si reciben menos paramtros de los que deberian recibir simplemente se compilan a si mismas con los parametros que recibieron y devuelven una función que solo necesita un parametro para terminar su ejecución.
Veamos un ejemplo simple
supongamos que la funcion myFunc suma dos parametros

alert(myFunc(2,2)); // devuelve 4
var adds4 = myFunc(4); // adds4, es ahora una función,
// que le suma 4, a lo que reciba de argumento.
alert(adds4(5)); // devuelve 9.


bien ahora veamos como implementar esta funcion

function add(a, b) {
if (arguments.length < 1) {

return add;

} else if (arguments.length < 2) {

return function(c) {

return a + c
}

} else {

return a + b;
}
}

No es mucho mas complicada, pero tampoco muy generica verdad? bueno
podemos encontrar una solución mucho mas elegante en la siguiente funcion

function curry(func,args,space) {
var n = func.length - args.length; //arguments still to come
var sa = Array.prototype.slice.apply(args); // saved accumulator array
function accumulator(moreArgs,sa,n) {
var saPrev = sa.slice(0); // to reset
var nPrev = n; // to reset
for(var i=0;i<moreArgs.length;i++,n--) {
sa[sa.length] = moreArgs[i];
}
if ((n-moreArgs.length)<=0) {
var res = func.apply(space,sa);
// reset vars, so curried function can be applied to new params.
sa = saPrev;
n = nPrev;
return res;
} else {
return function (){
// arguments are params, so closure bussiness is avoided.
return accumulator(arguments,sa.slice(0),n);
}
}
}
return accumulator([],sa,n);
}


como la usamos?

function add (a,b,c){
if (arguments.length < this.add.length) {
return curry(this.add,arguments,this);
}
return a+b+c;
}



Sin embargo esta funcion no nos provee precompilación que es la verdadera gracia de curriar funciones, solo sirve para verse bonita.
pero si quieren saber mas sobre curried functions en javascript, les recomiendo que visiten este link y vean el algoritmo de Horspool precompilado en javascript

Un poco de Magia para empezar el dia

Hola hoy les acerco un poco de sintaxis util en javascript:

Formas de crear un objeto:
EN JAVASCRIPT TODO ES UN OBJETO y como tal no deberia ser dificil crear uno nuevo, para esto tenemos varias opciones


var obj= new func();


nos permite crear un objeto a partir de una funcion y utilizando su prototipo.
Sin embargo la mejor manera de crear un obj es utilizando la notacion JSON veamos un ejemplo y lo explicamos despues


var obj = {
miembro1:123,
meiembro2:"hola",
metodo1: function(){ return "metodo1";},
metodo2: function(){ return "metodo2";},
"metodo3": function(){ return "metodo3";}
};
alert(obj.metodo3());


si se fijan bien la declaracion del objeto esta encerrada en llaves { }, y luego dentro se encuentran pares nombre valor separados por comas. ahora cada par nombre valor, nombre puede ser un identificador o un string y el valor puede ser cualquier valor (incluida una funcion) hasta otro objeto. Ahora hagamos un objeto complicas y juguemos con arrays

var objc={
nombre:"picanteverde",
posicion:{x:128,y:450},
telefonos:[431,561,443],
hijos:[
{nombre:'Alejandro',apellido:'Hernandez',edad:26},
{nombre:'Emanule',apellido:'Hernandez',edad:21}
],
hablar:function(){
alert(this.nombre);
}

};
objc.hablar();


se eniende como funciona? y lo util de JSON?? reemplaza xml?
lo dejo a su criterio
crear un objeto vacio

var o ={}; // objeto vacio
var a = []; // array vacia


Les gusto?

miércoles, 25 de marzo de 2009

Metaprogramación o DSL con javascript method chaining

Hoy vamos a ver un poco de como crear un mini Lenguaje de dominio especifico (como SQL, o CSS) con javscript de manera facil, rápida, elegante, agil y económica.
Partamos de un problema.
Supongamos que tenemos un select html de paises y solo si elijen eeuu debemos mostrar el select de estados, hariamos lo siguiente (usando la libreria prototype)

Event.observe(window, "load", function() {

Event.observe($("country"), "change", function() {
if ($F("country") == "United States")
$("state-field").show();
else
$("state-field").hide();
});

});

por ahora creanme que Event.observe recibe un objeto del dom, el nombre de un evento, y la funcion a attachear, $ en la lib prototype es un atajo a document.getElementById, $F es un atajo al value de un objeto de formulario, y finalmente se le agregan a los objetos del DOM dos metodos show y hide que simplemente manipulan el valor de display a nivel de css.

lo importante aqui es ver que nuestro limpio codigo puede convertirse en algo mucho mas complicado si varían los requerimientos.

ahora supongamos que agregamos un campo de provincias, que debe aparecer solo cuando elijamos Canada,
y un campo brutus que solo debe aparecer cuando elijamos Michigan u Ohio
el código elegante se empobrece y se torna dificil de leer

Event.observe(window, "load", function() {

Event.observe($("country"), "change", function() {
var country = $F("country");
if (country == "United States") {
$("us-state-field").show();
$("province-field").hide();
} else if (country == "Canada") {
$("province-field").show();
$("us-state-field").hide();
} else {
$("us-state-field").hide();
$("province-field").hide();
}
});

Event.observe($("us-state"), "change", function() {
var state = $F("us-state");
if (state == "Ohio" || state == "Michigan")
$("brutus").show();
else
$("brutus").hide();
});

});



eso sin contar que eredamos un bug que no nos oculta brutus si deseleccionamos estados unidos
Pero eso no es importante, lo importante es ver como la legibilidad del codigo se degrado luego de haber cambiado los requerimientos (cosa que raramente pasa en el mundo real, jajajaja)

Entonces como mejorar esto?
lo mejor es intentar separar el QUE? del COMO?
es decir separar las reglas de lo que tenemos que hacer
de la implementación de como hacerlo.
entonces veamos como creariamos un pequeño lenguaje que nos permita definir esto
para crear un lenguaje vamos a utilizar el lenguaje natural mas parecido al lenguaje del dominio del problema, (pero ahora lo vamos a hacer en ingles).


show us-state when country is “United States”
show province when country is “Canada”
show Brutus when state is “Ohio” or “Michigan”


ahora como convertimos esto en javascript, simple
creando objetos que se encarguen de la implementación teniendo en cuenta el orden de llamadas de metodos


show("us-state-field").when("country").is("United States");
show("province-field").when("country").is("Canada");
show("brutus").when("us-state").is("Ohio,Michigan");


para ver como implementariamos estos metodos los voy a dejar en suspenso hasta un proximo encuentro
ja

fuente
libreria Event.behavior

Vamos a soñar despiertos

yo soy de los que opinan que las majores ideas para los browsers del futuro la dan los que hacen los mejores browser del presente:

Mozilla le pidio a Jesse James Garrett (muchacho que en el 2004 dijo, si convinamos javascript html y xml tenemos AJAX) que diseñe conceptualmente como deberían ser los browser dentro de 10 a 50 años. Si se fijan bien muchos de los conceptos son realizables ya hoy en dia mediante javascript.pero mejor los dejo con el video disfrutenlo en HD
es el ultimo link.
Saluts

http://labs.mozilla.com/projects/concept-series/

http://adaptivepath.com/aurora/

http://www.vimeo.com/1450211

Mi sueño se hizo realidad (Otra vez)

asi es, siempre quise tener un buen editor de código con resaltador de sintaxis multi lenguaje (php,javascript,css,html) y aunque bespin es un proyecto muy en serio que ataca este problema, esta escrito en python y no es nada facil de instalar en tu hosting. Pero ahora tenemos a ecoder que es una aplicacion php que te permite editar tu código en linea. Como un gran amigo mio siempre decía, "Los cambios se implementan en el entorno de producción, ja!". Disfrutenlo, y aunque todavia está en una etapa muy beta, se que vamos a seguir escuchando noticias de él.

Notas: es un tanto dificil de instalar ya que tiene muy poca documentación (los comments del código) pero si son bueno php-hackers se las van a arreglar muy bien.

ecoder

Como programar en Javascript

Javascript es un lenguaje funcional esto implica que sus construcciones de codigo son simplemente funciones. Pero no implica que solamente se pueda programar en formato funcional ya que podemos aplicar muchos paradigmas. Como por Ejemplo el paradigma orientado a objetos.

Como dijimos antes EN JAVA SCRIPT TODO ES UN OBJETO, inclusive las funciones, pero no existen las clases, y esto nos presenta una dificultad como trabajar con el paradigma orientado a objetos.

supongamos que necesitamos crear una persona con dos miembros, un nombre y un apellido, y un metodo hablar que nos alertará el nombre y el apellido.
veamos como hacer esto


function persona (pNombre, pApellido){
this.nombre = pNombre;
this.apellido= pApellido;
}
persona.prototype.hablar = function (){
alert(this.apellido + ", " + this.nombre);
}

var a = new persona("picante","verde");
a.hablar();


funcamentalmente entendamos una cosa,

function persona (pNombre, pApellido){ ... }
es un atajo de
var persona = function (pNombre, pApellido){ ... }


prototype es el prototypo de un objeto (no es la clase, pero podemos decir que es algo parecido (ah y tambien es un objeto)).
Entonces si creamos un nuevo miembro en el prototypo, simplemente asignandolo
vamos a crear un nuevo miembro en todos los objetos que hayan sido creados a travez de ese prototypo.
la cuestion es mucho mas compleja pero por ahora pueden quedarse con esa idea.

martes, 24 de marzo de 2009

Javascript 3d

Si javascript trabaja con 3d hace mucho tiempo pero ultimamente han avanzado más que nunca asi podemos ver como esta aplicación renderiza en 3d inclusive con reflejos en las texturas

fuente

OCR con javascript?

Como verán javascript no deja de sorprenderme jamas y pueden ver aqui como algunos hackers se la ingeniaron para saltar el captcha de megaupload solo utilizando javascript

fuente

Bookmarklets

A travez de aNieto2k vengo a enterarme de que los bookmarklets son pequeños scripts escritos obviamente en javascript y que pueden ser almacenados en tus favoritos (Bookmarks) y ejecutados a tu gusto.
Todo esto gracias a que si en la barra de direcciones de tu navegador escribes

javascript:alert("hola");

puedes ejecutar codigo javascript, que se ejecuta dentro del entorno de la página que tengas abierta en ese momento

si no me crees, ingresa a una página con muchas imagenes y copia el siguiente codigo javascript dentro de tu barra de direcciones y presiona enter

javascript:R=0; x1=.1; y1=.05; x2=.25; y2=.24; x3=1.6; y3=.24; x4=300; y4=200; x5=300; y5=200; DI=document.getElementsByTagName("img"); DIL=DI.length; function A(){for(i=0; i-DIL; i++){DIS=DI[ i ].style; DIS.position='absolute'; DIS.left=(Math.sin(R*x1+i*x2+x3)*x4+x5)+"px"; DIS.top=(Math.cos(R*y1+i*y2+y3)*y4+y5)+"px"}R++}setInterval('A()',5); void(0);


Saludos

Bookmarklets para desarrolladores web en aNieto2k

Bespin, editando codigo en la nube

Magnifico, los muchachos de mozilla se encargaron de crear un genial editor de texto multilenguaje con resaltador de sintaxis (justo como a nosotros nos gusta)
se llama Bespin y pueden leer mas sobre el aca pienso yo que es una gran alternativa a los viejos IDE que no son tan optimos para el desarrollo web. Asi que ahora los web developers contamos con una excelente alternativa a programas como
context

Notepad ++
y el glorioso Kate que siempre fue el que mas usé.

Bespin esta programado en python y es posible bajar el codigo fuente e instalarlo en tu propio servidor (pero no facil).
Como detalle me gustaría agregar que el editor de codigo de Bespin esta basado en el objeto canvas de html por lo que no podrás usarlo con navegadores que no soporten este objeto.

Funciones Lambda

Despues de mi post de closures sentí que debería haber explicado un poco de funciones lambda antes y su funcionalidad, el nombre lambda viene del calculo lambda que es una teoría matematica tan complicada que excede el alcance de este post, este blog y este autor asi que les dejo la tarea de investigación a ustedes.
Basicamente son funciones sin nombre, pero en javascript esto tiene mucha mayor profundidad, ya que lo que sucede en realidad es que EN JAVASCRIPT TODO ES UN OBJETO y me gustaría que eso quede claro por eso lo voy a repetir EN JAVASCRIPT TODO ES UN OBJETO , entonces hasta las funciones son objetos.
Por tanto es indistinto escribir cualquiera de las dos declaraciones de funciones siguientes.

function FuncX(){
return "x";
}

var FuncY = function (){
return "y";
}


de esta forma podemos ver que podemos asignar una funcion a una variable y siempre que declaramos funciones implicitamente estamos declarando variables con el nombre de la funcion.

para ver esto llevado al extremo podemos ver el siguiente ejemplo

var funcRec = function(){
return function(){
return funcRec();
}
}

alert(funcRec()()()()()()()()()()()()); // que devuelve????


a decir verdad esto es muy simple. la funcion funcRec devuelve una funcion (lambda) anonima, que al ser ejecutada devuelve el valor de la llamada a funcRec.
entonces

funcRec() //devuelve una funcion que al ser ejecutada devolverá el valor de ejecutar funcRec()
funcRec()()// ejecuta la funcion devuelta por la primer ejecucion, la cual devuelve exactamente lo mismo


confuso verdad, bueno espero que lo lean muchas veces hasta que lo entiendan. Les dejo algo más elaborado para ver si les sirve.


var a=0;
var funcRec = function(){

alert("a=" + a);
return function(){
a+=1;
return funcRec();
}
}

alert(funcRec()()());

Closures

Las closures son una parte vital del paradigma de Programación Funcional asi que vamos a darle una pequeña mirada a este concepto para aclarar las cosas un poco. Una closure es cuando definimos una funcion esta tiene acceso a las variables del entorno donde fue definida. Aun si la ejecución de ese entorno finalizó. Veamos un ejemplo porque estoy seguro que nadie entendio nada ja.

  function outer(c, d) {
var e = c * d;

function inner(a, b) {
return (e * a) + b;
}

return inner(2, 1);
}

como pueden ver en este simple ejemplo definimos una función dentro de otra sin embargo podemos ver que la funcion inner tiene acceso a la variable e que fue definida fuera de la funcion.
entonces si llamamos la funcion

outer(3,2) // returns 13

ahora veamos a que me refiero con que no importa si la funcion outter ya finalizó su ejecución.

function crearFuncion(c){
var a=3;
var b=4;
var func = function(x){
return a*b*c*x;
}
return func;
}

como podemos ver este ejemplo es aun más complicado pero nos permite reflejar el hecho de que en Javascript todo es un objeto, hasta las funciones son objetos y como las funciones pueden recibir objetos como parametros, y pueden devolver objetos, entonces tambien pueden recibir funciones y devolver funciones.
Veamos como utilizariamos esto

var f = crearFuncion(2);
alert(f(5)) // alerts 120 ( = 2*3*4*5)

// que ocurriría si hiciesemos ...
alert(crearFuncion(2)(5))


allí podemos ver que la funcion func (declarada dentro de crearFuncion) puede seguir utilizando las variables a,b,c (declarados dentro de crearFuncion) aún despues de que la ejecución de crearFuncion haya terminado.

eso son closures!

Como escribir buen Javascript

Una vez más nuestro amigo Douglas se ha esforzado en traernoes este espectacular compendio de consejos para escribir buen codigo javascript como pueden ver en Convenciones de Código para el Lenguaje de Programación Javascript es una excelente idea y una buena practica tener estos consejos en mente a medida que creemos nuestros programas (aunque muchas veces estemos apurados jaja)

Beyond JS

Ahora que ya he dedicado mi (segundo) primer Post del blog a Douglas quisiera comentarles sobre esta libreria muy poco conocida que encontré en la red, se llama Beyond JS y aunque no es una libreria que utilizaría dia a dia realmente me dejó pensando. aqui un Ejemplo de su utilización para que se deleiten

document.body.onmousemove = Function.from("star", "moveTo").delay(1000).using(
"+".using(
Function.from(event, ×),
"*".using("radius", Function.from(Math, "sin", "angle"))),
"+".using(
Function.from(event, "y"),
"*".using("radius", Function.from(Math, "cos", "angle")))
).curry({
radius: 30,
angle: function() {return (new Date)/50;}.asValue()


Como pueden ver hace arto uso de function Chaining (que conocí gracias a jquery)
y además obtiene las referencias a funciones a las funciones mediante el Function.from
el resto la verdad que requiere un analisis más largo pero eso se los dejo a ustedes.
Ah! una cosa más ven ese curry bueno vamos a hablar un poco de eso más tarde
}).gate(Function.from("doStar".element(),"checked"));

Dedicado a Douglas

Vamos a arrancar con una fuente inagotable de maravillas de este lenguaje, la página de javascript de Douglas Crockford alli podrán encontrar el Magistral articulo Javascript: El Lenguaje de Programación más Malentendido del Mundo que está solamente en ingles pero que REALMENTE vale la pena leer, junto con El Lenguaje de Programación más Malentendido del Mundo se ha Vuelto el Lenguaje de Programación más Popular del Mundo (asi es parece que Douglas disfruta de los titulos largos) espero que les resulte tan interesante y divertido como me resulto a mi

Abriendo el Blog 2.0

Ja pasados unos dias me di cuenta que practicamente semanalmente le enviaba a un grupo selecto de amigos las noticias que me habian parecido importantes sobre Javascript mi lenguaje favorito. Entonces me dije a mi mismo "deberia abrirme un blog" y luego recorde "ya lo abrí un tiempo atras" (solo que olvide postear cosas ja) asi que decidí volver a la carga a hablar con todos ustedes de lo mucho que disfruto aprender algo nuevo todos los dias con este lenguaje.