Este Archivo, la GitHub Code Vault, fue establecido por el GitHub Archive Program, cuya misión consiste en preservar el software de código abierto para generaciones futuras. Puede que estés leyendo esto dentro de un año, o de mil, pero de cualquier manera, esperamos que su contenido y quizás el propio concepto del código abierto, te sean útiles.
Se trata fundamentalmente de un archivo de software. El software son una serie de comandos utilizados para controlar las acciones de un ordenador. Un ordenador es un dispositivo que puede realizar automáticamente funciones matemáticas mucho más rápido que la mente humana y que tiene capacidades muy superiores a las nuestras. Nuestros ordenadores se utilizan para explorar los secretos del universo, para conectar a toda la humanidad en una red omnipresente de información, para manipular señales lo suficientemente rápido como para transmitir sonidos y proyectar imágenes detalladas en movimiento en pantallas eléctricas y para controlar maquinaria sumamente potente que supera con creces tanto la capacidad como la precisión del trabajo humano.
Un ordenador sin software no puede hacer ninguna de estas cosas. Un ordenador es algo extraordinario y maravilloso, pero sin software, toda su potencia no sirve para nada. El objetivo de este Archivo es transmitirte lo que sabemos sobre el software.
El software se escribe en secuencias de comandos complejas pero legibles para el hombre, cuyos diversos tipos se conocen como lenguajes de programación, ya que una unidad completa de software a menudo se denomina programa. Estos programas luego se pasan al lenguaje binario de unos y ceros utilizado por los ordenadores. Este proceso se llama compilación.
Debido a que es muy difícil descifrar el software compilado a su forma original de programa, también conocido como código fuente, la gente puede mantener esa forma original en secreto y reclamar su propiedad. El software de código abierto no es un tipo de software diferente, sino que tiene unos valores distintos. La filosofía del código abierto rechaza el secretismo y la propiedad. Los programas de software de código abierto se ponen a disposición de todas las personas que deseen usarlos, sin coste alguno, para que a su vez puedan mejorar esos programas o utilizarlos para crear algo nuevo y mejor.
Un proyecto de código abierto es el trabajo colectivo de una comunidad autogestionada formada por miles de usuarios. La recopilación de todos los proyectos de software de código abierto archivados aquí es el trabajo de una comunidad de varios millones de personas. Si bien ciertas personas pueden tener derechos especiales dentro de un proyecto determinado, como la capacidad de aprobar o rechazar los cambios sugeridos en la última versión oficial de su código fuente, nadie lo posee nunca. Todo el mundo tiene derecho a tomar y utilizar una copia completa de cualquier proyecto de código abierto en cualquier momento, sin coste o sanción. Esto es lo que se conoce como la bifurcación de un proyecto.
Cuando muchas personas trabajan en el código fuente al mismo tiempo, es difícil controlar e integrar todos sus cambios. Existe un proyecto de código abierto llamado "Git" dedicado a resolver este problema. Integra un historial completo de todas las adiciones y cambios de un proyecto en una entidad conocida como repositorio de Git. Este Archivo es básicamente un archivo de dichos repositorios.
Este Archivo ha sido creado por una empresa llamada "GitHub", que proporciona un servicio que permite a gente de todo el mundo almacenar los programas de software que han escrito, hacer un seguimiento de los cambios realizados en estos programas y colaborar con otros usuarios para mejorarlos y expandirlos. GitHub pone sus servicios a disposición de los desarrolladores de software público de código abierto de forma gratuita. Cuenta con decenas de millones de usuarios de este tipo.
Lo que sigue es una descripción de lo que creemos que se necesita saber y tener para hacer el mejor uso de este Archivo de software. Si no sabes o no entiendes algo, ¡no te desesperes! También hemos incluido una guía sobre cómo alcanzar estos requisitos. Si por alguna razón no podéis alcanzarlos vosotros mismos, podrán hacerlo vuestros descendientes.
En principio, lo único que se necesita para acceder al contenido de este Archivo es una fuente de luz y algún tipo de lupa. Sin embargo, la mayoría (aunque no todos) de sus datos han sido almacenados en bobinas de película en una forma cifrada y comprimida. Para leer, descifrar y descomprimir estos datos se requerirá una capacidad computacional considerable. En teoría podría hacerse sin ordenadores, pero sería una tarea muy tediosa y difícil.
Nuestra expectativa es que no necesites nuestras definiciones de software, ordenador y otros términos. Imaginamos que tendréis vuestros propios ordenadores, probablemente mucho más avanzados que los nuestros y posiblemente con una arquitectura fundamentalmente diferente. Una vez que entiendas la descripción general y la guía que figura a continuación, podrás acceder fácilmente a todos los datos.
Sin embargo, es posible que tengáis ordenadores inferiores a los nuestros o incluso que no tengáis ordenadores. Si se diera ese caso, hemos preparado una bobina de datos sin comprimir, sin cifrar y legible para los humanos a la que llamamos el Tech Tree (árbol tecnológico). El Tech Tree contiene información sobre nuestras tecnologías básicas, nuestros ordenadores y nuestro software, con la esperanza de que, con el tiempo, podáis utilizar estos conocimientos para reproducir ordenadores que puedan hacer uso del software de código abierto incluido en este Archivo.
El Archivo es tan grande -- aproximadamente 24 billones de bytes (explicado más abajo) -- porque es sumamente inclusivo y democrático. Muchos millones de personas ponen el software que escriben a disposición de todo el mundo. Este Archivo incluye una instantánea, es decir, una sola copia, en un único momento dado, de todo el software público que los usuarios de GitHub están desarrollando activamente. Esto significa que incluye decenas de millones de repositorios independientes. Esperamos que este enfoque amplio y democrático sea de interés para los historiadores del futuro.
Los repositorios incluidos en este Archivo se determinaron exclusivamente en función de la hora de su última confirmación, es decir, la última vez que fueron actualizados y su número de estrellas. (Todos los usuarios de GitHub pueden marcar con una estrella los repositorios públicos, para indicar que les resultan interesantes o relevantes). La instantánea se inició el 02/02/2020, es decir, el segundo día del mes de febrero, en el año 2020 del calendario gregoriano, que utilizamos para medir el tiempo. Los repositorios incluidos en él son: todos los repositorios con confirmaciones en los 80 días anteriores; todos los repositorios con al menos una estrella con confirmaciones en los 365 días anteriores; y todos los repositorios con al menos 250 estrellas, sin tener en cuenta cuándo se actualizaron por última vez.
Obviamente, no todos estos repositorios tienen la misma importancia en términos de influencia y dependencias. El Tech Tree incluye un índice y una breve descripción de los repositorios más importantes del Archivo e indica en qué bobina se puede encontrar cada uno, de modo que se pueda acceder a ellos sin tener que revisar millones de repositorios para determinar cuáles son más útiles en la práctica.
El Archivo consta de 201 bobinas de película: una "bobina guía" legible por el ser humano de información y orientación y 200 bobinas de software archivado. Cada bobina incluye 65.000 fotogramas individuales. Los fotogramas al comienzo de cada bobina y los fotogramas de la bobina guía incluyen texto e imágenes legibles por los humanos. El resto de fotogramas de la película contienen datos digitales almacenados en una forma visual conocida como código QR.
Por datos digitales se entiende datos almacenados en última instancia en formato binario, es decir, como 0 y 1, ya que los propios ordenadores son binarios -- controlados por señales eléctricas que están "encendidas" o "apagadas", lo que corresponde a 1 o 0 -- por lo que los datos binarios son mucho más fáciles de entender para los ordenadores que cualquier otro tipo de datos.
Los metadatos legibles por el ser humano que se almacenan al principio de cada bobina incluyen información sobre la propia película, una guía sobre la codificación QR utilizada, un programa de software para decodificarla y un índice. El índice contiene el título, el número del fotograma inicial y la suma de comprobación de cada archivo almacenado en esa bobina.
Un archivo es una entidad de datos única y coherente. Una suma de comprobación es un valor único que se obtiene a partir de un cálculo, conocido como función hash, que se ejecuta sobre todo el contenido de un archivo para garantizar que su contenido no haya sido dañado. La función hash utilizada en el Archivo se conoce como "SHA-1".
Cada código QR se compone de un campo de pequeños cuadrados blancos o negros que ocupan casi todo el fotograma de la película. Utilizamos los códigos QR porque son mucho más compactos y robustos que el texto legible por los humanos. Un código QR se decodifica en datos binarios, es decir, una serie de unos y ceros.
Esta decodificación es solo el primer paso para convertir esos datos binarios en información con sentido. Se trata de datos comprimidos, lo que quiere decir que han sido compactados para ahorrar espacio, de forma similar a escribir "128xA" en vez de escribir la letra A 128 veces. Después de decodificarlos, hay que descomprimirlos.
El resultado tras la descompresión se conoce como archivo de almacenamiento: un único archivo que incluye todo el contenido del repositorio de un determinado proyecto de software. La mayoría de los repositorios incluyen muchos archivos, por lo que este archivo de almacenamiento es como un libro que tiene muchos capítulos distintos o una caja que contiene muchas otras cajas. Por lo general, es conveniente, aunque no es absolutamente necesario, desempaquetar el archivo de almacenamiento en los archivos que lo componen antes de acceder a ellos.
Finalmente, cada archivo componente constituye su propio conjunto de datos binarios, es decir, unos y ceros. Se puede dar sentido a los datos si se conoce su formato. Por ejemplo, en el formato conocido como "UTF-8", el formato más común en el Archivo, los unos y los ceros se dividen en grupos de ocho, conocidos como bytes, el byte 01000001 representa la letra A; los tres bytes 01101001 01101110 01110100 representan la palabra int y los dos bytes 11000011 10000011 representan la letra à (A con un acento en la parte superior).
Este proceso de archivado de datos, archivos binarios empaquetados en archivos de almacenamiento que han sido previamente comprimidos y luego codificados mediante QR, es claramente complejo comparado con el simple hecho de escribir un texto legible por los humanos. El proceso inverso por el que tendrás que pasar -- QR a binario comprimido; comprimido a descomprimido; archivo de almacenamiento a múltiples archivos; archivos de texto a texto legible por el ser humano -- es igualmente complejo. Esto se debe a que esta complejidad nos permite almacenar muchos más datos de los que se podrían almacenar de otro modo, en una forma relativamente fácil de leer para un ordenador.
Si esta complejidad te resulta difícil y costosa, te pedimos disculpas, pero esperamos que, de ser así, esta guía y el Tech Tree legible por el hombre alivien esta complejidad y quizás te sean más útiles que el contenido del Archivo, al menos hasta que vuestros ordenadores hayan avanzado lo suficiente como para que la complejidad de los datos del Archivo se pueda abordar con facilidad.
Puede que resulte educativo examinar cómo se divide lógicamente el Archivo. En concreto, será útil que analicemos los archivos, directorios y formatos de datos.
Un archivo es una colección de datos agrupados en una entidad coherente con un solo nombre: imaginemos que los datos son arena y un archivo es una especie de bolsa que puede contener arena y solo arena. Un directorio es una recopilación de archivos: sería como una bolsa que solo puede contener otras bolsas. Siguiendo esta metáfora, todos los repositorios constan de un directorio externo, conocido como el directorio raíz, que contiene un determinado número de archivos y/o un determinado número de directorios. Cada directorio puede, a su vez, contener tanto archivos como directorios.
Se prefiere esta estructura porque resulta mucho más sencillo trabajar con archivos organizados en grupos que con un único conjunto de archivos. El identificador de un archivo concreto dentro del directorio externo está formado por los nombres de todos sus directorios anexos, empezando por la raíz, seguido de su propio nombre individual, con el carácter / entre cada nombre. Por ejemplo, un archivo llamado README.md en el directorio raíz se identificaría como /README.md y un archivo identificado como /public/www/index.html sería el archivo index.html en el directorio "www" dentro del directorio "public" dentro del directorio raíz.
Cada repositorio tiene a su vez dos nombres, separados por un divisor, que en el Archivo es un _ o el carácter de guion bajo. (Históricamente ha sido el carácter / o barra diagonal, pero este también se utiliza para indicar un directorio, por lo que usamos _ para mayor claridad). El primer nombre es la cuenta de GitHub propietaria de ese repositorio; el segundo es el nombre del repositorio concreto. La combinación de los identificadores del repositorio y del fichero se puede utilizar para identificar de manera única un fichero individual en el Archivo. Por ejemplo, el fichero "package.json" en el directorio "web" en el repositorio "ykarma" dentro de la cuenta de GitHub "rezendi" podría identificarse de forma única como /web/package.json en rezendi_ykarma en el Archivo.
Diferentes tipos de archivos tienen diferentes fines. El Archivo de GitHub está formado en gran parte por archivos de texto, es decir, archivos cuyos datos representan el lenguaje escrito. La mayoría de los programas de software se escriben en archivos de texto que contienen un texto altamente estructurado conocido como código fuente. Un programa especial llamado compilador convierte ese código fuente legible por el hombre en instrucciones legibles por el ordenador conocidas como código compilado o código máquina.
Los archivos que no son de texto, como los que representan imágenes visuales o contienen código compilado, suelen denominarse archivos binarios. Se trata, desafortunadamente, de un término engañoso, ya que los archivos de texto son también, en última instancia, 1 y 0. Nos referiremos a los archivos que no son de texto como archivos no textuales.
Existen muchas formas de representar el lenguaje humano escrito usando 1 y 0. Por razones históricas, la mayor parte del código fuente se escribió originalmente en lo que se conoce como el alfabeto latino. El alfabeto latino se compone de 26 caracteres básicos que se utilizan para representar palabras habladas, cada uno de los cuales tiene dos formas, mayúscula y minúscula. También cuenta con 10 dígitos para representar los números. El alfabeto latino, junto con otros símbolos asociados empleados para indicar la estructura y otros conceptos, está codificado en 1 y 0 en un formato conocido como "ASCII", que puede representar 128 caracteres diferentes y por razones históricas fue predominante en la mayoría de los programas informáticos durante muchos años.
Sin embargo, el alfabeto latino es solo un pequeño subconjunto de las muchas maneras en las que los humanos se expresan por escrito. Para respaldar otros scripts y al mismo tiempo permitir que todo el software que había sido escrito para usar ASCII siguiera funcionando sin cambios (un concepto conocido como retrocompatibilidad), se introdujo otro formato de datos llamado "UTF-8".
El ASCII sigue siendo el formato más común de código fuente. Todas las bobinas de este Archivo incluyen una guía de los caracteres ASCII. ASCII es un subconjunto de UTF-8, lo que significa que todas las codificaciones ASCII son también codificaciones UTF-8. La bobina guía además contiene una especificación de todos los caracteres UTF-8. Casi todos los archivos de texto de este Archivo deberían estar codificados en UTF-8.
Los archivos no textuales incluyen archivos destinados a representar imágenes y documentos con formato. Una convención ampliamente utilizada consiste en que un archivo termine con un carácter "." seguido de un sufijo que indica su tipo. Por ejemplo, un archivo que termina con .jpg probablemente sea un archivo de imagen JPEG; uno que termina con .PNG es probable que sea un archivo de imagen Portable Network Graphic (gráfico de red portátil); y uno que termina con .pdf un archivo Portable Document Format (formato de documento portátil).
No hay un único sufijo para los archivos de texto. De hecho, en el caso del código fuente, es más probable que el sufijo indique en qué lenguaje de programación o de marcado está escrito el código. Los lenguajes de programación y de marcado se describirán con más detalle a continuación.
Aquí proporcionaremos un resumen de cómo desempaquetar un repositorio archivado concreto para acceder a sus diversos archivos constituyentes. De nuevo, este proceso consiste en:
-
Identificar la bobina y los fotogramas específicos en los que están archivados los datos del repositorio.
-
Decodificar a partir de los códigos QR, los campos de píxeles negros, blancos y grises en esos fotogramas, en un archivo binario, una secuencia de (al menos miles y a menudo millones de) unos y ceros.
-
Descomprimir el archivo binario para obtener un archivo más largo y sin comprimir.
-
Desempaquetar el archivo de almacenamiento para obtener los subarchivos independientes que contiene. Hay que tener en cuenta que, por lo general, los datos archivados son comprensibles, aunque estén desordenados, incluso si se omite este paso.
-
Por último, convertir cada uno de esos archivos secundarios -- a su vez secuencias de 1 y 0 cuya longitud varía de muy corta a muy larga -- en caracteres escritos, si se trata de archivos de texto.
Identificación de la bobina y los fotogramas específicos en los que están archivados los datos del repositorio
Cada bobina de película comienza con un fragmento de película guía en blanco, seguido del fotograma de referencia cero, que consiste en un rectángulo sólido negro en una esquina del fotograma por lo demás vacío. El siguiente fotograma legible por el ser humano es el fotograma de control, que contiene información sobre la bobina. A continuación se encuentra la Tabla de contenido, que a su vez incluye una lista de los archivos de datos del usuario.
Cada repositorio de esta bobina es uno de esos archivos de datos del usuario. La lista incluye un ID único, un ID de archivo y un nombre para cada uno de esos archivos. Por ejemplo, en el repositorio CPython de la cuenta Python el ID de archivo podría aparecer como 12345 y el nombre como python_cpython.tar.
A la lista de archivos de datos del usuario le sigue una lista de ubicaciones de datos digitales. Esta lista incluye el ID de archivo, un fotograma inicial, un byte inicial, un fotograma final y un byte final. Así que, usando el ejemplo hipotético de CPython, el elemento de esta lista con el ID 12345 podría tener un fotograma inicial de 054321, un byte inicial de 03210321, un fotograma final de 054545 y un byte final de 12321232.
Esto quiere decir que para obtener los datos de CPython hay que: Ir al fotograma 54321 de esta bobina de película. Decodificar todos los fotogramas desde el fotograma inicial, 54321, hasta el fotograma final, 54545, en valores binarios, según se describe a continuación. Esto te dará 225 fragmentos de datos numerados del 54321 al 54545, que comenzarán con un conjunto de fragmentos en blanco sin datos. Descarta los primeros 3210320 bytes del primer fragmento de datos que no esté en blanco. Junta todos los fragmentos de datos "centrales", en orden. Por último, junta los primeros 12321232 bytes del último fragmento de datos, 54545. Acabas de montar el repositorio completo de CPython, como un único archivo comprimido.
Los detalles sobre cómo decodificar los fotogramas de la película en datos binarios se encuentran en la Información de representación legible por el ser humano que sigue a la Tabla de contenido al principio de cada bobina de película en el Archivo. Esta información se encuentra en todas las bobinas, de modo que, aunque una bobina individual se separe del Archivo, seguirá siendo posible descifrar su contenido. Esa información de representación incluye, en orden:
-
Guía del GitHub Archive Program (este documento)
-
Índice descriptivo de GitHub, una lista y una breve descripción de todos los repositorios de esta bobina
-
Descripción de la Información de representación
-
Preservación digital y cómo recuperar los datos, una visión general de los detalles de la recuperación de datos
-
Descripción del medio de almacenamiento
-
Tecnología de recuperación de datos
-
Estructura de la bobina de preservación genérica (formato de la bobina)
-
Descripción del formato de fotogramas 4K genérico
-
Descripción de la biblioteca de desempaquetado (para los códigos QR)
-
Código fuente de la biblioteca de desempaquetado
-
Especificaciones del formato de datos ASCII
-
Especificaciones del lenguaje de programación C
-
Código fuente del archivo de almacenamiento TAR
-
Código fuente del PDF
-
Especificaciones del formato de archivo XZ (para compresión / descompresión, descrito a continuación)
El sexto de esos elementos, el documento sobre la Tecnología de recuperación de datos, describe los requisitos y procesos necesarios para utilizar un escáner a fin de capturar los datos de un único fotograma de película codificado digitalmente y pasarlos a una forma apta para el análisis informático. El octavo de ellos, la Descripción del formato de fotogramas 4K genérico, proporciona la información técnica, incluido el código fuente, necesaria para que un ordenador tome esa imagen escaneada y la convierta en datos binarios.
En principio, es teóricamente posible convertir un repositorio de datos codificados en QR en datos binarios sin utilizar un ordenador. Sin embargo, sería sumamente difícil y probablemente requeriría un esfuerzo considerable por parte de una comunidad bien organizada durante muchas semanas, si no meses o años. Dado que el contenido de los repositorios es software destinado a ser ejecutado en un ordenador, su uso en ausencia de un ordenador sería mínimo en el mejor de los casos.
En el supuesto de que los herederos de este Archivo no tengan ordenadores, deben mantener el archivo íntegro y protegido hasta que dispongan de ellos. Uno de los propósitos del Tech Tree legible por los humanos es ayudar a acelerar el desarrollo de las tecnologías y los ordenadores en caso de producirse esta eventualidad. (Su otro propósito es codificar nuestra tecnología y su desarrollo para los historiadores del futuro).
Desempaquetado del archivo de almacenamiento para obtener los subarchivos independientes que contiene
El archivo binario de cada repositorio se encuentra en un formato conocido como TAR, de Tape Archive. Un archivo TAR está compuesto esencialmente por la agrupación de varios archivos, conectando el final de uno con el principio del siguiente, como si pegáramos con cinta adhesiva trozos de papel individuales para formar un único rollo. Un archivo TAR puede incluir cualquier número de archivos, de cualquier tamaño, divididos en un número cualquiera de directorios y subdirectorios.
Todos los subarchivos dentro de un archivo TAR van precedidos de un registro de encabezado de 512 bytes, que actúa como la cinta adhesiva en la metáfora del rollo de papel. Este registro de encabezado contiene información sobre el archivo, como su nombre y tamaño. El final del Archivo está indicado por al menos dos bloques consecutivos de 512 bytes.
Como los archivos TAR son básicamente colecciones de archivos con registros de texto entre ellos, si un archivo TAR solo contiene archivos de texto, puede tratarse como un archivo de texto propiamente dicho. Si contiene una mezcla, puede tratarse como un archivo de texto que contiene una mezcla de texto estructurado y con sentido (los archivos de texto constitutivos) y un galimatías incomprensible (los archivos no textuales constitutivos).
Es posible anidar archivos TAR dentro de archivos TAR, un contenedor dentro de otro y así es como se almacenan la mayoría de nuestros datos archivados. Para cualquier repositorio dado, el archivo TAR externo contendrá al menos:
- un único archivo de metadatos sin comprimir llamado META, que incluye el nombre del repositorio, el nombre de la cuenta, la descripción, el lenguaje, el número de estrellas y el número de bifurcaciones
- un archivo comprimido (ver abajo) llamado COMMITS, que incluye el registro de los cambios realizados en el repositorio a lo largo del tiempo
- un archivo llamado repo.tar.xz, un archivo TAR comprimido que recoge el contenido propiamente dicho del repositorio
Otros metadatos, como wikis, páginas de GitHub (gh-pages), problemas y solicitudes de extracción también pueden incluirse como archivos comprimidos independientes.
Los detalles específicos de los archivos TAR y el software para codificarlos y decodificarlos se pueden encontrar en la Información de representación en todas las bobinas del Archivo.
Con el fin de incluir el mayor número de repositorios y la mayor cantidad de datos posible, la mayoría de los datos han sido comprimidos. La compresión consiste en utilizar una pequeña cantidad de datos para representar una cantidad mayor, mediante el uso de patrones y repeticiones en esa cantidad mayor. Por ejemplo, en lugar de escribir el carácter a nueve veces seguidas, se podría escribir el texto comprimido 9a, si se tiene la seguridad de que el lector entenderá que 9a representa el texto sin comprimir aaaaaaaaa.
Los algoritmos de compresión eficaces son mucho más complejos que eso, pero se aplica el mismo principio. Este Archivo utiliza un programa de compresión conocido como "XZ", que a su vez utiliza un algoritmo llamado "LZMA". El segundo archivo de datos de cada bobina contiene el código fuente y la documentación de XZ en un único archivo TAR sin comprimir, que se describe a continuación. (El primer archivo de datos contiene la Declaración Universal de los Derechos Humanos en todos los idiomas humanos escritos existentes).
El LZMA combina lo que se conoce como el algoritmo "LZ77" y el "rango de codificación". El LZ77 sustituye los datos repetidos con referencias a apariciones anteriores de esos datos. Por ejemplo, simplificando sobremanera, si una frase de 80 bytes aparece dos veces, separadas por 400 bytes, la segunda vez el algoritmo básicamente compacta los datos diciendo "repetir los 80 bytes de hace 400 bytes". El rango de codificación esencialmente convierte un mensaje entero en un solo número muy largo, que a su vez se puede codificar.
Los pasos específicos del algoritmo que se utilizan para descomprimir los datos se describen en el código fuente de XZ contenido en el segundo archivo de datos de todas las bobinas. Aunque en teoría es posible realizar la descompresión a mano, como ya hemos dicho, sería un proceso extremadamente intensivo en cuanto a tiempo y mano de obra. En la práctica, se necesitaría un ordenador operativo.
A lo largo de los milenios, la humanidad ha utilizado muchos caracteres escritos. La codificación empleada para representar estos caracteres como 1 y 0 dentro de este Archivo se conoce como "UTF-8". Un único carácter UTF-8, es decir, un único símbolo escrito, puede ocupar de 1 a 4 bytes de datos binarios.
Por razones históricas, ya que eran los más utilizados en la época y la región en la que comenzó el desarrollo de software, un grupo de caracteres (y conceptos) conocidos como "ASCII" se codifican de manera más eficiente, a 1 byte por carácter. Todo lo que no es ASCII se codifica como 2 o más bytes por carácter. La mayoría de los archivos de texto de este Archivo son ASCII, pero un número considerable de ellos no lo son. Muchos más son mayormente ASCII con caracteres no ASCII ocasionales.
Las especificaciones detalladas del ASCII se pueden encontrar en la Información de representación en todas las bobinas del Archivo. Las especificaciones detalladas del UTF-8 se pueden encontrar en la bobina guía. El primer archivo de datos de cada bobina del Archivo contendrá el texto de la Declaración Universal de los Derechos Humanos en todos los idiomas humanos escritos existentes. Esto servirá como herramienta de traducción y como ejemplo de ASCII y UTF-8.
Existen muchos tipos diferentes de archivos de texto, creados por diferentes razones. El tipo principal aquí, la razón por la que existe este Archivo, es el código fuente. El código fuente es muy denso, un texto sumamente estructurado, en el que símbolos como "{" y ";" tienen gran importancia.
La clave del código fuente es que está escrito para ser leído por los compiladores. Como los compiladores son programas informáticos, otra forma de decir esto es que el código fuente está escrito para ser leído por ordenadores. Un buen código también está escrito para que otros humanos, si tienen las habilidades necesarias y están formados en el campo del software, puedan entenderlo; pero solo es correcto si puede entenderlo un compilador.
Ese compilador, a su vez, a través de complicadas secuencias descritas en el Tech Tree, convertirá el código fuente en las secuencias de unos y ceros que harán que el ordenador realice las funciones y actividades descritas por el código. Para poner un ejemplo muy simple, la línea de código
para (int i=0; i<5; i++) { }
será convertida por el compilador en una serie de instrucciones binarias que se suministran al ordenador, lo que hará que una pequeña parte del mismo, llamada registro, establezca su valor en 0 y posteriormente incremente ese valor a 1, 2, 3 y luego a 4. (Esto no pretende ser un ejemplo de código útil; es solo una ilustración del proceso de múltiples capas que convierte el código fuente en software funcional).
Otros tipos de archivos de texto, como el JSON, XML y HTML, se utilizan para almacenar datos (en lugar de comandos) para los ordenadores. Por lo general, también son legibles para los humanos, aunque sus formatos estructurados los hacen más difíciles de leer que un texto narrativo menos estructurado como este archivo.
La mayor parte de los otros tipos de archivos de texto están destinados a ser leídos por los humanos en última instancia. Algunos son simples, en su mayor parte texto no estructurado, como este archivo que estás leyendo actualmente. Un tipo que encontrarás con frecuencia en el Archivo es Markdown, indicado por la extensión .md que se añade a los archivos, que es una especie de forma intermedia destinada a ser leída por los humanos en su forma original y también, al mismo tiempo, estructurada para que los ordenadores puedan darle formato y crear diseños más útiles y atractivos visualmente. La mayoría de los repositorios de este Archivo tienen un archivo Markdown README.md, que suele ser una introducción inicial al repositorio, en la que se describe qué es, por qué existe y cómo utilizarlo.
También puede resultar útil un breve resumen de las formas más comunes de archivos no textuales. El código compilado es no textual. Los archivos JPG y PNG codifican las imágenes en formato digital y los MP3 y WAV codifican audio. Los archivos PDF codifican los documentos con un formato preciso y perfecto. Y los archivos ZIP y TAR, como se mencionó anteriormente, son archivos contenedores que a su vez pueden incluir muchos otros archivos.
Hoy en día, la humanidad utiliza miles de lenguajes escritos y aún más lenguas habladas. La mayoría de ellos los utilizan solo poblaciones pequeñas, pero existen por lo menos veinte idiomas utilizados como primera o segunda lengua por al menos 60 millones de personas.
Los idiomas más utilizados en el mundo son el inglés y el chino. Por razones históricas, durante muchos años la mayor parte del desarrollo informático tuvo lugar en países de habla inglesa, por lo que durante un tiempo, el inglés se convirtió en el idioma por defecto del software. La gran mayoría de los lenguajes de programación utilizan palabras en inglés en su sintaxis. Es el idioma en el que se escribió por primera vez esta guía del Archivo.
No está garantizado que los herederos de este archivo sepan inglés, aunque parece bastante probable que sea un idioma que dure indefinidamente. En caso de que sea útil alguna orientación a otros idiomas, incluimos las más de 500 traducciones disponibles de la Declaración Universal de los Derechos Humanos como un archivo UTF-8 sin comprimir al comienzo de cada bobina y también dentro del Tech Tree. Esta declaración recoge un listado de los derechos y libertades de todos los seres humanos en nuestra era, que nunca deben ser arrebatados.
Los lenguajes de programación son los que usan los humanos para comunicar instrucciones a los ordenadores. Son los lenguajes en los que se expresa el software. Otros humanos (formados) también deberían de ser capaces de leer el software escrito en lenguajes de programación, pero ese es un objetivo secundario.
Un lenguaje de programación es un conjunto de elementos predefinidos, la mayoría de ellos palabras, que pueden organizarse de manera estructurada para pedir a un ordenador que realice la acción especificada de la manera especificada. Una colección de tales instrucciones se conoce como programa o como código fuente. El código fuente es básicamente un programa informático en forma escrita y congelada.
Por lo general, los programas se dividen en pasos independientes, llamados sentencias, que a su vez se agrupan en colecciones denominadas funciones. Un programa entero puede estar contenido en un único archivo o puede estar repartido entre miles.
Existen cientos de lenguajes de programación diferentes, con muchas formas, enfoques y filosofías distintas. Algunos se compilan en archivos binarios individuales, que luego se ejecutan; otros, conocidos como lenguajes "interpretados", se compilan y se ejecutan de una vez, sin ninguna etapa intermedia. La mayoría de los lenguajes modernos incluyen bibliotecas de funciones ya escritas y dichas bibliotecas pueden llegar a ser muy voluminosas y elaboradas. Algunos de los lenguajes de programación más populares hoy en día son:
-
C, uno de los lenguajes más antiguos y rápidos, más universales y más potentes, simple en algunos aspectos pero bastante limitado en otros y no siempre intuitivo, fácil de leer o de aprender.
-
C++, una evolución más compleja, abstracta y potente de C.
-
C#, una evolución posterior compilada no en código máquina binario sino en un "runtime" interpretado.
-
Java, que es similar (pero anterior) a C#, es quizás el lenguaje más utilizado hoy en día.
-
JavaScript, muy diferente de Java a pesar de la similitud de su nombre, también conocido como "ECMAScript", es un lenguaje inicialmente utilizado en su totalidad dentro de un navegador web, es decir, un programa que buscaba, interpretaba y mostraba datos desde un ordenador remoto conocido como servidor de Internet; hoy en día, sin embargo, se utiliza también de manera generalizada en esos servidores.
-
TypeScript, una forma de JavaScript con reglas más estrictas para que los errores, también conocidos como bugs, tengan menos probabilidades de acabar en los programas.
-
Python, un lenguaje elegante popular entre científicos, potente e ideal como primer lenguaje.
-
Ruby, un lenguaje intuitivo cuyas sentencias a menudo se leen prácticamente como el inglés escrito.
-
Go, un lenguaje simple y potente que destaca especialmente en los programas paralelos, es decir, programas escritos de tal manera que ejecutan múltiples funciones de forma independiente al mismo tiempo.
-
Swift, un nuevo lenguaje utilizado para escribir para los teléfonos y otros dispositivos usados por mil millones de personas.
-
Rust, concebido como un sustituto de C, que reduce la probabilidad de que haya bugs peligrosos.
-
PHP, un lenguaje sencillo utilizado para los servidores de Internet.
-
Lisp, un lenguaje muy antiguo con un enfoque de la programación completamente diferente, centrado en las funciones.
-
SQL, un tipo de lenguaje muy diferente empleado para obtener datos de almacenes de datos estructurados y muy eficientes conocidos como bases de datos.
-
Ensamblador (o assembly), una familia de lenguajes muy crípticos, limitados, pero rápidos y potentes, en los que existe una relación directa entre las construcciones del lenguaje y el código máquina del ordenador en cuestión; puede considerarse código semicompilado.
El proceso de tomar un único y simple archivo de código fuente para convertirlo en impulsos eléctricos dentro de un ordenador es extremadamente complejo. Gestionamos esta complejidad usando capas de abstracción. Una abstracción conocida como un conjunto de instrucciones permite utilizar el resultado en código máquina de un único compilador en muchos tipos diferentes de ordenadores. Por lo general, el autor del código fuente no tiene que conocer o preocuparse por el tipo de ordenador, ni siquiera por el conjunto de instrucciones que se emplearán para ejecutar ese código; esto lo abstrae el compilador.
El software moderno es, a su vez, mucho más complejo que un solo autor trabajando en un solo programa para un solo ordenador. Consiste en que muchos autores trabajen en muchos archivos dentro de un mismo proyecto, simultáneamente, a menudo utilizando múltiples lenguajes de programación. Además, cada proyecto depende de otros proyectos independientes y autónomos como herramientas y/o componentes, mientras se trabaja activamente en estos proyectos que a su vez dependen de otros proyectos totalmente diferentes. Conseguir que todas estas partes en movimiento funcionen conjuntamente de forma elegante y eficiente es el verdadero reto del desarrollo de software moderno.
Cuando varios autores de código fuente, también llamados desarrolladores de software, trabajan en un único proyecto, cada uno tiene su propio ordenador y una copia del proyecto entero en su ordenador. Si cada uno de ellos realiza cambios, entonces cada uno tiene una versión diferente del mismo proyecto. El proceso de conciliación de múltiples versiones de un proyecto se conoce como control de versiones. Es administrado por el software de control de versiones; en este Archivo, por un software llamado Git, del que el propio GitHub toma el nombre. Todos los repositorios de este Archivo son repositorios de Git.
Git puede fusionar automáticamente diferentes versiones de software en una única forma coherente y necesita una cantidad mínima de intervención humana. Git también dispone de un historial completo que permite volver a una versión anterior siempre que sea necesario. Sin embargo, para ahorrar espacio, los repositorios de este Archivo por lo general no incluyen los historiales de Git.
Cuando varios desarrolladores llevan un proyecto por muchos caminos diferentes de forma simultánea, hablamos de la ramificación de un proyecto y esos caminos se denominan ramas. La rama principal acordada de un proyecto se conoce como el tronco o la rama maestra. Git ofrece una herramienta que los desarrolladores pueden utilizar para resumir las diferencias entre dos ramas y proponer la unión de la suya con el resto. Esto es lo que se conoce como una solicitud de extracción. El desarrollo de software moderno consiste en gran medida en ramificar un proyecto, escribir o editar el software en tu rama y, una vez terminado, presentar una solicitud de extracción para que tu trabajo se vuelva a incorporar a la rama maestra.
Básicamente, todos los lenguajes de programación permiten aprovechar el trabajo de los demás. Sin reutilizar el trabajo de los demás, los proyectos serían muchísimo más difíciles y extremadamente lentos y cada vez menos proyectos verían la luz en el mundo real.
Si el proyecto A tiene que incluir al proyecto B para poder funcionar, entonces se dice que A es dependiente del proyecto B y B es una dependencia del proyecto A. A puede tener muchas dependencias, cada una de las cuales puede tener múltiples dependencias propias y así sucesivamente. Además, cada dependencia corresponde a una versión concreta, o rango de versiones, de un proyecto determinado. El desglose completo de todas las capas de dependencias de un proyecto se conoce como su árbol de dependencias.
Normalmente, las dependencias se detallan dentro de los archivos del código fuente, por lo general en la parte superior y cada vez que el compilador o intérprete encuentra una dependencia, la busca en un conjunto de directorios predefinidos. Dado que el árbol de dependencias de un proyecto puede ser muy complejo, a veces se presenta en su totalidad en un único archivo dentro del proyecto conocido como lista de paquetes. Por ejemplo, los proyectos en Ruby pueden tener un Gemfile para este fin y los proyectos en JavaScript pueden tener un archivo package.json. Esto permite a los sistemas de gestión de paquetes obtener todas las dependencias de un proyecto de una sola vez, desde uno o más servidores de Internet.
En el caso de este Archivo, es probable que las dependencias de cualquier proyecto dado se encuentren en otra parte del Archivo. Para encontrar una dependencia en el Archivo, primero hay que averiguar el nombre de la dependencia en el código fuente o en la lista de paquetes, cuyos detalles concretos varían en función del lenguaje y del marco de trabajo y después hay que utilizar el índice maestro de la bobina guía o, en su defecto, los índices al comienzo de cada bobina, para determinar en qué bobina y en qué fotograma(s) se encuentra el repositorio en cuestión.
Dado que para ejecutar un programa en un ordenador solo se necesita el código máquina compilado, es posible distribuirlo manteniendo el código fuente en secreto. Esto se conoce como el modelo de código cerrado. Durante los inicios de la informática, el código fuente se solía distribuir junto con su código máquina, pero posteriormente, a medida que el software se convirtió en una industria lucrativa, el modelo de código cerrado empezó a ser cada vez más común.
Desde entonces se ha comprobado que hacer público el código fuente, para que quien quiera lo copie, ramifique y mejore, es un enfoque mucho más eficaz para el desarrollo de software. Cuanta más gente pueda leer el código fuente de un proyecto, más gente podrá identificar posibles necesidades y características nuevas útiles, más gente entenderá el proyecto lo suficiente como para contribuir, más gente detectará errores y enviará correcciones y más gente podrá probar y verificar que el código nuevo funciona.
En general, el código cerrado conduce a comunidades más pequeñas, aisladas y fragmentadas con dificultades para encontrar y adoptar nuevas y mejores ideas. El código abierto fomenta el desarrollo de grandes comunidades interconectadas, que se ayudan mutuamente para que sus proyectos crezcan, prosperen y tengan éxito, utilizando los trabajos de los demás como dependencias y/o reutilizando su código y aprendiendo los unos de los otros. El software de código abierto constituye un conjunto de herramientas para el uso colectivo de toda la humanidad y cuantas más y mejores herramientas tengamos, más rápido y mejor progresaremos como especie.