Diferencia entre revisiones de «Lenguaje de programación»
(→Elementos principales de un lenguaje de programación) |
(→Tipos de lenguajes de programación) |
||
| (No se muestran 14 ediciones intermedias del mismo usuario) | |||
| Línea 10: | Línea 10: | ||
El ordenador es capaz de entender un lenguaje denominado '''lenguaje máquina o lenguaje ensamblador'''. En los primeros tiempos de la Informática, los programadores escribían código directamente en este lenguaje máquina. Este tipo de lenguajes eran muy complejos de usar por parte de los programadores, pero muy sencillo de ejecutar por parte del ordenador. Por este motivo, los programas escritos en lenguaje máquina se suelen ejecutar con rapidez y sin requerir muchos recursos. | El ordenador es capaz de entender un lenguaje denominado '''lenguaje máquina o lenguaje ensamblador'''. En los primeros tiempos de la Informática, los programadores escribían código directamente en este lenguaje máquina. Este tipo de lenguajes eran muy complejos de usar por parte de los programadores, pero muy sencillo de ejecutar por parte del ordenador. Por este motivo, los programas escritos en lenguaje máquina se suelen ejecutar con rapidez y sin requerir muchos recursos. | ||
| − | Por ejemplo, el siguiente programa en ensamblador escribe el mensaje ''Hola mundo''<ref>[http://es.wikipedia.org/wiki/Hola_mundo Hola mundo (Wikipedia ES)]</ref> en la pantalla<ref>Extraído de [http://es.wikipedia.org/wiki/Lenguaje_ensamblador Lenguaje ensamblador (Wikipedia ES)]</ref>: | + | Por ejemplo, el siguiente programa en ensamblador escribe el mensaje ''Hola mundo''<ref name="holamundo">[http://es.wikipedia.org/wiki/Hola_mundo Hola mundo (Wikipedia ES)]</ref> en la pantalla<ref>Extraído de [http://es.wikipedia.org/wiki/Lenguaje_ensamblador Lenguaje ensamblador (Wikipedia ES)]</ref>: |
{{#tag:source|; --------------------------------------------- | {{#tag:source|; --------------------------------------------- | ||
; Programa que imprime un string en la pantalla | ; Programa que imprime un string en la pantalla | ||
| Línea 69: | Línea 69: | ||
Un '''intérprete''' es un programa que lee el código fuente escrito en un lenguaje de alto nivel, y lo ejecuta línea a línea, directamente. Es decir, no genera ningún programa nuevo escrito en lenguaje máquina. Por este motivo, es necesario usar el intérprete cada vez que queramos ejecutar el programa de alto nivel. A pesar de esta desventaja respecto a los compiladores, es más fácil depurar y revisar la ejecución de un programa con un intérprete que con un compilador. | Un '''intérprete''' es un programa que lee el código fuente escrito en un lenguaje de alto nivel, y lo ejecuta línea a línea, directamente. Es decir, no genera ningún programa nuevo escrito en lenguaje máquina. Por este motivo, es necesario usar el intérprete cada vez que queramos ejecutar el programa de alto nivel. A pesar de esta desventaja respecto a los compiladores, es más fácil depurar y revisar la ejecución de un programa con un intérprete que con un compilador. | ||
| − | Los lenguajes por sí mismos no son ni interpretados ni compilados. | + | Los lenguajes por sí mismos no son ni interpretados ni compilados. El mismo lenguaje puede usarse con un compilador o con un intérprete. Existen algunas limitaciones que hacen que algunos lenguajes no se puedan compilar. Además, es cierto que algunos lenguajes son más sencillos de implementar usando un compilador, y otros usando un intérprete. Por eso en ocasiones se suele decir que un lenguaje es ''compilado'' y otro es ''interpretado''. Siguiendo estos criterios, el lenguaje M de [[MATLAB]] y [[Octave UPM]] es interpretado, aunque por ejemplo, [[MATLAB]] incorpora un compilador que es capaz de transformar el código M a código ejecutable directamente. |
| − | En el [[Cálculo científico en la docencia|cálculo científico]] los | + | En el [[Cálculo científico en la docencia|cálculo científico]] los intérpretes presentan ventajas, ya que es más fácil explorar de manera interactiva cómo se comporta un programa, lo que facilita las tareas de desarrollo. Sin embargo, una vez que se termina el programa en lenguaje interpretado, se suelen usar herramientas que los transformen a un lenguaje ''compilado'', como el lenguaje C, para posteriormente generar un fichero ejecutable que se ejecute más rápidamente que el programa interpretado. Ésta es una manera habitual de trabajar con [[MATLAB]], por ejemplo. |
== Elementos principales de un lenguaje de programación == | == Elementos principales de un lenguaje de programación == | ||
| Línea 80: | Línea 80: | ||
* Sistema de tipos | * Sistema de tipos | ||
| − | La '''sintaxis''' | + | === Sintaxis === |
| + | La '''sintaxis''' define cómo deben escribirse los programas (qué símbolos hay que usar, en qué orden, etc). Por ejemplo, si queremos escribir un bucle que repita varias veces el mensaje ''Hola mundo'', en lenguaje [[MATLAB]] hay que escribir | ||
{{#tag:source|for k=1:10 | {{#tag:source|for k=1:10 | ||
disp('Hola mundo'); | disp('Hola mundo'); | ||
| Línea 90: | Línea 91: | ||
La sintaxis es uno de los elementos principales que hacen que un lenguaje de programación sea más sencillo de entender y cómodo de usar. En el caso particular de [[MATLAB]] y [[Octave UPM]], la sintaxis del lenguaje está pensada para que sea sencilla de entender, y para que sea fácil trabajar con matrices que contengan muchos elementos. Las operaciones matriciales se pueden expresar con muy poco código, al contrario que con la mayoría de los lenguajes de programación. | La sintaxis es uno de los elementos principales que hacen que un lenguaje de programación sea más sencillo de entender y cómodo de usar. En el caso particular de [[MATLAB]] y [[Octave UPM]], la sintaxis del lenguaje está pensada para que sea sencilla de entender, y para que sea fácil trabajar con matrices que contengan muchos elementos. Las operaciones matriciales se pueden expresar con muy poco código, al contrario que con la mayoría de los lenguajes de programación. | ||
| + | === Semántica === | ||
La '''semántica''' del lenguaje de programación asigna significado a las expresiones escritas del lenguaje. Por ejemplo, en el caso anterior, la semántica nos diría que tenemos una variable contador ''k'', que tomará los valores de 1 a 10, de manera consecutiva, y que repetirá el comando que muestra ''Hola mundo'' tantas veces como valores diferentes tome la variable ''k''. El proceso de asignar un significado a un determinado trozo de código lo realiza el intérprete o el compilador. Antes de asignar el significado, el intérprete también comprueba que el código es sintácticamente correcto, según las reglas del lenguaje. | La '''semántica''' del lenguaje de programación asigna significado a las expresiones escritas del lenguaje. Por ejemplo, en el caso anterior, la semántica nos diría que tenemos una variable contador ''k'', que tomará los valores de 1 a 10, de manera consecutiva, y que repetirá el comando que muestra ''Hola mundo'' tantas veces como valores diferentes tome la variable ''k''. El proceso de asignar un significado a un determinado trozo de código lo realiza el intérprete o el compilador. Antes de asignar el significado, el intérprete también comprueba que el código es sintácticamente correcto, según las reglas del lenguaje. | ||
| Línea 110: | Línea 112: | ||
error: A(I): index out of bounds; value 8 out of bound 6|lang="matlab"}} | error: A(I): index out of bounds; value 8 out of bound 6|lang="matlab"}} | ||
El código es sintácticamente correcto, pero semánticamente no es posible asignar un significado a esa línea de código, porque el vector tiene 6 elementos, y nosotros estamos pidiendo el octavo elemento. | El código es sintácticamente correcto, pero semánticamente no es posible asignar un significado a esa línea de código, porque el vector tiene 6 elementos, y nosotros estamos pidiendo el octavo elemento. | ||
| − | |||
| + | === Sistema de tipos === | ||
| + | En un lenguaje de programación podemos asignar valores a las variables. Pero además de asignar un valor, estamos también asignando un tipo. Algunos lenguajes de programación no tienen tipos, pero la mayoría de los lenguajes asignan también un tipo a los valores. | ||
| + | |||
| + | ==== Tipado estático y dinámico ==== | ||
| + | |||
| + | El ''tipado'' puede ser de dos tipos | ||
| + | * Estático | ||
| + | * Dinámico | ||
| + | Cuando el tipado es ''estático'', es necesario declarar las variables antes de usarlas, y decir de qué tipo van a ser. Si el tipado es ''dinámico'', una variable puede tener diferentes tipos dentro del mismo programa. Normalmente, los lenguajes con tipado dinámico no requieren que las variables se declaren antes de usarlas. | ||
| + | |||
| + | El lenguaje M tiene tipos y es de tipado dinámico. Si no elegimos un tipo de manera explícita, las variables en el lenguaje M tendrá tipo ''double'', que corresponde a números reales con doble precisión. Un valor real de doble precisión usa 64 bits de almacenamiento, y usa más decimales para representar el número real que otros tipos. | ||
| + | Es posible también tener otros tipos dentro del lenguaje M: | ||
| + | * Reales de precisión sencilla, que usan 32 bits de almacenamiento (''float'') | ||
| + | * Enteros de diferentes tamaños (8, 16, 32 bits) | ||
| + | * Enteros sin signo | ||
| + | * Valores lógicos | ||
| + | * Cadenas de texto | ||
| + | Existen también otros tipos más complejos (vectores, matrices, estructuras, etc.). En [[Octave UPM]] y [[MATLAB]] podemos ver los tipos de las variables usando el ''workspace'', y el comando ''whos''. | ||
| + | |||
| + | El sistema de tipos define también las reglas que permiten combinar valores de diferentes tipos. Por ejemplo, en un lenguaje con tipado estático, si se asigna un valor del tipo equivocado a una variable, se produce un error. Los lenguajes con tipado dinámico son más laxos y permisivos, pero aún así también tienen sus normas. Por ejemplo, en el lenguaje M no es posible realizar una operación aritmética entre enteros de diferentes tamaños: | ||
| + | {{#tag:source|>> a = int8(3) | ||
| + | a = 3 | ||
| + | >> b = int16(2) | ||
| + | b = 2 | ||
| + | >> a+b | ||
| + | error: binary operator '+' not implemented for 'int8 scalar' by 'int16 scalar' operations|lang="matlab"}} | ||
| + | |||
| + | Estas normas de tipado permiten a un compilador descartas posibles valores y operaciones sobre algunas variables, por lo que es posible generar un ejecutable optimizado, que se ejecute de manera más rápida. También ayudan a capturar errores en un programa, al cambiar de manera inadvertida de un tipo a otro. Sin embargo, no existen evidencias empíricas de que los programas escritos en lenguajes con tipado estático contengan menos errores que los escritos en lenguajes con tipado dinámico. La mayoría de lenguajes modernos (Python, Ruby) tienen tipado dinámico. | ||
| + | |||
| + | En el caso particular del lenguaje M, es muy habitual trabajar siempre con valores de tipo ''double'', sin cambiar a otros tipos numéricos (''float'', enteros) y sin especificar de manera explícita. Las ganancias en tiempos de ejecución que pueden lograrse al cambiar de un tipo a otro son probablemente marginales, y salvo aplicaciones muy específicas, es mejor trabajar con los tipos por defecto sin realizar conversiones de tipos. | ||
| + | |||
| + | ==== Tipado fuerte y débil ==== | ||
| + | Otra clasificación habitual de los sistemas de tipos de los lenguajes de programación los divide en: | ||
| + | * Tipado fuerte | ||
| + | * Tipado débil | ||
| + | |||
| + | Los lenguajes con ''tipado débil'' son más laxos, ya que permiten usar un tipo diferente al requerido en determinadas ocasiones. El compilador o intérprete se encarga de realizar la conversión necesaria. El lenguaje M tiene tipado débil a la hora de trabajar con valores lógicos. En muchas situaciones donde se requiere un valor de tipo lógico, el lenguaje M admite valores de otros tipos. Por ejemplo, si es un valor numérico, si es igual a 0 asume que es equivalente a un valor lógico falso. Si tiene cualquier otro valor, es verdadero. Si lo que se encuentra es un vector, asume que es falso si el vector está vacío, y verdadero si no lo está. Veamos algunos ejemplos: | ||
| + | |||
| + | El valor numérico cero es siempre falso. Al ejecutar este código, que espera siempre un valor lógico a continuación de ''if'' {{ matlab | codigo = if 0 | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | obtenemos el mensaje ''Es falso''. | ||
| + | |||
| + | Si lo cambiamos a 18 (por poner un valor diferente a cero): {{ matlab | codigo = if 18 | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | obtenemos el mensaje ''Es verdadero''. | ||
| + | |||
| + | Lo mismo ocurre con los valores negativos: {{ matlab | codigo = if -7 | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | obtenemos el mensaje ''Es verdadero''. | ||
| + | |||
| + | Si probamos ahora con vectores, cualquier vector no vacío se entiende como verdadero: {{ matlab | codigo = if [1 2 3] | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | muestra el mensaje ''Es verdadero''. | ||
| + | |||
| + | En cambio, el vector vacío se entiende como falso: {{ matlab | codigo = if [] | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | muestra el mensaje ''Es falso''. | ||
| + | |||
| + | ¿Pero qué ocurre por ejemplo con un vector todo de zeros?{{ matlab | codigo = if [0 0 0] | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | muestra el mensaje ''Es falso''. | ||
| + | |||
| + | Es decir, si el vector no está vacío, pero todos los elementos que contiene se pueden evaluar como falso, el intérprete le asigna el valor falso. Sin embargo, en ocasiones ''puede ser complicado adivinar qué va a entender el intérprete''. Veamos el siguiente ejemplo. ¿Se entenderá como verdadero o como falso? {{ matlab | codigo = if [0 1 0] | ||
| + | disp('Es verdadero'); | ||
| + | else | ||
| + | disp('Es falso'); | ||
| + | end}} | ||
| + | El vector no está vacío, y uno de sus elementos no se entendería como falso. Sin embargo, se muestra el mensaje ''Es falso''. | ||
| + | |||
| + | En los lenguajes con ''tipado fuerte'' todos los ejemplos de arriba habrían dado error, ya que no se puede usar un tipo diferente donde se requiere un valor lógico. | ||
| + | |||
| + | En el lenguaje M, '''confiar en la conversión automática del tipado débil puede conducir a errores sutiles''', y por tanto difíciles de identificar y depurar. Es mucho mejor convertir de manera explícita cualquier valor a un valor lógico, usando operadores lógicos u otras soluciones. | ||
| + | |||
| + | == Más información == | ||
| + | |||
| + | Wikipedia en español contiene un excelente artículo sobre qué es un lenguaje de programación<ref>[http://es.wikipedia.org/wiki/Lenguaje_de_programaci%C3%B3n Lenguaje de programación (Wikipedia ES)]</ref>. Hay también un listado con varias decenas de lenguajes de programación<ref>[http://es.wikipedia.org/wiki/Lista_de_lenguajes_de_programaci%C3%B3n Lista de lenguajes de programación (Wikipedia ES)]</ref>. | ||
| + | |||
| + | El primer programa que se suele desarrollar al aprender un lenguaje de programación es el ''Hola mundo''<ref name="holamundo" />, que muestra el mensaje ''Hola mundo'' en la pantalla. Suele ser un ejemplo muy sencillo y trivial, pero en algunos lenguajes, puede requerir varias líneas de código. Una buena manera de comparar lenguajes de programación es comprobar cómo se implementa el ''Hola mundo'' en ese lenguaje<ref>[http://es.wikipedia.org/wiki/Anexo:Ejemplos_de_implementaci%C3%B3n_del_%C2%ABHola_mundo%C2%BB Ejemplos de implementación del "Hola mundo" (Wikipedia ES)]</ref>. | ||
| + | |||
| + | {{ Referencias }} | ||
[[Categoría:Informática]] | [[Categoría:Informática]] | ||
Revisión actual del 19:09 30 oct 2013
Los lenguajes de programación permiten escribir programas para que se ejecuten en un ordenador. Existen muchos lenguajes de programación de diferentes tipos, que presentan ventajas e inconvenientes según el tipo de programa que se vaya a desarrollar. Los lenguajes de programación cumplen las mismas reglas que otros lenguajes naturales, aunque son lenguajes artificiales.
Contenido
1 Tipos de lenguajes de programación
Algunos lenguajes son de propósito general, y otros son más adecuados para tareas especializadas (desarrollo de aplicaciones en la web, en el escritorio, en un móvil, cálculo científico). Existen muchos criterios para clasificar los lenguajes de programación, según las características de los lenguajes. Nosotros los clasificaremos en dos grandes grupos:
- Lenguajes de bajo nivel
- Lenguajes de alto nivel
Los ordenadores pueden entender directamente los lenguajes de bajo nivel, pero no los del alto nivel, que requieren de programas que traduzcan un programa de alto nivel al lenguaje que entiende la máquina.
El ordenador es capaz de entender un lenguaje denominado lenguaje máquina o lenguaje ensamblador. En los primeros tiempos de la Informática, los programadores escribían código directamente en este lenguaje máquina. Este tipo de lenguajes eran muy complejos de usar por parte de los programadores, pero muy sencillo de ejecutar por parte del ordenador. Por este motivo, los programas escritos en lenguaje máquina se suelen ejecutar con rapidez y sin requerir muchos recursos.
Por ejemplo, el siguiente programa en ensamblador escribe el mensaje Hola mundo[1] en la pantalla[2]:
; ---------------------------------------------
; Programa que imprime un string en la pantalla
; ---------------------------------------------
.model small ; modelo de memoria
.stack ; segmento del stack
.data ; segmento de datos
Cadena1 DB 'Hola Mundo.$' ; string a imprimir (finalizado en $)
.code ; segmento del código
; ---------------------------------------------
; Inicio del programa
; ---------------------------------------------
programa:
MOV AX, @data ; carga en AX la dirección del segmento de datos
MOV DS, AX ; mueve la dirección al registro de segmento por medio de AX
MOV DX, offset Cadena1 ; mueve a DX la dirección del string a imprimir
MOV AH, 9 ; AH = código de la función del MS DOS para imprimir un string en la pantalla
INT 21h ; llamada al MS DOS para imprimir un string en la pantalla
INT 20h ; llamada al MS DOS para finalizar el programa
end programaComo podemos observar es un lenguaje muy complejo, que necesita muchas líneas de código para realizar una tarea muy sencilla. Conforme la tecnología de los ordenadores fue avanzando, también cambiaron los lenguajes de programación. Se crearon lenguajes de alto nivel. Un lenguaje de alto nivel es más fácil de entender por parte de los programadores, pero requiere ser traducido a lenguaje máquina para poder ser ejecutado por el ordenador. Por este motivo, los programas escritos en lenguajes de alto nivel suelen ser más lentos que los programas escritos en lenguajes de alto nivel. Aunque el tiempo de desarrollo requerido para escribir programas en lenguajes de alto nivel es mucho menor.
Por ejemplo, el programa equivalente al de arriba en lenguaje MATLAB, un lenguaje de muy alto nivel, sería
disp('Hola mundo');Es decir, es tremendamente más sencillo de escribir y de entender, ya que necesita una única línea de código que es bastante auto-explicativa. Sin embargo, el programa MATLAB necesita un intérprete para que el ordenador entienda el programa. El intérprete consume muchos recursos de la máquina, por lo que se ejecutará de manera mucho más lenta que el programa anterior, y también necesitará más memoria RAM y un procesador más potente.
La siguiente tabla muestra un resumen de ventajas e inconvenientes de los lenguajes de alto y bajo nivel:
| Lenguajes de alto nivel | Lenguajes de bajo nivel | |
|---|---|---|
| Ventajas | Fáciles de entender y usar por los programadores | Fáciles de ejecutar por el ordenador |
| Inconvenientes | Requieren traducción a un lenguaje de bajo nivel | Difíciles de entender por los programadores. Provoca problemas de mantenimiento de software |
| Tiempo de desarrollo | Corto | Muy largo |
| Tiempo de ejecución | Lento | Muy rápido |
En la práctica se suelen emplear mucho más los lenguajes de alto nivel. Pero esto requiere usar un programa que haga de traductor a lenguaje máquina. Existen dos clases de estos programas traductores:
- Compiladores
- Intérpretes
Un compilador es un programa que toma el código fuente escrito en un lenguaje de alto nivel, y lo transforma en un archivo escrito en lenguaje de bajo nivel, que es ejecutable directamente por el sistema operativo. Una vez generado el programa por parte del compilador, ya no se necesita usar el compilador cada vez que se quiera ejecutar el programa, se puede ejecutar directamente. Ésta es la principal ventaja de los compiladores.
Un intérprete es un programa que lee el código fuente escrito en un lenguaje de alto nivel, y lo ejecuta línea a línea, directamente. Es decir, no genera ningún programa nuevo escrito en lenguaje máquina. Por este motivo, es necesario usar el intérprete cada vez que queramos ejecutar el programa de alto nivel. A pesar de esta desventaja respecto a los compiladores, es más fácil depurar y revisar la ejecución de un programa con un intérprete que con un compilador.
Los lenguajes por sí mismos no son ni interpretados ni compilados. El mismo lenguaje puede usarse con un compilador o con un intérprete. Existen algunas limitaciones que hacen que algunos lenguajes no se puedan compilar. Además, es cierto que algunos lenguajes son más sencillos de implementar usando un compilador, y otros usando un intérprete. Por eso en ocasiones se suele decir que un lenguaje es compilado y otro es interpretado. Siguiendo estos criterios, el lenguaje M de MATLAB y Octave UPM es interpretado, aunque por ejemplo, MATLAB incorpora un compilador que es capaz de transformar el código M a código ejecutable directamente.
En el cálculo científico los intérpretes presentan ventajas, ya que es más fácil explorar de manera interactiva cómo se comporta un programa, lo que facilita las tareas de desarrollo. Sin embargo, una vez que se termina el programa en lenguaje interpretado, se suelen usar herramientas que los transformen a un lenguaje compilado, como el lenguaje C, para posteriormente generar un fichero ejecutable que se ejecute más rápidamente que el programa interpretado. Ésta es una manera habitual de trabajar con MATLAB, por ejemplo.
2 Elementos principales de un lenguaje de programación
En un lenguaje de programación tenemos tres elementos principales:
- Sintaxis
- Semántica
- Sistema de tipos
2.1 Sintaxis
La sintaxis define cómo deben escribirse los programas (qué símbolos hay que usar, en qué orden, etc). Por ejemplo, si queremos escribir un bucle que repita varias veces el mensaje Hola mundo, en lenguaje MATLAB hay que escribir
for k=1:10
disp('Hola mundo');
endEn cambio, en lenguaje Python habría que escribir
for k in range(1,10):
print("Hola mundo")La sintaxis es uno de los elementos principales que hacen que un lenguaje de programación sea más sencillo de entender y cómodo de usar. En el caso particular de MATLAB y Octave UPM, la sintaxis del lenguaje está pensada para que sea sencilla de entender, y para que sea fácil trabajar con matrices que contengan muchos elementos. Las operaciones matriciales se pueden expresar con muy poco código, al contrario que con la mayoría de los lenguajes de programación.
2.2 Semántica
La semántica del lenguaje de programación asigna significado a las expresiones escritas del lenguaje. Por ejemplo, en el caso anterior, la semántica nos diría que tenemos una variable contador k, que tomará los valores de 1 a 10, de manera consecutiva, y que repetirá el comando que muestra Hola mundo tantas veces como valores diferentes tome la variable k. El proceso de asignar un significado a un determinado trozo de código lo realiza el intérprete o el compilador. Antes de asignar el significado, el intérprete también comprueba que el código es sintácticamente correcto, según las reglas del lenguaje.
Un ejemplo de regla sintáctica del lenguaje MATLAB es que todos los bucles que comienzan por for tienen que acabar con un end. Otro ejemplo de regla sería que las cadenas de texto, que comienzan por comilla simple, tienen siempre que terminar por comilla simple. Cuando un programa no es sintácticamente correcto, el intérprete de MATLAB/Octave UPM genera un error del tipo Syntax error. Por ejemplo, un error de sintaxis es usar corchetes para intentar referirnos a un elemento de un vector:
>> v = [1 4 1 2 1 4];
>> v[4]
parse error:
syntax error
>>> v[4]
^Pueden producir también errores de tipo semántico. En lenguaje MATLAB un error típico de esta clase es intentar obtener el elemento 0 de un vector. En este lenguaje, según la semántica, todos los vectores comienzan siempre por el elemento número 1. Por ejemplo:
>> v(0)
error: subscript indices must be either positive integers or logicalsEl error es de tipo semántico porque no hemos usado un entero positivo o un valor lógico para direccionar en el vector.
Otro error de tipo semántico es intentar recuperar un elemento de un vector más allá del límite del vector. Siguiendo con los ejemplos anteriores, el vector tiene 6 elementos. Si intentamos recuperar el elemento 8 del vector ocurre lo siguiente:
>> v(8)
error: A(I): index out of bounds; value 8 out of bound 6El código es sintácticamente correcto, pero semánticamente no es posible asignar un significado a esa línea de código, porque el vector tiene 6 elementos, y nosotros estamos pidiendo el octavo elemento.
2.3 Sistema de tipos
En un lenguaje de programación podemos asignar valores a las variables. Pero además de asignar un valor, estamos también asignando un tipo. Algunos lenguajes de programación no tienen tipos, pero la mayoría de los lenguajes asignan también un tipo a los valores.
2.3.1 Tipado estático y dinámico
El tipado puede ser de dos tipos
- Estático
- Dinámico
Cuando el tipado es estático, es necesario declarar las variables antes de usarlas, y decir de qué tipo van a ser. Si el tipado es dinámico, una variable puede tener diferentes tipos dentro del mismo programa. Normalmente, los lenguajes con tipado dinámico no requieren que las variables se declaren antes de usarlas.
El lenguaje M tiene tipos y es de tipado dinámico. Si no elegimos un tipo de manera explícita, las variables en el lenguaje M tendrá tipo double, que corresponde a números reales con doble precisión. Un valor real de doble precisión usa 64 bits de almacenamiento, y usa más decimales para representar el número real que otros tipos. Es posible también tener otros tipos dentro del lenguaje M:
- Reales de precisión sencilla, que usan 32 bits de almacenamiento (float)
- Enteros de diferentes tamaños (8, 16, 32 bits)
- Enteros sin signo
- Valores lógicos
- Cadenas de texto
Existen también otros tipos más complejos (vectores, matrices, estructuras, etc.). En Octave UPM y MATLAB podemos ver los tipos de las variables usando el workspace, y el comando whos.
El sistema de tipos define también las reglas que permiten combinar valores de diferentes tipos. Por ejemplo, en un lenguaje con tipado estático, si se asigna un valor del tipo equivocado a una variable, se produce un error. Los lenguajes con tipado dinámico son más laxos y permisivos, pero aún así también tienen sus normas. Por ejemplo, en el lenguaje M no es posible realizar una operación aritmética entre enteros de diferentes tamaños:
>> a = int8(3)
a = 3
>> b = int16(2)
b = 2
>> a+b
error: binary operator '+' not implemented for 'int8 scalar' by 'int16 scalar' operationsEstas normas de tipado permiten a un compilador descartas posibles valores y operaciones sobre algunas variables, por lo que es posible generar un ejecutable optimizado, que se ejecute de manera más rápida. También ayudan a capturar errores en un programa, al cambiar de manera inadvertida de un tipo a otro. Sin embargo, no existen evidencias empíricas de que los programas escritos en lenguajes con tipado estático contengan menos errores que los escritos en lenguajes con tipado dinámico. La mayoría de lenguajes modernos (Python, Ruby) tienen tipado dinámico.
En el caso particular del lenguaje M, es muy habitual trabajar siempre con valores de tipo double, sin cambiar a otros tipos numéricos (float, enteros) y sin especificar de manera explícita. Las ganancias en tiempos de ejecución que pueden lograrse al cambiar de un tipo a otro son probablemente marginales, y salvo aplicaciones muy específicas, es mejor trabajar con los tipos por defecto sin realizar conversiones de tipos.
2.3.2 Tipado fuerte y débil
Otra clasificación habitual de los sistemas de tipos de los lenguajes de programación los divide en:
- Tipado fuerte
- Tipado débil
Los lenguajes con tipado débil son más laxos, ya que permiten usar un tipo diferente al requerido en determinadas ocasiones. El compilador o intérprete se encarga de realizar la conversión necesaria. El lenguaje M tiene tipado débil a la hora de trabajar con valores lógicos. En muchas situaciones donde se requiere un valor de tipo lógico, el lenguaje M admite valores de otros tipos. Por ejemplo, si es un valor numérico, si es igual a 0 asume que es equivalente a un valor lógico falso. Si tiene cualquier otro valor, es verdadero. Si lo que se encuentra es un vector, asume que es falso si el vector está vacío, y verdadero si no lo está. Veamos algunos ejemplos:
El valor numérico cero es siempre falso. Al ejecutar este código, que espera siempre un valor lógico a continuación de ifif 0
disp('Es verdadero');
else
disp('Es falso');
endobtenemos el mensaje Es falso.
Si lo cambiamos a 18 (por poner un valor diferente a cero):if 18
disp('Es verdadero');
else
disp('Es falso');
endobtenemos el mensaje Es verdadero.
Lo mismo ocurre con los valores negativos:if -7
disp('Es verdadero');
else
disp('Es falso');
endobtenemos el mensaje Es verdadero.
Si probamos ahora con vectores, cualquier vector no vacío se entiende como verdadero:if [1 2 3]
disp('Es verdadero');
else
disp('Es falso');
endmuestra el mensaje Es verdadero.
En cambio, el vector vacío se entiende como falso:if []
disp('Es verdadero');
else
disp('Es falso');
endmuestra el mensaje Es falso.
¿Pero qué ocurre por ejemplo con un vector todo de zeros?if [0 0 0]
disp('Es verdadero');
else
disp('Es falso');
endmuestra el mensaje Es falso.
Es decir, si el vector no está vacío, pero todos los elementos que contiene se pueden evaluar como falso, el intérprete le asigna el valor falso. Sin embargo, en ocasiones puede ser complicado adivinar qué va a entender el intérprete. Veamos el siguiente ejemplo. ¿Se entenderá como verdadero o como falso?if [0 1 0]
disp('Es verdadero');
else
disp('Es falso');
endEl vector no está vacío, y uno de sus elementos no se entendería como falso. Sin embargo, se muestra el mensaje Es falso.
En los lenguajes con tipado fuerte todos los ejemplos de arriba habrían dado error, ya que no se puede usar un tipo diferente donde se requiere un valor lógico.
En el lenguaje M, confiar en la conversión automática del tipado débil puede conducir a errores sutiles, y por tanto difíciles de identificar y depurar. Es mucho mejor convertir de manera explícita cualquier valor a un valor lógico, usando operadores lógicos u otras soluciones.
3 Más información
Wikipedia en español contiene un excelente artículo sobre qué es un lenguaje de programación[3]. Hay también un listado con varias decenas de lenguajes de programación[4].
El primer programa que se suele desarrollar al aprender un lenguaje de programación es el Hola mundo[1], que muestra el mensaje Hola mundo en la pantalla. Suele ser un ejemplo muy sencillo y trivial, pero en algunos lenguajes, puede requerir varias líneas de código. Una buena manera de comparar lenguajes de programación es comprobar cómo se implementa el Hola mundo en ese lenguaje[5].