jueves, 26 de marzo de 2009

Lenguajes fuertemente tipados vs. lenguajes no tipados

En el mundo existen dos tipos de programadores: los que les gustan los lenguajes fuertemente tipados (strongly-typed) y los que les gustan los lenguajes no tipados (weakly-typed). Y no se hablan...

Yo soy del primer grupo, creo que por una cuestión de cuales son los lenguajes que he usado: desde Pascal en la facultad, pasando por C, C++, Java, C#, hasta GeneXus. Definir de qué tipo de datos es una variable me resulta de lo más natural.

No quiero ponerme en la postura de discutir cual opción es mejor, porque claramente se puede lograr lo mismo con cualquier tipo de lenguaje, pero hay cosas en los lenguajes no tipados que no me convencen.

El otro día tuve que revisar un programa escrito en PHP en busca de un posible bug, y la verdad que no saber de que tipo es una variable es algo que me choca.

Por ejemplo, si tengo una invocación (puede estar mal la sintaxis) de la forma:
$var->methodName($arg1, $arg2, $arg3);
si no se de que tipo es la variable $var, ¿donde busco la definición del método methodName?

A mi por lo menos me gusta saber con que tipos de datos estoy trabajando...

Tambiénme choca que se puedan hacer cosas como (puede estar mal la sintaxis):
$a = 1;
...
$a = 'Hola' + $a;
...
$a = new HttpClient('www.example.com');
...
$a = $a + 1;
pero bueno, se supone que esa es la ventaja de no tener chequeos estrictos en el tipo de datos, ¿no? Me parece que permitir saltearse el chequeo de tipos es algo que puede provocar más bugs.

10 comentarios:

  1. Estoy de acuerdo, probablemente también por mi formación, pero me gustan los lenguajes fuertemente tipados.
    Hace poco estuve incursionando en python y me chocha bastante no conocer el tipo de las variables, no contar con un buen intellisense (autocompletar) y detectar errores en ejecución que se podrían detectar en la codificación.

    Supongo que la ventaja en este tipo de lenguajes siempre vine por el lado de la "flexibilidad" y la "expersividad" que permiten escribir mucho menos código. Lo cual disminuye el número de bugs (lógicos) y acelera la codificación. Dejando más tiempo para corregir otros bugs.

    ResponderEliminar
  2. Como hace 10 años que uso Smalltalk debo decir que NO me gusta definir los tipos de las variables. Hay que tener en cuenta que Smalltalk es especial. Siempre vas a saber de que tipo es una variable, le das "Inspect" al objeto y te muestra el objeto en un "Inspector", con el tipo, las variables de instancia, etc.
    Hay muchos de los problemas que se mencionan de los lenguajes NO tipados que en Smalltalk sencillamente NO suceden. Por ejemplo, Smalltalk no se definen los tipos pero tenes intellisense.
    Saludos,
    Bruno

    ResponderEliminar
    Respuestas
    1. Estimado, en Python si se puede saber el tipo de dato que tiene asignado una variable.
      Existe una función que se llama type()

      Eliminar
  3. Tipado fuerte-vs-no tipado es toda una "holy war". Mi experiencia con lenguages no tipados es en JavaScript, y creo que son muy poderosos sobre todo por la flexibilidad que te brindad para lograr resultados rapidos. (Programacion exploratoria creo que le dicen) y tambien, desde el punto de vista de OO, reaccionar a "mensajes no definidos"
    Pero por otro lado, para asegurarte que estas usando los tipos correctos, tenes que escribir tests unitarios. Yo prefiero no tener que escribir tests y que el compilador se encargue de eso. Creo que la gran utilidad es usar el compilador para asegurarse que los contratos (interfaces) entre modulos se cumplan.
    Una critica muy comun es que hay que escribir mucho mas y que es redundante en la mayoria de los casos.
    Pero lenguages como Scala, Haskell, F#, o ML (sobre todo de programacion funcional) tienen "inferencia de tipos": el tipo de cada variable es deducido por el compilador segun el uso que se le da y no hay que darlo explicitamente. Es muy interesante.

    ResponderEliminar
  4. Todo es relativo. En Smalltalk en realidad como todo es un objeto las "variables" en realidad son un vinculo (puntero) con nombre a otro objeto.
    miObjeto := ChessPlayer named: 'Karpov'.
    miObjeto esta apuntando (es un vinculo, puntero) a un objeto de clase ChessPlayer que se llama 'Karpov'.
    miObjeto puede tener una "variable" llamada #paisOrigen, entonces, #paisOrigen es un vinculo a un objeto de clase Pais, y asi con todos.
    miObjeto paisOrigen. "devuelve unPais"
    miObjeto := 125.
    ahora la variable (vinculo o punteron con nombre) apunta al objeto 125 que es anInteger.
    De esta forma emula un sistema biológico, solo hay objetos y vínculos entre objetos, estos se comunican enviándose mensajes, nada más. Por ejemplo el cuerpo humano (biológico) es un sistema muy complejo a todo nivel. Sin embargo a las células no se le definen los tipos, no hay un compilador chequeando todo el cuerpo por si hay un error de tipo, o si una variable esta definida, ni hay test unitarios. Esto demuestra que se pueden construir sistemas complejos sin test unitarios, chequeo de tipos, etc. Con ambientes tipados también se pueden construir sistemas muy complejos, uno no invalida al otro. Smalltalk se parece más a un sistema biológico. Pero como todo es relativo, existe un ambiente llamado StrongTalk, que es un Smalltalk que requiere definición de tipos.

    Saludos,
    Bruno

    PD: me quedo sin definir los tipos.

    ResponderEliminar
  5. Hola... Segun wikipedia... "Un lenguaje de programación es fuertemente tipado si no se permiten violaciones de los tipos de datos, es decir, dado una variable de un tipo concreto, no se puede usar como si fuera una variable de otro tipo distinto a menos que se haga una conversión."

    El lenguaje "C" son debilmente tipado (p.e. un entero se puede usar como puntero).

    Java en cambio es fuertemente tipado.

    Otra tema es que la declaracion de tipos deba ser explicita como en Java o implicita como en Ruby o Phyton.

    Estos 2 lenguajes son fuertemente tipados por lo que no se hacer cosas como
    a= 1
    b = "a"
    c = a + b

    Pero ninguna de estas dos caracteristicas son el centro del problema del presente post.

    El tema es si el lenguaje es dinámico o estático.

    Cuando el lenguaje es estático, como C, Java o C# el compilador la tiene fácil y nos puede ayudar con verificación de errores, coloreo de sintaxis y asistencia a la escritura del codigo como el intelisense.

    El problema es cuando los lenguajes son dinámicos como Ruby o Phyton... en ese caso el tema se la complica la vida al compilador/interprete/IDE.

    Debo confesar que algunas veces extraño un buen intelisense... pero las ventajas de los lenguajes dinámicos son tan enormes que bien vale la pena la perdida de ayuda por parte del compilador.

    Tal vez este no sea el lugar para introducir una discusión... pero si tiene algun tiempo libre les recomiendo encarecidamente que prueben lenguajes como Ruby... son realmente fantastico y aumenta la productividad enormemente.

    sds

    ResponderEliminar
  6. Intelisense, no se Ruby o Phyton, pero Smalltalk es dinamico, y tiene intelisense.
    No es 100% exacto debido a la naturaleza dinamica del ambiente, pero no me doy ni cuenta, el intelisense es bunisimo.
    Hay 3 "niveles de exactitud" del intelisense.
    1. En el Debugger (tenes los "objetos vivos") es 100%.
    2. En los Class Browser, Workspaces y otras herramientas sera un 80% (depende).

    ResponderEliminar
  7. Hola Marcos, obviamente entiendo tu punto, y estoy de acuerdo. Un "señalamiento" sería el siguiente. El Tipo es un asunto complejo y múltiple. No sólo está el fuerte vs. débil, también está el late vs. early, el inferred vs. explicitado (haskell, lo probaste? muy "fuertemente" tipoado, y al mismo tiempo inferred, y te asegura cosas que ningún lenguaje fuertemente tipado tipo Pascal, o Java te aseguran. Como que el tipo es ya buena parte del programa, eso está muy bueno...) Por otro lado, tenés toda la gama de lenguajes Perl , Python, Ruby, que tienen tipo en el valor y no en la variable , pero admiten asserts (chequeos, que pueden ser de tipo, queda a gusto del programador).

    No es una guerra "santa" ni "pecaminosa". Es un proceso dialéctico. .....

    saludos, haroldo

    ResponderEliminar
  8. Estoy de acuerdo contigo en cuanto a lo que dices que un lenguage no tipado puede ocasionar bugs, pero no solo eso, sino que es más difícil hallarlos, mientras menos estricto sea el compilador más te da soga para equivocarte. Y lo digo porque yo he usado lenguajes de los dos lados, tanto los fuertemente tipados (Java) como los no tipados como PHP.

    ResponderEliminar
  9. Estoy de acuerdo con Alejandro Di Battista, aquí se habla de tipado estático vs tipado dinámico y no si es fuerte o débilmente tipado, un ejemplo claro es Python: tiene tipado dinámico, pues no tienes que declarar el tipo; pero es fuertemente tipado al no poder tratar una variable como si fuera de otro tipo.

    ResponderEliminar