Nix Flakes y las funciones equivalentes en Guix
(coopi.neocities.org)- Nix Flakes agrupa las dependencias del proyecto, el bloqueo, el esquema de salidas y el entorno de desarrollo alrededor de
flake.nixyflake.lock, mientras que Guix ofrece el mismo tipo de funciones mediante una combinación de herramientas ortogonales como channels, manifests,guix describe,guix shellyoperating-system - Flakes fija las dependencias con
inputspor proyecto y unflake.lockautomático, mientras que Guix construye entornos reproducibles conguix describepor usuario,channels.scmcon commits anotados en el proyecto yguix time-machine - La pureza se impone en Flakes mediante restricted evaluation, mientras que en Guix se logra por diseño a través de la estructura de módulos de Scheme, entradas explícitas y contenedores de compilación aislados
- En cuanto a la estructura de salidas, Flakes ofrece attrsets estándar como
packages,devShellsynixosConfigurations, mientras que Guix usa registros y archivos transparentes de Scheme como<package>, manifest,operating-systemy service, que cada comando consume directamente - El criterio de elección es que si prefieres un único punto de entrada y un esquema estándar, Flakes encaja mejor; si prefieres combinar herramientas pequeñas e independientes, Guix se ajusta mejor
Comparación clave
- No existe una sola función de Guix equivalente a un Nix flake; mientras Nix Flakes resuelve varios problemas con una gran función unificada, Guix responde con una combinación de herramientas más pequeñas y ortogonales
- Guix reutilizó el daemon de Nix y comparte los componentes en C++ encargados del aislamiento de compilación y la gestión del store
- Guix reimplementa desde cero en Guile Scheme la mayor parte de lo que está por encima del daemon de Nix, como el lenguaje, las definiciones de paquetes y el sistema de servicios
- Guix y Nix comparten el formato de derivación ATerm y el linaje del daemon, pero la estructura por encima del daemon está organizada a la manera propia de Guix
- Guix tiene las capacidades que ofrecen Flakes, pero las presenta de una forma distinta
Estructura básica de un Nix Flake
- Un Nix flake es un árbol de código fuente con un archivo
flake.nixen la raíz, normalmente en forma de repositorio Git - La presencia de
flake.nixconvierte al árbol de código fuente en un flake, y el archivo tiene una estructura con elementos comodescription,inputsyoutputs descriptiones una cadena legible por humanos que indica lo que ofrece el flakeinputsdeclara dependencias como otros flakes, repositorios Git o tarballs; Nix las obtiene, las evalúa y luego las pasa a la funciónoutputsoutputses una función que recibe los inputs resueltos y un input especialself, y devuelve un attrset estructurado con paquetes, shells de desarrollo, configuraciones de NixOS, overlays y más-
Estructura de ejemplo y objetivos de ejecución
- En el ejemplo,
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";dentro deinputssignifica que se toma la ramanixos-unstabledel repositorioNixOS/nixpkgsen GitHub - El flake de ejemplo usa
supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];ynixpkgs.lib.genAttrspara generar salidas para varias arquitecturas de CPU - Flakes requiere el nivel
packages.<system>y, en el ejemplo, el paquetedefaultbajopackagesse define conpkgs.buildGoModule src = ./.;indica que se usa todo el repositorio Git como código fuentedevShellsdefine los shells de desarrollo que consultanix develop; en el ejemplo se usanpkgs.mkShellybuildInputs = with pkgs; [ go gopls gotools ];
- En el ejemplo,
-
flake.locky evaluación pura- Cuando se ejecuta un comando de Nix sobre un flake, Nix genera el archivo JSON
flake.lock, que fija todos los inputs y los inputs transitivos a revisiones exactas flake.lockes un archivo de bloqueo que permite la reproducibilidad de compilaciones entre distintas máquinas y a lo largo del tiempo- Flakes impone evaluación pura, por lo que
$NIX_PATH,builtins.currentSystemy las variables de entorno no pueden entrar de forma implícita; todo debe ser explícito - Las funciones que cumple Flakes pueden resumirse como: declarar dependencias, fijar dependencias, imponer pureza, ofrecer un esquema estándar de salidas, permitir compartir de forma reproducible y definir entornos de desarrollo
- Cuando se ejecuta un comando de Nix sobre un flake, Nix genera el archivo JSON
Enfoque equivalente en Guix
- Guix ya tenía soluciones para buena parte de las funciones de Flakes antes de que Flakes se introdujera en Nix 2.4 el 1 de noviembre de 2021
- El mecanismo de channels de Guix se introdujo alrededor de 2018-2019
- La solución de Guix es orthogonal y permite usar cada herramienta de forma independiente, en lugar de adoptar una abstracción monolítica única
-
Channels y declaración de dependencias
- En Flake, las dependencias se declaran directamente dentro de
flake.nix; en el ejemplo se usannixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";yhome-manager.url = "github:nix-community/home-manager"; inputs.nixpkgs.follows = "nixpkgs";de un input de Flake hace quehome-manageruse elnixpkgsdel flake actual en lugar de traer su propio inputnixpkgs, evitando así que existan dos copias distintas de nixpkgs- Los channels de Guix son repositorios Git que incluyen módulos de Guile; normalmente contienen definiciones de paquetes, pero también pueden incluir servicios, configuraciones de sistema y código arbitrario en Scheme
- Los channels de Guix se declaran en
~/.config/guix/channels.scm, y este archivo Scheme devuelve una lista de registros de channel guix pullobtiene y compila todos los channels, y hace que esos módulos estén disponibles en todos los comandosguix- Los channels pueden declarar dependencias sobre otros channels usando el archivo
.guix-channelen la raíz del repositorio - La dependencia entre channels en Guix es aproximadamente similar a
inputsen flake, y al ejecutarguix pulltambién se obtienen las dependencias transitivas de channels
- En Flake, las dependencias se declaran directamente dentro de
-
Dependencias por proyecto y dependencias por usuario
- Flakes sigue un enfoque por proyecto, donde cada repositorio tiene su propio
flake.nixy sus inputs, mientras que los channels funcionan a nivel de sistema o por usuario, ychannels.scmse aplica a todas las invocaciones deguix - Flakes permite de forma natural que distintos proyectos tengan distintos conjuntos de dependencias; en Guix, para lograr el mismo efecto normalmente se usa
guix time-machineo perfiles separados - Flakes usa una sintaxis tipo URL como
github:NixOS/nixpkgs,git+https://..., mientras que los channels usan URLs Git simples - La sintaxis de Flake es más ergonómica para referencias rápidas, mientras que los channels son más simples y explícitos
- Flakes soporta repositorios sin
flake.nixcomo inputs no-flake medianteflake = false; - En Guix, como un channel es un repositorio Git que contiene archivos Scheme, no se necesita ningún opt-in especial; cualquier repositorio con módulos de Guile puede ser un channel
- Flakes sigue un enfoque por proyecto, donde cada repositorio tiene su propio
Fijación, reproducibilidad y viaje en el tiempo
-
flake.lockflake.lockes un grafo JSON donde todos los inputs quedan fijados con un hash de commit exacto, y Nix verificanarHash, que es el hash del árbol completo de código fuente descargadoflake.lockse commitea al repositorio, por lo que quien haga clone obtiene las mismas versiones de dependencias- En
flake.lock,originales el objetivo solicitado ylockedes el objetivo que realmente se obtuvo - El sistema de dos capas de
flake.lockpermite actualizaciones selectivas, comonix flake lock --update-input nixpkgs, manteniendo el resto sin cambios
-
guix describeyguix time-machine- Guix registra los commits exactos de todos los channels al ejecutar
guix pull, yguix describemuestra esa información - La salida de
guix describeincluye número de generación, fecha, indicador de actual, nombre del channel, URL del repositorio, rama y commit - Los commits de channels registrados en Guix equivalen a un lock file, pero no están en un archivo dentro del directorio del proyecto, sino como un perfil de Guile en
~/.config/guix/current - Para compartir un entorno reproducible, en Guix se puede usar
guix time-machine guix time-machine --commit=8a1ab328 -- shell -m manifest.scmfija primero Guix a una revisión específica y luego ejecutaguix shellusando las definiciones de paquetes de esa revisiónguix time-machinedescarga y compila esa revisión si hace falta, y crea un entorno aislado donde las definiciones de paquetes corresponden exactamente al estado de ese commit- También existe un patrón en Guix de incluir en el repositorio un
channels.scmcon commits fijados guix time-machine -C channels.scm -- shell -m manifest.scmreproduce el entorno exacto usando elchannels.scmincluido en el repositorio
- Guix registra los commits exactos de todos los channels al ejecutar
-
Diferencias entre ambos enfoques
flake.lockes por proyecto y automático, mientras queguix describees por usuario y automático- Un
channels.scmcon commits fijados ofrece fijación por proyecto en Guix, pero de forma manual - Guix está mejorando la ergonomía de la fijación por proyecto, pero el flujo de trabajo actual requiere una configuración más explícita
flake.lockes un grafo JSON legible por máquina, y su equivalente en Guix es un archivo Scheme que enumera channels con hashes de commit- Ambos enfoques logran el objetivo de fijar dependencias, pero el lock de flake está más estructurado porque es un grafo completo de dependencias con entradas
originalylockedpara todos los inputs transitivos guix time-machinees una función sin equivalente directo en flake, ya que permite moverse no solo entre versiones fijadas de dependencias, sino también hacia un estado histórico completamente distinto de la colección de paquetes
Modelo de pureza
- Flakes se ejecuta en un contexto de evaluación restringido, y el uso de
builtins.currentSystem,builtins.getEnvy$NIX_PATHestá prohibido o se ignora - En Flakes, todo debe venir de las entradas declaradas, lo que dificulta que se generen dependencias accidentales sobre estado implícito
- La contrapartida de la evaluación pura en Flakes es que se necesitan parámetros
systemexplícitos en muchos lugares para detectar el sistema, y no es posible leer variables de entorno - Cuando se necesita una vía de escape impura en Flakes, se debe pasar explícitamente
--impure - Guix no necesita un modo de evaluación pura aparte, ya que por convención la evaluación ya es pura
- Los módulos de Guile no acceden a variables de entorno a menos que se les pasen explícitamente
- En Guix no existe un equivalente a
$NIX_PATH, y los paquetes se resuelven mediante el sistema de módulos, no por una ruta de búsqueda - En Guix no existe un concepto equivalente a
builtins.currentSystem, y los sistemas se especifican explícitamente mediante los metadatos del paquete y la bandera--system - Las compilaciones en Guix también son puras, y se ejecutan en contenedores aislados donde solo son visibles las entradas declaradas explícitamente
- En las compilaciones de Guix no hay acceso a
/usr/bin,/etcni a la red; las excepciones de acceso a red se limitan a derivations de salida fija - El método de aislamiento de compilación de Nix y Guix comparte esencialmente el mismo enfoque
- Guix logra la pureza a nivel de arquitectura mediante la estructura de módulos de Scheme, mientras que Flakes impone la pureza superponiendo un modo de evaluación restringido sobre un sistema originalmente impuro
Esquema de salidas y modelo de datos
-
Esquema de salidas de Flake
- Flakes define un esquema estándar para las salidas, y
packages.<system>.<name>se usa ennix build,devShells.<system>.<name>ennix developyapps.<system>.<name>ennix run - El esquema de salidas de Flake también incluye
nixosConfigurations.<name>,overlays.<name>,nixosModules.<name>,formatter.<system>,templates.<name>ychecks.<system>.<name> - La estandarización del esquema de salidas de Flake hace que
nix build .,nix runynix flake showconsulten ubicaciones consistentes, lo que mejora la capacidad de descubrimiento - La desventaja del esquema de salidas de Flake es que es rígido; para agregar tipos de salida arbitrarios se necesita modificar el propio Nix, aunque existe un pequeño mecanismo de extensión
- Debido al parámetro
<system>de Flake, el soporte multiplataforma debe manejarse explícitamente, por lo que se usan funciones auxiliares o bibliotecas comoforAllSystems,flake-utilsyflake-parts
- Flakes define un esquema estándar para las salidas, y
-
Tipos de datos de primera clase en Guix
- En Guix no hay un único esquema de salidas como en Flakes, sino tipos de datos de primera clase que pueden ser consumidos por varios comandos
- En Guix, los paquetes se definen como registros
<package>y los usanguix installyguix build - En Guix, los manifests se definen como archivos de Scheme y los usan
guix shell -myguix package - En Guix, las configuraciones de sistema se definen con
operating-systemy las usaguix system reconfigure - En Guix, las configuraciones de home se definen con
home-environmenty las usaguix home reconfigure - En Guix, los servicios se definen como registros
<service>y se usa el camposervicesdeoperating-system - En Guix, los channels son repositorios Git y los usa
guix pull - En Guix, las variantes de paquetes son procedimientos de Scheme y se usan
--with-inputy--transform
-
Archivos y definiciones de paquetes
- Un proyecto de Guix puede ofrecer una combinación de un channel con definiciones de paquetes,
manifest.scmpara desarrollo,system.scmpara despliegue y declaracionesoperating-systemohome-environment, entre otros - En Guix, estos archivos no requieren un archivo especial de punto de entrada; son simplemente archivos de Scheme que definen valores de Scheme
- En Guix, basta con especificar el archivo al subcomando
guixcorrespondiente para que el comando lo procese, sin necesidad de ceremonias adicionales ni validación de esquema - Un ejemplo de
manifest.scmdeclara un entorno de desarrollo pasando una lista de nombres de paquetes"guile","guile-git"y"guile-json"aspecifications->manifest - Un ejemplo de
mylib.scmdefine un registro<package>, el equivalente en Guix a una derivation de Nix, y los campos del paquete pueden consultarse de forma programática - Un ejemplo de definición de paquete incluye
(name "mylib"),(version "0.1.0"),(source (local-file ".")),(build-system gnu-build-system),(inputs (list guile guile-git)),(home-page "https://example.com")y(license gpl3+) local-fileen Guix toma los archivos del directorio actual en tiempo de compilación, de forma similar asrc = ./.;en Nixgnu-build-systemen Guix sigue el método./configure && make && make install, y Guix también tiene otros sistemas de compilación comocmake-build-systemypython-build-system- A diferencia de Nix, donde
stdenvproporciona implícitamentegccycoreutils, en Guix todas las dependencias son explícitas
- Un proyecto de Guix puede ofrecer una combinación de un channel con definiciones de paquetes,
Entorno de desarrollo
- En el ejemplo de
devShellsde Flakes se usadevShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; }; mkShellcrea una derivation que genera un entorno de shell durante la build;buildInputsentra en elPATHdentro del shell yshellHookejecuta bash arbitrario al entrar al shell- Se entra al dev shell de Flake con
nix developo connix develop .#my-shellpara un shell con nombre - El entorno de desarrollo de Guix puede definirse en
manifest.scmpasando una lista de cadenas de especificación de paquetes aspecifications->manifest - El manifest de Guix del ejemplo declara
"go","gopls","go-tools" - Se entra al shell basado en manifest de Guix con
guix shell -m manifest.scm - Guix permite, en un entorno ad hoc, pasar solo nombres de paquetes por línea de comandos sin archivo, como
guix shell go gopls go-tools guix shellsoporta--containerpara aislamiento total,--emulate-fhspara ejecutar programas que esperan el layout estándar del filesystem de Linux y--nestingpara ejecutar Guix dentro de un contenedor de Guix- Los manifests de Guix son archivos Scheme independientes, no incrustados dentro de una estructura mayor como
flake.nix guix shellpuede funcionar incluso sin archivo, peronix developrequiere un flake o unshell.nixde la interfaz legacy- Flakes ofrece dev shells con nombre como
devShells.x86_64-linux.test,devShells.x86_64-linux.default - En lugar de dev shells con nombre, los manifests de Guix se organizan poniendo archivos separados como
manifest.scm,test-manifest.scmuno junto a otro - Tanto Nix Flakes como Guix soportan desarrollo en contenedores
Configuración del sistema
-
NixOS y Flakes
- En el ejemplo de
nixosConfigurationsde Flakes,nixpkgs.lib.nixosSystemrecibe una lista de módulos de NixOS y genera una derivation completa del sistema que incluye kernel, servicios, archivos de configuración, etc. - El comando de ejemplo para desplegar NixOS basado en Flake es
nixos-rebuild switch --flake .#myhost - El ejemplo
nixosConfigurations.myhostincluyesystem = "x86_64-linux";ymodules = [ ./configuration.nix home-manager.nixosModules.home-manager ]; - Los módulos de NixOS usan un sistema de módulos con fusión basada en prioridades mediante
options,config,mkIf,mkDefault,mkForce - En el sistema de módulos de NixOS, aunque varios módulos configuren la misma opción, el sistema resuelve las prioridades, por lo que es fácil evitar conflictos incluso cuando decenas de módulos contribuyen a la misma configuración
- En el ejemplo de
-
Guix
operating-system- El
operating-systemde Guix no es una función sino un record de Scheme, y Guix valida cada field como un valor tipado con nombre - El comando de ejemplo para desplegar un sistema con Guix es
guix system reconfigure config.scm - El record
operating-systemdel ejemplo incluye(host-name "myhost"),(timezone "Etc/UTC"), configuración del bootloader, filesystems y servicios - El ejemplo de configuración del bootloader en Guix usa
grub-efi-bootloadery el destino"/boot/efi", y Guix soporta GRUB, U-Boot, etc. - Los filesystems en Guix se declaran como una lista, y
%base-file-systemsproporciona valores por defecto para/dev,/proc,/sys, etc. - Los servicios en Guix forman un directed acyclic graph (DAG), y cada servicio puede extender otros servicios
%base-servicesproporciona servicios esenciales como el sistema init Shepherd, syslog, networking, etc.- La configuración del sistema en Guix no requiere un tipo especial de output; basta con indicar a
guix systemun archivo que retorne un recordoperating-system - La composición de servicios de Guix facilita escribir servicios nuevos que se conecten al sistema existente de manera arbitraria
- El
Descubribilidad y registro
- Flakes tiene
flake.nix, un punto de entrada estándar donde se declaran en un solo archivo las dependencias del proyecto, outputs y un esquema descubrible - Los proyectos de Guix pueden usar archivos basados en convención como
manifest.scm,channels.scm,guix.scm,package.scm - Hay intentos de estandarizar
guix.scmcomo archivo de proyecto reconocido automáticamente porguix shell, pero todavía no está tan establecido comoflake.nix - Flakes tiene el registro global flake-registry, que mapea nombres cortos a URL; los ejemplos son
nix run nixpkgs#hello,nix build github:NixOS/nixpkgs#firefox - Guix usa especificaciones de paquetes para una conveniencia similar; los ejemplos son
guix shell hello,guix install firefox - Guix no tiene un equivalente de registro para apuntar a un repositorio Git arbitrario mediante un nombre corto, y usa la URL directamente
- El registro de Nix a veces ha sido una fuente de confusión, porque no siempre está claro si
nixpkgses una entrada del registro, una ruta local u otro destino nix flake showes un comando que muestra en vista de árbol todo lo que ofrece un flake- Guix tiene
guix searchpara paquetes yguix system searchpara servicios, pero no existe un comando equivalente que muestre todo lo que ofrece un proyecto o repositorio específico, por lo que hay que revisar directamente los archivos Scheme - Flakes tiene una fuerte capacidad de descubribilidad en el sentido de que
nix flake showofrece una vista consistente de lo que proporciona un proyecto - Los proyectos de Guix son más ad hoc, hay que saber qué archivo mirar y no existe un archivo estándar de punto de entrada único
- Guix tiene gran flexibilidad porque todo es Scheme, así que se puede definir y combinar lo que se quiera sin un schema
Modelo de paquetes y reescritura de grafos
- En Nix, un paquete es una función que devuelve una derivation mediante una llamada a
stdenv.mkDerivation { ... }, y el resultado es un conjunto de atributos opaco. - En Guix, un paquete es un registro
<package>, una estructura de datos transparente con campos nombrados que puede inspeccionarse, transformarse y combinarse con procedimientos estándar de Scheme. - Como las definiciones de paquetes en Guix son registros transparentes y no funciones opacas, es posible inspeccionarlas y transformarlas de forma programática sin herramientas especiales.
- En Guix, como los paquetes son datos, las reescrituras de grafos se pueden realizar fácilmente.
- En Guix, con
package-input-rewritingse puede expresar una operación que recorra todo el grafo de dependencias para reemplazarperlporperl-minimal. - La palabra clave
inheritde Guix redefine un paquete heredando todos los campos decoreutilsy sobrescribiendo solo los campos especificados. - Nix tiene overlays con un propósito similar, pero debido a su interfaz de funciones opaca, inspeccionar y transformar es más difícil y su usabilidad es menor.
Actualizaciones de seguridad, bootstrap y autenticación
- El grafting de Guix permite aplicar actualizaciones de seguridad en el árbol de dependencias sin reconstruir todos los paquetes dependientes.
- Cuando hay una vulnerabilidad en bibliotecas de bajo nivel como glibc, Guix puede reescribir las rutas del almacén para sustituirlas por la versión corregida.
- Nix reconstruye todo en escenarios de actualizaciones de seguridad, y en árboles de dependencias grandes el tiempo de compilación puede diferir por horas.
- Guix pone un fuerte énfasis en el bootstrap basado en código fuente, de modo que todo el sistema puede construirse a partir de una base mínima de confianza.
- La cadena de bootstrap de Guix comienza con un ensamblador hexadecimal de alrededor de 500 bytes y continúa con el compilador de C
mesescrito en Scheme,tccy toda la toolchain de GNU. - El proyecto bootstrappable builds aborda los detalles completos del bootstrap desde código fuente.
- Nix depende de más semillas binarias que Guix.
- Si no se puede auditar la cadena de bootstrap, no es posible verificar por completo que el sistema realmente se haya construido a partir del código fuente previsto, por lo que el bootstrap completo desde código fuente es importante para la confianza y la verificabilidad.
- Los canales de Guix admiten autenticación criptográfica de forma predeterminada.
- Un canal de Guix especifica una “introducción” compuesta por un commit concreto y su firma Ed25519, y Guix verifica toda la cadena de firmas desde esa introducción hasta el commit actual.
- Flakes usa HTTPS y la infraestructura de GitHub como modelo de confianza, lo que representa un modelo de seguridad distinto de la autenticación de canales con Ed25519 en Guix.
Correspondencias clave del cuadro resumen
- En la declaración de dependencias, Flakes usa
inputsenflake.nix, mientras que Guix usachannels.scmy.guix-channel. - Para fijar dependencias, Flakes usa
flake.lockautomático y por proyecto, mientras que Guix usaguix describeautomático por usuario ychannels.scmcon commits especificados manualmente por proyecto. - La evaluación pura se aplica en el modo flake y, en Guix, es una característica inherente por diseño.
- En el esquema de salidas, Flakes usa un attrset estructurado en
outputs, mientras que Guix usa registros de Scheme ad hoc. - Para entornos de desarrollo, Flakes usa
devShellsynix develop, mientras que Guix usamanifest.scmyguix shell. - En la configuración del sistema, Flakes usa
nixosConfigurationsy el sistema de módulos, mientras que Guix usaoperating-systemy un DAG de servicios. - Para reproducibilidad con un solo comando, Flakes usa
nix build github:foo/bar, mientras que Guix usa la formaguix time-machine -C channels.scm -- build. - Para fijación por proyecto, Flakes lo maneja automáticamente con
flake.lock, mientras que Guix lo hace manualmente conchannels.scmque incluye commits. - En explorabilidad, Flakes usa
nix flake show, mientras que Guix depende de la inspección de módulos de Scheme. - En el modelo de paquetes, Flakes/Nix usa funciones opacas y Guix usa registros transparentes.
- En el sistema init, Nix usa systemd y Guix usa GNU Shepherd.
- Para actualizaciones de seguridad, Nix requiere reconstrucción completa y Guix usa grafting rápido.
- En confianza de bootstrap, Nix se basa en semillas binarias y Guix en bootstrap completo desde código fuente.
- Para actualizaciones autenticadas, Flakes usa confianza en HTTPS/GitHub y Guix usa autenticación de canales con Ed25519.
- En soporte FHS, Nix ofrece
buildFHSUserEnvy Guix--emulate-fhs. - En soporte no Linux, Nix cuenta con nix-darwin para macOS y Guix se organiza alrededor de GNU Hurd.
- En cuanto a si es exclusivamente software libre, Nix no lo es y es configurable, mientras que Guix cumple con la FSDG.
Conclusión
- Flakes y Guix resuelven el mismo tipo de problemas —reproducibilidad, gestión de dependencias y declaración del sistema— con filosofías arquitectónicas distintas.
- Flakes se acerca a una sola funcionalidad con un archivo, un esquema, un archivo de bloqueo y un conjunto de convenciones.
- Guix es una combinación de herramientas ortogonales como channels para la distribución, manifests para los entornos,
operating-systempara la configuración,guix time-machinepara la reproducibilidad y registros de Scheme para otras estructuras. - Si prefieres una sola forma estándar, un solo archivo de entrada, un solo esquema de salida y un solo formato de bloqueo, Flakes encaja de manera natural.
- Si prefieres aplicar a la gestión de paquetes la filosofía Unix de combinar herramientas pequeñas e independientes para que cada una haga bien una sola cosa, Guix encaja mejor.
- Ambos ecosistemas han evolucionado en torno a la idea de que la gestión de paquetes debe ser funcional, declarativa y reproducible, y empujan esa misma idea con implementaciones diferentes.
1 comentarios
Opiniones en Lobste.rs
Este sitio es demasiado frustrante de leer en móvil: la letra es un poco pequeña y además interrumpe constantemente al hacer scroll.
Después de la primera comparación ya no pude seguir leyendo, porque me regresaba de golpe al índice todo el tiempo.
Incluso después de leer el artículo, todavía no me queda claro cómo se deben declarar y fijar las dependencias de un proyecto. Da la impresión de que, para distribuirlo y compartirlo, hay que buscar manualmente en
channels.scmel hash de commit de cada dependencia transitiva e insertarlo ahí.time-machineparece funcionar solo con el conjunto de paquetes de Guix, no con dependencias fuera del árbol.También es bastante fácil ejecutar código viejo de nixpkgs, algo como
nix run github:nixos/nixpkgs/<commit hash>#<package>.Lo particular de Guix es que no separa la versión del conjunto de paquetes de la versión del gestor de paquetes. Si quieres ejecutar paquetes antiguos, también terminas ejecutando una versión antigua de Guix, y no me queda claro por qué querrías eso.
El artículo dice que en flakes hay que buscar y fijar commits manualmente, pero justo después pone como ejemplo un comando de Guix en el que también hay que especificar un commit. En Nix flakes también puedes sobrescribir la versión de nixpkgs con
--override-input, aunque es medio sucio, y justo eso es una de las cosas que unflake intenta mejorar.Normalmente desarrollas dentro de un entorno dedicado de
guix shell, y cuando llega el momento de compartirlo, usasguix describe -f channels > channels.scmpara registrar todos los hashes de commit enchannels.scm.Si ves la documentación de declaring channel dependencies, parece que sí puedes especificar los commits de las dependencias, pero no veo una opción para verificar que, si esa dependencia a su vez tiene dependencias, esas también queden fijadas a commits específicos.
La sintaxis
--commit=detime-machineaplica a canales de Guix, pero con-Ctambién puedes cargar canales adicionales desde un archivo.Incluso si hay cambios incompatibles en el gestor de paquetes y en los registros de paquetes, esto tiene la ventaja de no perder historial ni reproducibilidad.
Eso sí, requiere hacer un checkout de nixpkgs por cada commit, así que el costo inicial de construirlo sería enorme. Una vez hecho, mantener el índice debería costar poco.
Ya le avisaron a coopi del problema del sitio y de este hilo, así que ojalá lo arreglen pronto.
Hablando desde alguien que está completamente inclinado hacia Guix, también me gustaría, como dijo coopi, que Guix tuviera un archivo/directorio estándar como
flake.nixo un directorionixdonde estuviera todo. Aunque quizá no sea posible, porque para importar módulos de Scheme hay que indicar la ruta correcta.En este post de Lobsters están las cosas de las que habla el autor, así que parece que con las etiquetas
nixylispbasta.linux. Es el único kernel que ambos tienen en común :P Aunque sí, como dijiste, puede queunixno encaje.Por ejemplo, algo así: Y también estaría bien un comando
guix channelque ayudara a crear y manejar canales nuevos.Me pregunto si en Guix existe una función como
.inputs.nixpkgs.followsde Nix flakes para sobrescribir los valores fijados de dependencias transitivas.Además, buena parte de la explicación del autor sobre Guix me recuerda al Nix anterior a flakes: sin un punto de entrada estándar y con una estructura basada en canales. Pero en Guix, como hay un sistema de tipos y un lenguaje real, siento que ese mismo patrón duele menos. Se siente como una historia alternativa de lo que Nix habría sido si hubiera sido mejor o hubiera usado otro lenguaje.
Por los problemas de usabilidad que señalaron otros comentarios, me da cosa recomendarlo. Yo no me había dado cuenta porque uso NoScript y desactivo JavaScript por defecto.
Aun así, este artículo me cayó justo en el momento indicado. En mi empresa estamos avanzando mucho hacia usar Nix y las flakes nos han dado algo de batalla, pero la explicación de este artículo me pareció mucho más clara que otras que había leído antes.
Respuesta de Coopi: hizo un cambio esta mañana, pero no pudo probarlo por trabajo, y al parecer resultó que había un problema con JavaScript.
Este sitio no se puede usar en iOS móvil. La página parece cargar desde abajo y luego desplazarse inmediatamente hacia arriba, y si bajo más de una pantalla, algo se activa y me vuelve a subir.
El modo de lectura sí funciona, pero se pierden el resaltado y los detalles de estilo originales, que en realidad estaban bastante bien.
Es válido decir que lo que hacen las flakes también se puede hacer con varias herramientas de Guix, pero hay que señalar que en Nix también existían antes, y siguen existiendo, herramientas pequeñas y ortogonales para resolver esos mismos problemas.
Lo que aportan las flakes es un punto de entrada estándar para proyectos y el ecosistema que eso hace posible, por ejemplo el registro. El artículo mismo dice que Guix no tiene esa parte.
Los usuarios de Guix pueden decidir que no necesitan un punto de entrada estándar, y muchos usuarios de Nix también lo han decidido durante mucho tiempo.
Pero decir que puedes lograr flakes con un conjunto de herramientas ortogonales suena un poco como afirmar que FreeBSD no necesita soporte OCI porque con jail ya puedes hacer todo lo necesario. Se pierde de vista la parte en la que la estandarización habilita un ecosistema.
Me interesa mucho Guix y hasta he contribuido un poco, pero sí me gustaría comparar por qué compilar con
guix time-machinejunto conchannels.scmtarda tanto más que cambiar los valores fijados de una flake y evaluar Nix. Si fuera algo como 3 veces más lento, por ejemplo pasar de 5~10 segundos a 15~30 segundos, me parecería aceptable, pero cuando lo intenté, ni de lejos era solo eso.