Como pensamos influencia en como nos comunicamos y viceversa. Similarmente, como pensamos la informática influencia en como programamos y viceversa. En las últimas décadas, los programadores han acumulado gran experiencia en el diseño y uso de los lenguajes de programación. Aún así, todavía no comprendemos del todo los aspectos del diseño de los lenguajes de programación, sus principios básicos y sus conceptos que forman parte del conocimiento estructural de la informática. No es suficiente para el programador con conocer C o Ruby, por ejemplo, si no que es necesario además tener un estudio de estos principios que son esenciales al programador. Esta integración añade una mayor perspectiva a la solución de problemas.
UN LENGUAJE DE PROGRAMACIÓN ES....
una herramienta para el desarrollo de software. Por lo tanto, las características de los lenguajes deben estar relacionados con la calidad del software.
EL SOFTWARE DEBE SER DE FÁCIL ESCRITURA
Se refiere a la posibilidad de expresar un programa de modo tal que sea natural para el problema. El programador no debe distraerse por los detalles o trampas del lenguaje, si no mas bien el programador debe enfocarse en la solución del problema. Aún cuando la capacidad de escritura es un criterio subjetivo, podemos decir que los lenguajes de alto nivel son de más fácil escritura que los lenguajes de bajo nivel. ¿Por qué? Porque el programador de alto nivel se concentra en la resolución de problemas, mientras que el de bajo nivel se ve frecuentemente forzado a considerar los mecanismos de direccionamiento requeridos para el acceso a ciertos datos en memoria (lenguaje assembler).
Pero no perdamos de vista que la facilidad de escritura debe ser consideraba dentro del contexto del problema a resolver. Es necesario conocer el problema a resolver para poder determinar con que lenguaje vamos a abordar la solución. Sabemos que C fue diseñado para Sistemas Operativos en 1972; en cambio Ruby fue diseñado Yukihiro Matsumoto en 1995 para la productividad y la diversión del desarrollador.Es por esto que nos va resultar más complejo desarrollar un driver para periféricos con Ruby que con C.
En el siguiente post se describen las características que presenta un sotware de fácil escritura:
Un lenguaje simple es fácil de dominar, y permite que los algoritmos puedan ser expresados fácilmente. Al hablar de simplicidad, nos estamos refiriendo a la facilidad de capturar, para poder entender y recordar lo que se quiso expresar. Nos referimos a simplicidad de un lenguaje aquel mantiene un patrón de aprendizaje, de forma tal que sea necesario aprender y recordar un conjunto mínimo de instrucciones, y a medida que se va necesitando, ir deduciendo a partir de ese conjunto familiar de instrucciones.
Un ejemplo muy claro, son las formas que posee Ruby para listar objetos de un arreglo. Tanto each, map, select, collect, reject, detect, inject como reduce, son métodos para recorrer un array.
Al aprender a usar each, los restantes deberían funcionar de igual forma:
Lenguaje Ruby
[1,2,3,4].map {|n| n*2}
# => [2,4,6,8]
[1,2,3,4].each {|n| n*2}
# => [1,2,3,4]
La segunda característica es tener mas de una manera de expresar algo. Por ejemplo,
Lenguaje Java
count = count +1
count += 1
count ++
["eva", "peron", "cristina", "nestor"].map { |name| name.capitalize }
#=> ["Eva", "Peron", "Cristina", "Nestor"]
["eva", "peron", "cristina", "nestor"].map do |name|
name.capitalize
end
#=> ["Eva", "Peron", "Cristina", "Nestor"]
["eva", "peron", "cristina", "nestor"].map &:capitalize
#=> ["Eva", "Peron", "Cristina", "Nestor"]
Otra característica es la sobrecarga de operadores, en la cual un solo operador tiene mas de un significado. Esto puede resultad util o puede incrementar la dificultad de lectura por parte del programador. Por ejemplo, es aceptable la sobrecarga del operador +, para ser usado en la suma con enteros y con punto flotante. De hecho, esta caracteristica le otorga simplicidad al lenguaje.
"Everything should be made as simple as possible, but not simpler" Einstein.
2) ORTOGONALIDAD
Empezando por 3 ejemplos:
Lenguaje C
C posee falta de ortogonalidad si consideramos las siguientes reglas junto a sus excepciones:
C posee 2 clases de tipos de datos estructurados: arreglos (array) y registros (struct). Las funciones pueden retornar records pero no arrays.
Tipos de datos que contiene un struct:
Un struct puede estar compuesto de cualquier tipo de datos excepto del mismo struct o de void (vacio).
struct account {
int account_number;
char *first_name;
char *last_name;
float balance;
};
Tipos de elementos que contiene un array:un array puede contener cualquier tipo de datos excepto void o function
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
En las funciones, los parametros son pasados por valor, excepto los arreglos, en cuyo caso son pasados por referencia.Lenguaje Ruby
En cambio en Ruby, por ejemplo, no existen excepciones para utilizar each, es decir, tanto las collections/ranges/arrays/files, todas aceptan el metodo each.
ARRAY
["first", "middle", "last"].each { |i| puts i.upcase }
HASH
{ font_size: 10, font_family: "Arial" }.each {|v, k| puts "#{v}: #{k}" }
RANGE("a".."z").each {|letter| puts letter.next }
FILES
File.open('/etc/shadow').each do |line|
puts "Esto es una linea del archivo shadow: #{line}"
end
Lenguaje Java
Un usuario del lenguaje Java se ve obligado a tener en cuenta que la asignacion funciona diferente con tipos de datos primitivos que con objetos, lo cual complica el aprendizaje y el uso del lenguaje.
boolean result = true;
char capitalC = 'C';
int[] anArray = new int[10];
Point originOne = new Point(23, 94);
Cuando las características de un lenguaje son ortogonales, entonces es
más fácil aprender el lenguaje y escribir los programas porque hay menos
excepciones y casos especiales que recordar.El usuario comprende mejor el lenguaje si tiene un conjunto relativamente pequeño de constructores primitivos pueden ser combinados para construir el flujo y las estructuras de datos de todo el programa. Es decir, se refiere a la capacidad de combinar varias características de un lenguaje en todas las combinaciones posibles, de manera que todas ellas tengan significado. El aspecto negativo de la ortogonalidad es que un programa suele compilar sin errores a pesar de contener una combinación de características que son lógicamente incoherentes o cuya ejecución es en extremo ineficiente. A causa de estas cualidades negativas, la ortogonalidad como atributo de un diseño de lenguaje es todavía motivo de controversia, pues a ciertas personas les gusta y a otras no.
Por tanto, la ortogonalidad esta directamente conectada con la simplicidad: mientras mas ortogonal sea un lenguaje, menos excepciones requerirá el lenguaje. Esto hace que el lenguaje sea mas fácil de aprender, de leer y de comprender.
3) EXPRESIVIDAD
Expresar la naturaleza del problema, es decir, concentarse en el problema-solución.
Se refiere a la posibilidad de expresar un programa en la forma que mas natural sea para el problema. El programador no debería distraerse en los detalles del lenguaje, si no que debería prestarle mas atención en resolver el problema. Aunque la expresividad es un criterio subjetivo, podemos acordar que los lenguajes de alto nivel son mas expresivos que los de bajo nivel.
Si queremos quedarnos con los nombres no repetidos:
Lenguaje Ruby
["Ana", "JUAN", "Luis", "horacio"].map(&:downcase) | ["ANA", "JUAN", "Luis", "HORACIO", "Laura"].map(&:downcase)
# => ["ana", "juan", "luis", "horacio", "laura"]
Lenguaje PHP
array_merge( array_map('strtoupper', array("ana", "JUAN", "Luis", "horacio")), array_map('strtoupper', array("ANA", "JUAN", "Luis", "HORACIO", "Laura")) ); # => ["ana", "juan", "luis", "horacio", "laura"]
4) SOPORTE DE ABSTRACCIÓN
Se refiere a la
habilidad de definir y luego utilizar estructuras complejas u
operaciones de forma tal que permita ignorar gran parte de los
detalles. Los lenguajes de programacion pueden soportar 2 tipos de categorías de abstracción: datos y procesos.
Un ejemplo muy claro
repecto al proceso de abstracción es el uso de subprogramas para
implementar, por ejemplo, un algoritmo de ordenación (sort
algorithm). Cada vez que se requiere utilizar el algoritmo de
ordenación, se convocara a dicho subprograma.
EL SOFTWARE DEBE SER LEGIBLE
Uno de los criterios más importantes para evaluar los lenguajes de programación es la facilidad con la que los programas pueden ser leidos y entendidos. Antes de 1970, el desarrollo de software era pensado en términos de la escritura del código. Una de las características más importantes de los lenguajes era la eficiencia. Los lenguajes habían sido diseñados más desde el punto de vista de la computadora que desde el usuario. Sin embargo, en los 70, se creó el concepto de ciclo de vida del software (Booch, 1987); la codificación pasó a un segundo plano, y el mantenimiento del mismo tomó mayor importancia ya que el mantenimiento del código implicaba mayores costos que el desarrollo del mismo. Debido a que la facilidad de mantenimiento está determinada en gran medida por la legibilidad de los programas, esta llego a ser una medida importante de la calidad de los programas y de los lenguajes de programación.
El software es legible si es posible seguir la lógica del programa y descubrir la presencia de errores mientras se examina el código. La legibilidad también es un criterio subjetivo, ya que es en gran medida una cuestión de gustos y estilos.
La legibilidad se debe considerar en el contexto del dominio del problema. Por ejemplo, si un programa está escrito en un lenguaje que no fue diseñado para su uso, el programa puede ser de difícil lectura.
En el siguiente post se describen las características que determinan la legibilidad del software:
1) SEMÁNTICA
Las reglas semánticas de un programa nos dicen como construir expresiones significativas, declaraciones y programas
2) SINTÁXIS
Las reglas sintacticas de una lenguaje nos dice como formar expresiones, declaraciones y programas para que se vean bien
- documentacion y comentarios
- eleccion de nombres
- uso de constantes
- convenciones lexicas
3) DEFINICIÓN (falta explicar para que este bien, no asi a lo rapido)
Precision en la definicion de la sintaxis y de la semantica
- Ambiguedad
- definiciones formales
- portabilidad
4) ESTRUCTURAS DE DATOS
Facilidades para expresar los datos del problema. Esto incluye:
- numero de componentes (tamaño fijo, tamaño variable)
- tipo de cada componente (homogéneo, heterogéneo)
- nombres para ser usados por los componentes seleccionados (se necesita un mecanismo de selección para la identificación individual de componentes de una estructura de datos)
- cantidad máxima de componentes
- organización de componentes
5) ESTRUCTURAS DE CONTROL
EL SOFTWARE DEBE SER CONFIABLE
Los usuarios deben ser capaces de confiar en el software. Las probabilidades de error debido a fallas en el prog
El sistema debe proveer soporte aun en presencia de eventos indeseables (ante fallas de software como de hardware)
1) CHEQUEO DE TIPOS
Chequeo estático o dinámico
2) ROBUSTO
Provee la habilidad de manejar eventos no deseados (arithmetic overflow, entrada invalida, etc). Estos eventos pueden ser captados y se brinda una respuesta adecuada. Des esta forma, el comportamiento del sistema se hace predecible ante situaciones anormales
3) RESTRICCIÓN DE ALIAS
Dos nombres que refieren a la misma posicion de memoria
El sistema debe proveer soporte aun en presencia de eventos indeseables (ante fallas de software como de hardware)
1) CHEQUEO DE TIPOS
Chequeo estático o dinámico
2) ROBUSTO
Provee la habilidad de manejar eventos no deseados (arithmetic overflow, entrada invalida, etc). Estos eventos pueden ser captados y se brinda una respuesta adecuada. Des esta forma, el comportamiento del sistema se hace predecible ante situaciones anormales
3) RESTRICCIÓN DE ALIAS
Dos nombres que refieren a la misma posicion de memoria
EL SOFTWARE DEBE SER MANTENIBLE
Como los costes de software aumentan y los sistemas de software son cada vez mas complejos, nos es economicamente viable tirar el software existente y desarrollar aplicaciones desde cero que lo reemplazen. El software existente debe ser modificado para satisfacer los nuevos requerimientos. Es casi imposible obtener el 100% de los requerimientos en una primera instancia; para sistemas mas complejos solo nos queda esperar a que evolucione poco a poco el sistema.
1) LOCABILIDAD
El efecto de una caracteristica se restrinja a una posicion local y pequena del programa. De todas formas, si se extendiese a una mayor parte del programa, la tarea de realizar un cambio puede ser muy complejo.
Un ejemplo: en la programacion de tipos de datos abstractos, la modificacion a una estructura definida dentro de una clase garantiza que no afecta al resto del programa siempre que las operaciones que manipulan las estructura de datos sean invocados en la misma manera.
2) MODIFICABILIDAD
Facilidad de introducir cambios
Como los costes de software aumentan y los sistemas de software son cada vez mas complejos, nos es economicamente viable tirar el software existente y desarrollar aplicaciones desde cero que lo reemplazen. El software existente debe ser modificado para satisfacer los nuevos requerimientos. Es casi imposible obtener el 100% de los requerimientos en una primera instancia; para sistemas mas complejos solo nos queda esperar a que evolucione poco a poco el sistema.
1) LOCABILIDAD
El efecto de una caracteristica se restrinja a una posicion local y pequena del programa. De todas formas, si se extendiese a una mayor parte del programa, la tarea de realizar un cambio puede ser muy complejo.
Un ejemplo: en la programacion de tipos de datos abstractos, la modificacion a una estructura definida dentro de una clase garantiza que no afecta al resto del programa siempre que las operaciones que manipulan las estructura de datos sean invocados en la misma manera.
2) MODIFICABILIDAD
Facilidad de introducir cambios
EL SOFTWARE DEBE SER EFICIENTE
La eficiencia ha sido el objetivo de cualquier sistema de software. Se trata de que el programa (ademas de realizar aquello por lo que fue creado) gestione de la mejor forma los recursos que utiliza. Se sabe que hoy en dia, el costo del hardware continua decreciendo, y a su vez el rendimiento del rendimiento continua creciendo (procesadores mas rapidos, mayor capacidad para almacenar datos)
referencias:
https://es.wikipedia.org/wiki/Ruby
http://es.wikipedia.org/wiki/C_(programming_language)






















