Software ******** Es la parte lógica del sistema informático. Dentro del software podemos distinguir: + *Software base*, que es aquel cuya finalidad es hacer funcionar al *hardware*, y dentro del cual incluímos el sistema operativo, los controladores y el *firmware*. + *Software de aplicación*, constituido por el resto de *aplicaciones informáticas* que permite convertir al ordenador en una herramienta útil para el usuario. .. note:: Los **datos** son también algo lógico, pero preferimos considerarlos más como materia de procesamiento que como componente del sistema informático, de ahí que no los citemos dentro del *software*. No obstante lo anterior, un programa es en sí mismo dato cuando se encuentra almacenado en forma de ficheros en el dispositivo de almacenamiento. Programas ========= Un :dfn:`programa` es un conjunto ordenado de instrucciones que definen cómo debe un ordenador procesar sus datos de entrada. Por su parte, una :dfn:`aplicación informática` es el conjunto de programas que permiten a un usuario llevar a cabo una tarea. Los procesadores son capaces de interpretar directamente sólo instrucciones numéricas (p.e. la instrucción *sumar* se representa por un código numérico binario). Los programas codificados así se dice que están en :dfn:`código máquina`. Como escribirlos directamente de esta forma es inviable para un programador humano, existen los :dfn:`lenguajes de programación` que son lenguajes formales que permiten al programador definir las instrucciones que desarrollan el algoritmo de un programa. .. seealso:: `TIOBE <https://www.tiobe.com/>`_ publica todos los meses un `conocido índice <https://www.tiobe.com/tiobe-index/>`_ que intenta medir la publicidad de los lenguajes de programación. Hay distintas clasificaciones: Según su *cercanía al código máquina* - **Lenguaje de bajo nivel** o **ensamblador** que es aquel que, simplemente, asigna un nombre a cada instrucción numérica del procesador. También permite definir macroinstrucciones que reunen bajo un nombre un conjunto de instrucciones simples del procesador. Obviamente, un programa en ensamblador sólo es útil para los procesadores que usan el juego de instrucciones para el que se escribió. - **Lenguaje de alto nivel** que es aquel que abstrae al programador de los detalles particulares del procesador acercándose al lenguaje natural. Gracias a esta característica el código es portable entre procesadores con distintos conjuntos de instrucciones. Ejemplos de lenguajes de este tipo son Java_, Python_, Javascript_, *Haskell* o *LISP*. - **Lenguaje de medio nivel** que es aquel lenguaje que siendo de alto nivel, permite acceso a bajo nivel a registros o direcciones de memoria. Es el caso del lenguaje de programación C_. Según su **paradigma** El :dfn:`paradigma de programación` hace referencia a la filosofía para el desarrollo del programa. Dependiendo de su paradigma la programación puede ser: - **Imperativa**, que consiste en indicar cómo hacer lo que se pretende hacer. Hay distintos paradigmas dentro de este enfoque: - **Estructurada**, que se basa en el uso de tres estructuras de programación (secuencia, condicional y bucle) y la definición de funciones. El ejemplo más sobresaliente de este paradigma es C_. - **Modular**, que añade a la anterior otra estructura más: el módulo. C_ también es modular. - **Orientada o objetos**, que es un paradigma que, aunque comparte las cuatro estructuras anteriores organiza el código en objetos que incluyen datos y comportamiento y se interrelacionan entre sí. Todos los lenguajes imperativos modernos son orientados a objetos: *C++*, Java_, Python_, Javascript_. - **Declarativa**, que consiste en indicar qué es lo que se pretende hacer. Dentro de este enfoque los paradigmas más conocidos son: - **Funcional**, que se basa en el uso de funciones matemáticas. El lenguaje puramente funcional más conocido es *Haskell*. - **Lógica**, que se basa en el uso de predicados lógicos. *Prolog* es el lenguaje más conocido. .. note:: Es habitual que los lenguajes de programación no desarrollen un único paradigma, sino que compartan enfoques de paradigmas distintos. Por ejemplo, Javascript_ o Python_ tienen características de programación funcional. Según **su traducción** a código máquina Al no estar escritos los programas en código máquina es necesario que se lleve a cabo una traducción a éste desde el código escrito en el lenguaje de programación usado. Dependiendo de cómo se lleve a cabo esta traducción se distingue: - Lenguaje **compilado**, que es aquel en que se lleva a cabo la traducción a código máquina y tal traducción se almacena en fichero. Cuando se ejecuta el programa lo que se hace es ejecutar el fichero compilado, esto es, el resultado de la traducción. En consecuencia: #. El código es código máquina y, por tanto, directamente inteligible por el procesador. #. Por la razón anterior, no se necesita tener instalada ninguna herramienta de traducción en el ordenador en que se desea usar el programa. #. Como no hay que hacer traducción durante la ejecución, ésta es más rápida y consumen menos recursos. #. El fichero compilado sólo es válido para procesadores con el juego de instrucciones y el sistema operativo para el que se compiló (plataforma). Si se quisiera utilizar en otro tipo de procesadores, habría que tener acceso al código fuente y realizar otra compilación (traducción) distinta. Son lenguajes compilados C_ o Pascal_. - Lenguaje **interpretado**, que es aquel en el que se lleva a cabo la traducción durante el proceso de ejecución. En los puramente interpretados la traducción se lleva a cabo a medida que se va ejecutando el fichero. #. El código es el código fuente escrito por el programador que no es inteligible por el procesador. #. En consecuencia, es necesario tener instalado en todo sistema en el que se quiera usar el programa el :dfn:`interprete`, esto es, el programa que se encarga de traducir el código fuente en código máquina. #. La traducción se lleva a cabo a medida que se ejecuta el programa, lo que supone un esfuerzo extra que merma la velocidad y el rendimiento. #. El código fuente es válido para todas aquellas plataformas para los que existe intérprete. Un ejemplo de lenguaje interpretado es el lenguaje de la *shell* de Linux. Modernamente, no obstante, muchos lenguajes interpretados han adoptado un camino intermedio: * Una primera fase en que se compila el código fuente a *bytecode* que es un código intermedio que es muchísmo más sencillo y rápido de interpretar a código máquina. * Una segunda fase en la que el *bytecode* se interpreta a código máquina. Con esta estrategia, al usuario se le puede proporcionar el *bytecode* y el intérprete, lo cual mejora el rendimiento y la velocidad. Además, el *bytecode* se caracteriza por ser independiente de la plataforma, por lo que un mismo *bytecode* sirve para distintos tipos máquinas. Lenguajes como Java_ y Python_ siguen esta filosofía. Licencias ========= Un aspecto indispensable a considerar en el uso del *software* es su **licencia**. Una :dfn:`licencia` es la declaración de la persona con atribución legal sobre una cosa (por lo general, el propietario) por la que confiere ciertos permisos sobre tal cosa a otra persona. Restringiendo el concepto al *software*, hay cuatro aspectos para los que el propietario legal puede conferir permiso al potencial usuario: **Uso** que no requiere explicación. **Acceso al código** o sea, permitir el acceso al código fuente escrito por el programador, para estudiar cómo lo ha hecho y adaptarlo a las propias necesidades. **Copia** o sea, permitir la copia del propio programa para sí o para terceros. **Mejora** o sea, el permiso para publicar las mejoras que se hayan llevado a cabo sobre el código. Las licencias de *software* se distinguen por como permiten o restringen estos cuatro aspectos. Muy genéricamente podemos distinguir tres tipos: * *Software* en el dominio público, que es *software* que carece de licencia. * *Software* libre y *software de código abierto*. * *Software* privativo, en contraposición, al anterior. .. _free-software: *Software* libre ---------------- Ideado por la |FSF|, es aquel que cumple con las cuatro libertades (relacionadas con los cuatro aspectos ya reseñados): 0. Libertad de *uso*, esto es, no hay limitación sobre quién usa el *software* o para qué lo usa. #. Libertad de **acceso al código fuente**, esto es, el usuario tiene derecho a acceder al código escrito por el programador y a obrar sobre él los cambios que estime oportunos para ajustarlo a sus necesidades. #. Libertad de **distribución**, esto es, el usuario tiene entera libertad para copiar el *software* para terceras personas. #. Libertad de **mejora**, esto es, el usuario puede publicar cualquier cambio que haya realizado en el código fuente a fin de que terceros se beneficien con él. Hay dos grandes familias de licencias libres dependiendo de cómo articulen la última de las libertades: - Licencias de tipo |BSD|, en las que no se establece ninguna restricción sobre el nuevo *software* generado gracias a la *libertad de mejora*. Recibe este nombre porque fue la licencia con la que se distribuía la versión de UNIX que desarrollaba la Universidad de *Berkeley* y que recibía el nombre de |BSD|. Licencias de este tipo son: * `Licencia BSD <https://es.wikipedia.org/wiki/Licencia_BSD>`_ usada por algunas distribuciones derivadas del UNIX |BSD| original como *FreeBSD* o *NetBSD*. * `Licencia MIT <https://es.wikipedia.org/wiki/Licencia_MIT>`_, creada en el |MIT| para licenciar el servidor gráfico :program:`X11`. Es la licencia más usada en Github_. * `Licencia Apache <https://es.wikipedia.org/wiki/Apache_License>`_, que es la licencia que usa la `Fundación Apache <https://es.wikipedia.org/wiki/Apache_Software_Foundation>`_ para sus productos. * `Licencia ISC <https://es.wikipedia.org/wiki/Licencia_ISC>`_ usada por el `ISC <https://es.wikipedia.org/wiki/Internet_Systems_Consortium>`_ para sus desarrollos (p.e. el servidor |DNS| :program:`bind`) o por la distribución *OpenBSD*. * `Licencia Beerware <https://es.wikipedia.org/wiki/Beerware>`_, licencia extremadamente permisiva que sólo anima al usuario a invitar al desarrollador a una cerveza si alguna vez se encuentra con él. - Licencias de tipo |GPL| (o licencias *copyleft*), en las que se prescribe que cualquier software derivado tiene que forzosamente cumplir las cuatro libertades y, por tanto, volver a ser |GPL|. A esta obligación de mantener la licencia es a lo que se denomina *copyleft*. Es la licencia que adopta la |FSF| en sus desarrollos pàra el proyecto |GNU| y a la que se acoge gran cantidad del *software* libre, aunque no pertenezca a este proyecto, como el núcleo de Linux. De la licencia |GPL| hay dos variantes fundamentales: * La `Licencia LGPL <https://es.wikipedia.org/wiki/GNU_Lesser_General_Public_License>`_, más permisiva que la |GPL| normal y que permite usar el *software* con esta licencia en un proyecto que no sea libre si se enlaza dinámicamente. Es apropiado para crear bibliotecas. * La `Licencia AGPL <https://es.wikipedia.org/wiki/GNU_Affero_General_Public_License>`_ que es más restrictiva que la |GPL| normal y obliga a entregar el código fuente al usuario, aunque no se le tenga que proporcionar una copia para que lo use. Un ejemplo típico, es el de un *software* de servidor: un *software* de servidor no es preciso proporcionárselo al cliente, si nosotros mismos le montamos el servidor. .. note:: Incluso Microsoft_ tiene `un par de licencias de software libre <https://es.wikipedia.org/wiki/Shared_source#Licencias_Libres/de_Fuente_Abierta>`_: la *Ms-PL* (Microsoft Public License) del corte de la |GPL| y la *Ms-RL* (Microsoft Reciprocal License) del corte de la *LGPL*. *Software* de código abierto ---------------------------- En 1998, nació la |OSI| como una escisión más pragmática del *software* que no aboga tanto por los aspectos filosóficos como por los tecnológicos. En los aspectos meramente funcionales pueden considerarse equivalentes. Los requisitos para que la |OSI| considere de código abierto un *software* son los expresados en este decálogo: #. Libertad de **uso sin discriminación de grupos o personas**. #. Libertad de **uso sin discriminación de áreas de iniciativa**. #. Un programa de código abierto no puede licenciarse únicamente como parte indisoluble de otro. #. La licencia no debe restringir la licencia de otro software, esto es, si el *software* se distribuye junto a otros no puede obligar a que estos otros sean también de *codigo abierto*. #. La licencia debe ser tecnológicamente neutral. #. Disponibilidad del **código fuente**. #. **Libre redistribución** del software. #. Los **derechos de distribución de la licencia** debe aplicarse a todos los que las redistribuyan sin necesidad de que estos requieran una licencia adicional. #. Libertad para poder generar **trabajos derivados**, #. Aunque se puede **limitar la redistribución** de estos trabajos derivados como meros parches que conserven la licencia original. Este decálogo desarrolla desde otro enfoque las cuatro libertades del *software* sobre las que se asienta la filosofía del *software libre*. .. warning:: No debe confundirse el *código abierto* con un *software* que, *simplemente* muestre su código fuente. *Software* privativo -------------------- Es el *software* que no es libre ni de *código abierto*. Dentro de este *software* hay modalidades de distribución muy utilizadas: **Freeware** Es simplemente software que se distribuye gratuitamente. **Shareware** Son versiones gratuitas de un *software* que se ofrecen para su evaluación, por lo que tienen alguna restricción (días de uso, tiempo continuado de uso, etc.). La característica fundamental de este *software* es que no está ser pensado para ser completamente funcional, sino sólo para permitir la evaluación del producto. **Crippleware** Son versiones amputadas de un *software*, por lo general gratuitas, que ofrecen una funcionalidad limitada frente a la versión completa. Suelen referirse como versiones *Lite*. La principal diferencia respecto al *shareware* es que estas versiones están pensadas para ser funcionales, aunque no ofrezcan todas las características. Por otro lado, atendiendo a quién sea el destinatario de la licencia se distingue: - La |EULA|, que es una licencia destinada a un único usuario. - |OEM| que es una licencia asociada al software incluido en un ordenador. Por ejemplo, si compramos un ordenador que tiene instalado un sistema *Windows*, este suele incorporar una licencia |OEM|. - Licencias corporativas o por volumen, que son licencias que se otorgan a usuarios de una misma empresa u organismo. Un ejemplo de esta licencia es la `Azure for Education <https://azure.microsoft.com/es-es/education/>`_, que ofrece Microsoft_ a instituciones académicas que imparten enseñanzas de informática. .. _C: https://es.wikipedia.org/wiki/C_(lenguaje_de_programaci%C3%B3n) .. _Pascal: https://es.wikipedia.org/wiki/Pascal_(lenguaje_de_programaci%C3%B3n) .. _Java: https://www.java.com/es/about/whatis_java.jsp?bucket_value=desktop-chrome76-linux&in_query=no .. _Python: https://www.python.org/ .. _Javascript: https://www.ecma-international.org/publications/standards/Ecma-262.htm .. _Github: https://github.com .. _Microsoft: https://www.microsoft.com .. |EULA| replace:: :abbr:`EULA (End-User Licencia Agreement)` .. |BSD| replace:: :abbr:`BSD (Berkeley Software Distribution)` .. |GPL| replace:: :abbr:`GPL (GNU Public Licence)` .. |FSF| replace:: :abbr:`FSF (Free Software Foundation)` .. |GNU| replace:: :abbr:`GNU (GNU is Not UNIX)` .. |MIT| replace:: :abbr:`MIT (Massachusetts Institute of Technology)` .. |OSI| replace:: :abbr:`OSI (Open SOurce Iniciative)` .. |OEM| replace:: :abbr:`OEM (Original Equipament Manufacturer)`