
JavaScript, Python, Snap!, C++, Java, Scheme, Prolog... ¿Por qué hay tantos lenguajes de programación? ¿Por qué no elegimos el mejor, o diseñamos uno nuevo y mejor, y nos atenemos a él?
Algunos lenguajes tienen propósitos muy limitados; estos se llaman lenguajes con propósito especial. Por ejemplo, Microsoft Word tiene un lenguaje de programación incorporado llamado "macros de Word" que solo sirve para generar datos y dar formato a un documento. Así como, HTML (Lenguaje de marcado de hipertexto) es solo para estructurar páginas web.
Los lenguajes de propósito general no tienen un propósito específico. En cierto sentido, estos idiomas son todos iguales: si un algoritmo puede ser expresado en un idioma, puede ser expresado en todos ellos. Se incluyen varias características básicas en casi todos los idiomas, incluidos los operadores aritméticos (+
, -
, ×
, ÷
) y operadores booleanos (y
, o
, no
). Las diferencias entre los idiomas se refieren principalmente a niveles de abstracción.
Un lenguaje de nivel alto (como Snap! o Scheme) incluye muchas abstracciones incorporadas que hacen más fácil centrarse en el problema que se quiere resolver en lugar de en cómo funciona el hardware de la computadora. Un lenguaje de bajo nivel (como C) tiene menos abstracciones, requiriendo que sepas mucho sobre la arquitectura de tu computadora para escribir un programa.
Los lenguajes de nivel alto pueden producir programas más seguros —los que son menos propensos a tener errores—porque las abstracciones manejan detalles desordenados que pueden hacer fracasar a los programadores.
Los lenguajes de nivel alto reducen los errores en el uso de la memoria. Los lenguajes más antiguos y de bajo nivel requerían que el programador manejara el uso de la memoria de la computadora con instrucciones que dijeran "consígueme un bloque de memoria lo suficientemente grande para contener 100 números" y otras instrucciones que dijeran "bien, ya terminé de usar este bloque de memoria; puede ser asignado para algún otro propósito."
Es una molestia en la que hay que pensar, y a los programadores humanos no se les da bien esto. En los lenguajes de bajo nivel, un error muy común es que una parte del programa diga "He terminado con este bloque de memoria" mientras que otra parte del programa lo sigue usando. Los lenguajes de alto nivel se encargan de esto por nosotros usando una técnica llamada recolección de basura que pone a la computadora a cargo de saber cuándo un bloque de memoria ya no está en uso.
Los lenguajes de alto nivel también pueden hacer la programación mucho más conveniente porque ofrecen más abstracciones. Un ejemplo son las funciones de orden más alto (como mapear
, mantener
, combinar
y para cada
), que permiten al programador escribir un código más corto y limpio.
para cada
en Unidad 2 Laboratorio 2: Comprobación de cada respuesta del cuestionario.mantener
en Unidad 2 Laboratorio 3: Mantener
elementos de una lista.mapear
en Unidad 3 Laboratorio 2: Transformar cada elemento de la lista.combinar
en Unidad 2 Laboratorio 4: Más reporteros matemáticos.Mantener
toma un predicado (una pregunta) como entrada y reporta una lista de los elementos que hacen que ese predicado sea verdadero.Combinar
toma un predicado con dos espacios en blanco (como () + () o unir () ()) como entrada y reporta del resultado de combinar todos los elementos de la lista usando esa función (por ejemplo, sumándolos todos juntos o uniéndolos todos en una cadena de texto).
En C, puedes hacer esto de la forma más larga:
pero C no te deja tomar una expresión (como o
) y ponerla en una función de orden superior como
mapear
:
La mejor razón para usar lenguajes de bajo nivel es para escribir sistemas operativos (como Windows, Mac OS X, Android, o iOS). Aprenderás más acerca de sistemas operativos en la página Dominio de software: Sistemas operativos.
Los programadores de aplicaciones no suelen decidir "Voy a escribir este programa en un lenguaje de bajo nivel". Puede que simplemente no se den cuenta de que es posible alcanzar niveles más altos de abstracción. Por ejemplo, el hardware de una computadora limita el tamaño de los números que su unidad aritmética puede sumar en un solo paso. Cuatro mil millones—unos diez dígitos—es un límite de tamaño común para los números enteros. Los programadores que utilizan Java, JavaScript, Python, C o C++ pueden pensar que este límite es inevitable. Pero los programadores que usan lenguajes de alto nivel, como Scheme o Common Lisp, saben que pueden hacer aritmética con números de millones o miles de millones de dígitos, limitados solo por el tamaño de la memoria de la computadora. Como verás más adelante, Snap! también tiene una librería que te permite hacer esto.
Las personas a menudo dicen que los diferentes lenguajes de programación son buenos para diferentes tipos de programas, pero excepto para el procesamiento de video en 3D, es difícil imaginar una aplicación que se vería perjudicada por cosas como la recolección de basura o funciones de orden superior. Hay solo unos pocos casos en los que las personas diseñan deliberadamente lenguajes con características que podrían no ser deseadas para algunas aplicaciones. Aquí hay un ejemplo: En Snap!, una cadena de texto de solo dígitos se considera un número; puedes hacer aritmética sobre ella. En un lenguaje para estudiantes, el requerir una conversión explícita entre tipos de datos solo hace más difícil empezar a programar. Pero la mayoría de los lenguajes que no son para principiantes mantienen los dos tipos de datos separados.
Los programadores pueden pensar que la abstracción es demasiado lenta. Esto solía ser cierto, y los programadores de videojuegos en 3D todavía necesitan toda la velocidad que puedan conseguir porque sus programas presionan la velocidad de las computadoras modernas. Así que a menudo escriben parte de sus programas, la parte que realmente pone las imágenes en la pantalla, en lenguaje de máquina, solo para la velocidad. Pero la mayoría de los programadores escriben aplicaciones que no fuerzan a las computadoras en absoluto. Cuando envías un correo electrónico o un mensaje de texto, el factor limitante es la velocidad con la que puedes escribir, no la velocidad con la que tu computadora puede ejecutar programas.
Código heredado. Los programadores de la industria casi nunca llegan a escribir un programa desde el principio. Mucho más a menudo, mantienen un programa que alguien escribió hace años, y esa persona puede que ya no trabaje para esa compañía. A largo plazo, podría ser mejor reescribir el programa en un lenguaje más moderno, pero a corto plazo, no hay tiempo para hacerlo, así que terminan modificando el código existente en el lenguaje de programación existente.
Tanto los idiomas de alto como de bajo nivel son utilizados por personas para escribir programas de máquina. El hardware de la computadora entiende una especie de lenguaje de nivel ultra bajo, llamado lenguaje de máquina. Programas especiales llamados compiladores e intérpretes se utilizan para traducir los lenguajes de programación de humanos a lenguaje de máquina para ser ejecutado por la computadora.
Un compilador es un programa que toma un programa de lenguaje de alto o bajo nivel (el código de origen) como entrada y produce un programa de lenguaje de máquina (el código de objeto) como su salida. Una vez producido, el programa de lenguaje de máquina puede ser ejecutado repetidamente sin necesidad de ser compilado de nuevo.
Un intérprete es un programa que toma un programa de alto o bajo nivel como entrada y lleva a cabo las instrucciones del lenguaje de la máquina según sea necesario para ejecutar el programa. No produce un programa de lenguaje de máquina independiente como salida y tendrá que repetir el proceso de nuevo la próxima vez.
¿Eso significa que los compiladores son mejores?
Exacto, excepto que el proceso de escribir un programa incluye depuración. Durante la depuración, un intérprete puede ayudar proporcionando información sobre el progreso del programa, como la característica de paso visual en Snap!, y permitiendo pequeños cambios en el programa de origen sin tener que ejecutar un compilador repetidamente. Por ejemplo, en Snap! puedes arrastrar un bloque a un script mientras se está ejecutando, y un compilador no podría permitir eso.
Para programadores profesionales, el mejor arreglo es tener ambos un intérprete y un compilador para el mismo lenguaje. El programador escribe y depura el programa usando un intérprete, y una vez que están seguros de que funciona, lo compilan. Entonces, el compilador puede funcionar lentamente, poniendo mucho esfuerzo en optimizar el código de lenguaje de máquina, para que obtengan el programa compilado lo más rápido posible.
Una de las características que te da Snap! es que puedes poner el texto del título en el medio de un bloque.
polígono
en Unidad 1: Gráficos y arte.polígono(30, 15)
x && y << z. ¿Cómo sabes cuál viene primero?
&&o
<<?
Observa el ejemplo, C Precedencia del operador.
Una de las razones para crear nuevos lenguajes de programación es facilitar la escritura de programas paralelos —programas que pueden usar más de un procesador al mismo tiempo. Hoy en 2017, las computadoras y los teléfonos inteligentes tienen chips de procesador multinúcleo que pueden incluir 2, 4, u 8 procesadores todos ejecutándose en código al mismo tiempo. (El número de procesadores aumentará aún más con el tiempo). Las grandes compañías como Google usan el paralelismo aún más; tienen grupos de miles de computadoras, todas trabajando en el mismo programa.
Lenguajes de programación funcional (lenguajes en los que los programadores nunca cambian el valor de una variable) son particularmente adecuados para el paralelismo porque no hay peligro de que un procesador cambie el valor de una variable que otro procesador está usando. A lo largo de este curso te hemos introducido en técnicas de programación funcional siempre que ha sido posible, incluyendo la redacción de reporteros y el uso de funciones de orden superior (mapear
, mantener
, y combinar
).
conjunto
(en su lugar, utilizarías variables de entrada de funciones recursivas) y estos cuatro comandos de lista: añadir
, borrar
, insertar
, y reemplazar
(en lugar de eso, usarías en frente de
, elemento 1 de
y todo menos el primero de
para reportar una nueva lista con diferentes valores en lugar de cambiar la lista anterior).