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)`