1 ポイント 投稿者 GN⁺ 5 시간 전 | 1件のコメント | WhatsAppで共有
  • Nix Flakesは、プロジェクト依存関係、ロック、出力スキーマ、開発環境をflake.nixflake.lockを中心にまとめるもので、Guixはchannels、manifests、guix describeguix shelloperating-systemのような直交的なツールの組み合わせによって同種の機能を提供する
  • Flakesは、プロジェクトごとのinputsと自動生成されるflake.lockで依存関係を固定し、Guixはユーザーごとのguix describe、プロジェクト内でコミットを記したchannels.scmguix time-machineによって再現可能な環境を構成する
  • 純粋性はFlakesではrestricted evaluationによって強制され、GuixではSchemeモジュール構造、明示的な入力、隔離されたビルドコンテナを通じて設計上実現される
  • 出力構造は、FlakesがpackagesdevShellsnixosConfigurationsのような標準attrsetを提供する一方、Guixは<package>、manifest、operating-system、serviceのような透過的なSchemeレコードとファイルを各コマンドが直接利用する
  • 選択基準は、単一のエントリーポイントと標準スキーマを好むならFlakesが向いており、小さく独立したツールを組み合わせる方式を好むならGuixのほうが適している

主要な比較

  • Nix flakeに相当する単一のGuix機能は存在せず、Nix Flakesが複数の問題を1つの大きな機能で解決するのに対し、Guixはより小さく直交的なツール群の組み合わせで対応する
  • GuixはNix daemonを再利用しており、build isolationとstore managementを担うC++コンポーネントを共有している
  • GuixはNix daemonの上にある言語、パッケージ定義、サービスシステムなどの大部分をGuile Schemeで新たに実装している
  • GuixとNixは、derivation formatであるATermとdaemonの系譜を共有しているが、daemon上位の構造はGuix独自の方式で構成されている
  • GuixはFlakesが提供するcapabilitiesを備えているが、それを異なる形で提供している

Nix Flakeの基本構造

  • Nix flakeは、ルートにflake.nixファイルを持つsource treeであり、通常はGit repositoryの形を取る
  • flake.nixの存在によってsource treeはflakeとなり、このファイルはdescriptioninputsoutputsのような構造を持つ
  • descriptionは人間が読める文字列で、flakeが提供する内容を示す
  • inputsは、他のflakes、Git repos、tarballsのようなdependenciesを宣言し、Nixがそれらをfetchしてevaluateしたうえでoutputs関数に渡す
  • outputsは、解決済みのinputsと特別なself inputを受け取り、packages、dev shells、NixOS configurations、overlaysなどを含むstructured attrsetを返す関数である
  • 例の構造と実行対象

    • 例のinputsにあるnixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";は、GitHub上のNixOS/nixpkgsリポジトリからnixos-unstableブランチを取得することを意味する
    • 例のflakeは、supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" ];nixpkgs.lib.genAttrsを使って、複数のCPU architectureごとのoutputsを生成する
    • Flakesはpackages.<system>レベルを要求し、例ではpackages配下のdefault packageをpkgs.buildGoModuleで定義している
    • src = ./.;は、Git repository全体をsourceとして使う
    • devShellsnix developが参照する開発shell定義であり、例ではpkgs.mkShellbuildInputs = with pkgs; [ go gopls gotools ];を使う
  • flake.lockと純粋評価

    • flakeに対してNixコマンドを実行すると、Nixはすべてのinputと推移的inputを正確なrevisionに固定するJSONファイルflake.lockを生成する
    • flake.lockは、マシンや時間をまたいだbuild reproducibilityを可能にするlock fileである
    • Flakesはpure evaluationを強制し、$NIX_PATHbuiltins.currentSystem、environment variablesが暗黙的に入り込めず、すべてがexplicitでなければならない
    • Flakesが果たす機能は、dependenciesの宣言、dependenciesのpinning、純粋性の強制、標準出力スキーマの提供、reproducible sharing、development environmentsの定義として整理できる

Guixの対応方法

  • Guixは、Nix 2.4でFlakesが2021年11月1日に導入される前から、Flakesの機能のかなりの部分に対する解決策をすでに備えていた
  • Guixのchannels mechanismは2018〜2019年ごろに導入された
  • Guixの解決策はorthogonalであり、単一のmonolithic abstractionを採用せず、各ツールを独立して利用できる
  • Channelsと依存関係の宣言

    • Flakeではflake.nix内にdependenciesを直接宣言し、例ではnixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";home-manager.url = "github:nix-community/home-manager";を使う
    • Flake inputのinputs.nixpkgs.follows = "nixpkgs";は、home-manager自身のnixpkgs inputを取得せず、現在のflakeのnixpkgsを使うようにして、異なるnixpkgsのコピーが2つ生じる状況を避ける
    • GuixのchannelsはGuile modulesを含むGit repositoryで、通常はpackage definitionsを含むが、services、system configurations、任意のScheme codeも含められる
    • Guix channelsは~/.config/guix/channels.scmで宣言し、このScheme fileはchannel recordsのlistを返す
    • guix pullはすべてのchannelsをfetchしてcompileし、それらのmodulesをすべてのguix commandで利用可能にする
    • Channelsはrepository rootの.guix-channel fileを使って、ほかのchannelsへのdependenciesを宣言できる
    • Guix channelsのchannel dependencyはflakeのinputsにおおむね似ており、guix pull実行時にtransitive channel dependenciesも一緒にfetchされる
  • プロジェクトごとの依存関係とユーザーごとの依存関係

    • Flakesはper-project方式で、各repositoryが独自のflake.nixとinputsを持つ一方、channelsはsystem-wideまたはper-user方式で、channels.scmがすべてのguix invocationsに適用される
    • Flakesは、異なるプロジェクトがそれぞれ異なるdependency setを自然に持てるよう支援し、Guixでは同じ効果を得るために通常guix time-machineまたはseparate profilesを使う
    • Flakesはgithub:NixOS/nixpkgsgit+https://...のようなURL-like syntaxを使い、channelsはplain Git URLsを使う
    • Flake syntaxはquick referencesではよりergonomicで、channelsはより単純でexplicitである
    • Flakesはflake = false;によって、flake.nixのないrepositoriesをnon-flake inputsとしてサポートする
    • GuixではchannelはScheme filesが入ったGit repositoryなので、特別なopt-inは不要で、Guile modulesがあるrepositoryならどれでもchannelになれる

固定、再現性、タイムマシン

  • flake.lock

    • flake.lockはJSON graphで、すべてのinputは正確なcommit hashにpinningされ、Nixはfetchしたsource tree全体のhashであるnarHashを検証する
    • flake.lockはrepositoryにcommitされるため、cloneした人は同一のdependency versionsを受け取る
    • flake.lockoriginalは要求した対象で、lockedは実際に得られた対象である
    • flake.lockのtwo-layer systemは、nix flake lock --update-input nixpkgsのように特定のinputだけを更新し、残りは維持するselective updateを可能にする
  • guix describeguix time-machine

    • Guixはguix pull実行時にすべてのchannelsの正確なcommitsを記録し、guix describeがこの情報を表示する
    • guix describeの出力にはgeneration番号、日付、current表示、channel名、repository URL、branch、commitが含まれる
    • Guixの記録されたchannel commitsはlock fileに相当するが、project directory内のfileではなく、~/.config/guix/currentにあるGuile profileとして存在する
    • 再現可能な環境を共有するには、Guixでは**guix time-machine**を使える
    • guix time-machine --commit=8a1ab328 -- shell -m manifest.scmは、まずGuix自体を特定のrevisionにpinningし、そのrevisionのpackage definitionsを使ってguix shellを実行する
    • guix time-machineは必要に応じてそのrevisionをdownloadしてcompileし、package definitionsが正確にそのcommit時点の状態であるisolated environmentを作成する
    • pinned commitsを持つchannels.scmをproject repositoryにcheck inするGuixのパターンもある
    • guix time-machine -C channels.scm -- shell -m manifest.scmは、repositoryに含まれるchannels.scmを使ってexact environmentを再現する
  • 両方式の違い

    • flake.lockはper-projectかつautomaticで、guix describeはper-userかつautomaticである
    • pinned commits入りのchannels.scmはGuixでper-project pinningを提供するが、manual方式である
    • Guixはper-project pinningのergonomics改善を進めているが、現時点のworkflowではよりexplicitなセットアップが必要である
    • flake.lockはmachine-readableなJSON graphで、Guixにおける対応物はcommit hashesを持つchannelsを列挙したScheme fileである
    • どちらの方式もdependency pinningという目標を達成するが、flake lockはすべてのtransitive inputについてoriginallocked entriesを持つfull dependency graphなので、よりstructuredである
    • guix time-machineは直接的なflake equivalentがない機能で、pinned dependency versionsだけでなく、package collectionの完全に異なるhistorical stateへ移動できる

純粋性モデル

  • Flakes は restricted evaluation context で実行され、builtins.currentSystembuiltins.getEnv$NIX_PATH の使用は禁止されるか無視される
  • Flakes ではすべてが declared inputs から来る必要があり、implicit state への accidental dependency が生じにくいようになっている
  • Flakes の pure evaluation のトレードオフは、system detection のために明示的な system パラメータが各所で必要になることと、environment variables を読み取れないことにある
  • Flakes で impure escape hatch が必要な場合は、--impure を明示的に渡さなければならない
  • Guix では別個の pure evaluation mode は不要で、evaluation は慣習上すでに pure である
  • Guile modules は、environment variables として明示的に渡さない限り、それらにアクセスしない
  • Guix には $NIX_PATH に相当するものがなく、packages は search path ではなく module system を通じて解決される
  • Guix には builtins.currentSystem に相当する概念がなく、systems は package metadata と --system フラグで明示される
  • Guix の build も pure であり、builds は explicitly declared inputs だけが見える isolated containers で実行される
  • Guix builds では /usr/bin/etc、network access はなく、network access の例外は fixed-output derivations に限られる
  • Build sandboxing の方式は、Nix と Guix が本質的に同じアプローチを共有している
  • Guix は Scheme modules 構造を通じてアーキテクチャレベルで purity を達成し、Flakes はもともと impure な system の上に restricted evaluation mode を重ねて purity を強制する

出力スキーマとデータモデル

  • Flake output schema

    • Flakes は outputs に対する standard schema を定義しており、packages.<system>.<name>nix builddevShells.<system>.<name>nix developapps.<system>.<name>nix run で使われる
    • Flake output schema には nixosConfigurations.<name>overlays.<name>nixosModules.<name>formatter.<system>templates.<name>checks.<system>.<name> もある
    • Flake output schema の standardization により、nix build .nix runnix flake show が一貫した場所を参照するため、discoverability が高まる
    • Flake output schema の欠点は rigid である点で、任意の output types を追加するには Nix 自体の修正が必要だが、小規模な extension mechanism は存在する
    • Flake の <system> パラメータのため、multi-platform support は明示的に処理する必要があり、forAllSystemsflake-utilsflake-parts のような helper functions や libraries が使われる
  • Guix の first-class data types

    • Guix には Flakes のような単一の output schema はなく、複数の command が利用できる first-class data types がある
    • Guix で packages は <package> records として定義され、guix installguix build が利用する
    • Guix で manifests は Scheme files として定義され、guix shell -mguix package が利用する
    • Guix で system configs は operating-system として定義され、guix system reconfigure が利用する
    • Guix で home configs は home-environment として定義され、guix home reconfigure が利用する
    • Guix で services は <service> records として定義され、operating-systemservices field が利用される
    • Guix で channels は Git repos であり、guix pull が利用される
    • Guix で package variants は Scheme procedures であり、--with-input--transform が利用される
  • ファイルとパッケージ定義

    • Guix project は、package definitions を含む channel、開発用の manifest.scm、デプロイ用の system.scmoperating-system または home-environment declaration などを組み合わせて提供できる
    • Guix ではこれらのファイルは special entry point file を必要とせず、Scheme values を定義する Scheme files にすぎない
    • Guix では関連する guix subcommand にファイルを指定すれば command が処理し、別途 ceremony や schema validation は不要である
    • 例の manifest.scm は、specifications->manifest"guile""guile-git""guile-json" の package names list を渡して development environment を宣言する
    • 例の mylib.scm は、Guix における Nix derivation の対応物である <package> record を定義し、package fields を programmatically query できる
    • 例の package definition は (name "mylib")(version "0.1.0")(source (local-file "."))(build-system gnu-build-system)(inputs (list guile guile-git))(home-page "https://example.com";)(license gpl3+) を持つ
    • Guix の local-file は build time に current directory の files を取り込み、Nix の src = ./.; に似ている
    • Guix の gnu-build-system./configure && make && make install 方式で、Guix には cmake-build-systempython-build-system など他の build systems もある
    • Guix は、Nix で stdenvgcccoreutils を implicit に提供するのとは異なり、dependencies をすべて explicit にしている

開発環境

  • Flakes の devShells の例では、devShells.x86_64-linux.default = pkgs.mkShell { buildInputs = with pkgs; [ go gopls gotools ]; shellHook = '' echo "Welcome to the devShell!" ''; }; を使用する
  • mkShell はビルド時にシェル環境を作成する derivation を生成し、buildInputs はシェル内の PATH に入り、shellHook はシェルに入る際に任意の bash を実行する
  • Flake の dev shell には nix develop、または名前付きシェル用の nix develop .#my-shell で入る
  • Guix の開発環境は、manifest.scmspecifications->manifest にパッケージ仕様文字列のリストを渡して定義できる
  • 例の Guix manifest では "go""gopls""go-tools" を宣言する
  • Guix manifest ベースのシェルには guix shell -m manifest.scm で入る
  • Guix では ad-hoc な環境において、ファイルなしで guix shell go gopls go-tools のようにコマンドラインのパッケージ名だけを渡せる
  • guix shell は完全な分離のための --container、標準的な Linux filesystem layout を期待するプログラム実行用の --emulate-fhs、Guix コンテナ内で Guix を実行する --nesting をサポートする
  • Guix manifests は、より大きな flake.nix 構造に埋め込まれていない、独立した Scheme ファイルである
  • guix shell はファイルなしでも動作できるが、nix develop には flake またはレガシーインターフェースの shell.nix が必要である
  • Flakes は devShells.x86_64-linux.testdevShells.x86_64-linux.default のような名前付き dev shell を提供する
  • Guix manifests では、名前付き dev shell の代わりに manifest.scmtest-manifest.scm のような別ファイルを並べて置く方式を取る
  • Nix Flakes と Guix はどちらもコンテナ化された開発をサポートする

システム構成

  • NixOS と Flakes

    • Flakes の nixosConfigurations の例では、nixpkgs.lib.nixosSystem が NixOS modules のリストを受け取り、kernel、services、config files などを含む完全な system derivation を生成する
    • Flake ベースの NixOS デプロイの例のコマンドは nixos-rebuild switch --flake .#myhost である
    • 例の nixosConfigurations.myhost には system = "x86_64-linux";modules = [ ./configuration.nix home-manager.nixosModules.home-manager ]; が含まれる
    • NixOS modules は、optionsconfigmkIfmkDefaultmkForce を通じた優先順位ベースのマージを使う module system である
    • NixOS のモジュールシステムでは、複数のモジュールが同じオプションを設定しても、システムが優先順位を解決するため、数十個のモジュールが同じ構成に貢献しても衝突を避けやすい
  • Guix operating-system

    • Guix の operating-system は関数ではなく Scheme record であり、各 field は名前付きの型付き値として Guix が検証する
    • Guix system デプロイの例のコマンドは guix system reconfigure config.scm である
    • 例の operating-system record には (host-name "myhost")(timezone "Etc/UTC")、bootloader configuration、file systems、services が含まれる
    • Guix bootloader configuration の例では grub-efi-bootloader と target "/boot/efi" を使い、Guix は GRUB、U-Boot などをサポートする
    • Guix file systems はリストで宣言され、%base-file-systems/dev/proc/sys などのデフォルトを提供する
    • Guix services は directed acyclic graph(DAG) を構成し、各 service はほかの services を extend できる
    • %base-services は Shepherd init system、syslog、networking などの必須 services を提供する
    • Guix system configuration には特別な output type は不要で、operating-system record を返すファイルを guix system に指定すればよい
    • Guix の service の組み合わせは、既存システムに任意の方法で接続される新しい service を書きやすくする

探索性とレジストリ

  • Flakes には、プロジェクト依存関係、出力、発見可能なスキーマを 1 つのファイルで宣言する標準エントリポイント flake.nix がある
  • Guix プロジェクトでは、manifest.scmchannels.scmguix.scmpackage.scm などの慣例ベースのファイルを使うことがある
  • guix shell が自動認識するプロジェクトファイルとして guix.scm を標準化しようとする動きはあるが、flake.nix ほど確立されてはいない
  • Flakes には、短い名前を URL にマッピングするグローバルレジストリ flake-registry があり、例として nix run nixpkgs#hellonix build github:NixOS/nixpkgs#firefox がある
  • Guix は似た利便性のためにパッケージ指定を使い、例として guix shell helloguix install firefox がある
  • Guix には、任意の Git リポジトリを短い名前で指すレジストリ相当のものはなく、URL を直接使う
  • Nix のレジストリは、nixpkgs がレジストリエントリなのか、ローカルパスなのか、別の対象なのかが常に明確ではなく、混乱の原因になることがあった
  • nix flake show は、flake が提供するすべての項目をツリービューで表示するコマンドである
  • Guix にはパッケージ用の guix search とサービス用の guix system search はあるが、特定のプロジェクトやリポジトリが提供するすべての項目を表示する対応コマンドはなく、Scheme ファイルを直接確認する必要がある
  • Flakes は、nix flake show が project の提供物を一貫したビューで示す点で discoverability が高い
  • Guix projects はより ad-hoc で、どのファイルを見るべきかを知っている必要があり、標準の単一エントリポイントファイルがない
  • Guix はすべてが Scheme であるため、schema なしで好きなものを定義して組み合わせられ、flexibility が高い

パッケージモデルとグラフ書き換え

  • Nix では、パッケージは stdenv.mkDerivation { ... } 呼び出しによって derivation を返す関数であり、その結果は不透明な attribute set である
  • Guix では、パッケージは <package> レコードであり、名前付きフィールドを持つ透明なデータ構造なので、標準の Scheme 手続きで検査、変換、結合できる
  • Guix の package definition は opaque functions ではなく transparent records なので、特別なツールなしで inspect と transform をプログラム的に実行できる
  • Guix では packages が data であるため、graph rewrites を容易に行える
  • Guix では package-input-rewriting によって依存関係グラフ全体を走査し、perlperl-minimal に置き換える処理を表現できる
  • Guix の inherit キーワードは、coreutils のすべてのフィールドを継承し、指定したフィールドだけを上書きする形でパッケージを再定義する
  • Nix には似た目的の overlays があるが、不透明な関数インターフェースのため検査や変換がより難しく、使い勝手が劣る

セキュリティ更新、ブートストラップ、認証

  • Guix の grafting は、すべての依存パッケージを再ビルドすることなく、依存関係ツリーにセキュリティ更新を適用できるようにする
  • glibc のような低レベルライブラリに脆弱性がある場合、Guix はストアパスを書き換えて修正版に置き換えられる
  • Nix はセキュリティ更新時にすべてを再ビルドし、依存関係ツリーが大きい場合はビルド時間に数時間の差が出ることがある
  • Guix は ソースベースのブートストラップ に強く注力しており、小さな信頼基盤からシステム全体をビルドできる
  • Guix のブートストラップチェーンは、約 500 バイトの hex assembler から始まり、Scheme で書かれた mes C コンパイラ、tcc、完全な GNU toolchain へと続く
  • bootstrappable builds プロジェクトは、完全なソースブートストラップの詳細を扱っている
  • Nix は Guix よりも多くのバイナリシードに依存している
  • ブートストラップチェーンを監査できなければ、システムが本当に意図したソースからビルドされたかを完全には検証できないため、完全なソースブートストラップは信頼性と検証可能性にとって重要である
  • Guix channels は 暗号学的認証 を標準でサポートしている
  • Guix channel は、特定のコミットとその Ed25519 署名から成る「introduction」を指定し、Guix はその introduction から現在のコミットまでの署名チェーン全体を検証する
  • Flakes は信頼モデルとして HTTPS と GitHub インフラを用いており、これは Guix の Ed25519 channel authentication とは異なるセキュリティモデルである

要約表の主要な対応関係

  • 依存関係の宣言では、Flakes は flake.nixinputs、Guix は channels.scm.guix-channel を使う
  • 依存関係の固定では、Flakes は自動・プロジェクト単位の flake.lock を使い、Guix はユーザー単位の自動 guix describe と、プロジェクト単位の手動コミット指定 channels.scm を使う
  • 純粋評価は flake mode で強制され、Guix では設計上の内在的特性である
  • 出力スキーマは、Flakes が outputs の構造化された attrset を使い、Guix は ad-hoc な Scheme records を使う
  • 開発環境は、Flakes が devShellsnix develop、Guix が manifest.scmguix shell を使う
  • システム構成は、Flakes が nixosConfigurations とモジュールシステム、Guix が operating-system とサービス DAG を使う
  • 1 コマンドでの再現性は、Flakes が nix build github:foo/bar、Guix が guix time-machine -C channels.scm -- build の形である
  • プロジェクト単位の固定は、Flakes が flake.lock で自動処理し、Guix がコミットを含む channels.scm で手動処理する
  • 探索性は、Flakes が nix flake show、Guix が Scheme モジュールの検査に依存する
  • パッケージモデルは、Flakes/Nix が不透明な関数、Guix が透明なレコードである
  • init system は、Nix が systemd、Guix が GNU Shepherd を使う
  • セキュリティ更新は、Nix が全面再ビルド、Guix が高速な grafting を使う
  • ブートストラップの信頼性は、Nix がバイナリシード、Guix が完全なソースブートストラップに基づく
  • 認証済み更新は、Flakes が HTTPS/GitHub への信頼、Guix が Ed25519 channel authentication を使う
  • FHS サポートは、Nix が buildFHSUserEnv、Guix が --emulate-fhs を提供する
  • 非 Linux サポートは、Nix が macOS 向けの nix-darwin、Guix が GNU Hurd に整理される
  • 自由ソフトウェア専用かどうかでは、Nix は専用ではなく構成可能であり、Guix は FSDG に準拠する

結論

  • Flakes と Guix は、再現性、依存関係管理、システム宣言という同種の問題を、異なるアーキテクチャ哲学で解決している
  • Flakes は、1 つのファイル、1 つのスキーマ、1 つのロックファイル、1 つの慣習の集合を備えた、単一機能に近い
  • Guix は、配布のための channels、環境のための manifests、構成のための operating-system、再現性のための guix time-machine、その他の構造のための Scheme records といった、直交するツール群の組み合わせである
  • 1 つの標準的なやり方、1 つのエントリーポイントファイル、1 つの出力スキーマ、1 つのロック形式を好むなら、Flakes が自然に合う
  • 小さく独立したツールを組み合わせ、それぞれのツールに 1 つのことをうまくやらせる Unix 哲学をパッケージ管理に適用するやり方を好むなら、Guix がよく合う
  • 両エコシステムは、パッケージ管理は関数型・宣言的・再現可能であるべきだという考えを中心に発展しており、異なる実装で同じアイデアを押し進めている

1件のコメント

 
GN⁺ 5 시간 전
Lobste.rs の意見
  • このサイトはモバイルだと読みにくすぎる。文字が少し小さいし、スクロールするたびにずっと邪魔してくる
    最初の比較以降は読めなかった。ずっと目次まで跳ね戻されるからだ

    • まったく読めない。ヨーヨーみたいに動く。最近本当に読みたかった記事の一つだったのに、過去最悪級のフラストレーションのたまる読書体験でがっかりした
    • デスクトップでも同じことが起きる。ありえないし、意図的にアクセシビリティを壊したように見える
  • 記事を読んでも、プロジェクトの依存関係をどう指定して固定すべきなのかまだよく分からない。配布して共有するには、channels.scm に各推移的依存関係のコミットハッシュを手動で調べて入れなければならないように見える
    time-machine は Guix パッケージ集合にしか動かず、ツリー外依存関係には効かないようだ
    nix run github:nixos/nixpkgs/<commit hash>#<package> のように、nixpkgs の過去時点のコードもかなり簡単に実行できる
    Guix が独特なのは、パッケージ集合のバージョンパッケージマネージャのバージョンを分離しない点だ。古いパッケージを動かそうとすると古い Guix リリースも一緒に動かすことになるが、なぜそれを望むのかよく分からない
    記事では flakes はコミットを手動で探して指定しなければならないと言いながら、その直後にコミットを指定しなければならない Guix コマンドを例に出している。Nix flake でも --override-input で nixpkgs バージョンを上書きできるが、これは雑で、だから unflake で改善しようとしている点の一つでもある

    • 筆者ほど Guix の使用経験はないが、ドキュメントはいくらか読んだのでいくつか答えてみる
      普通は専用の guix shell 環境で開発して、共有する段階になったら guix describe -f channels > channels.scm で全コミットハッシュを channels.scm に記録する流れだ
      declaring channel dependencies の文書を見ると依存関係のコミットは指定できるが、その依存先がさらに依存を持つ場合にそちらも特定コミットへ固定されているか検証するオプションはないようだ
      time-machine--commit= 表記は Guix チャネル向けだが、-C でファイルから追加のチャネルを読み込める
      パッケージマネージャとパッケージレコードに後方互換性を壊す変更が入っても、履歴と再現性を失わずに済む利点がある
    • そのために nixpkgs の逆引きインデックスを作れば可能だ。つまり、nixpkgs のコミット X から Y までが特定パッケージのバージョン A を含む、という形だ
      ただし各コミットごとに nixpkgs のチェックアウトが必要なので、最初の構築コストは非常に大きい。一度作れば、その後のインデックス維持コストは低いはずだ
  • サイトの問題とこのスレッドは coopi に伝えておいたので、すぐ直ることを願う
    完全に Guix 寄りの立場から言うと、coopi が言うように Guix にも Nix の flake.nixnix ディレクトリのような、すべてを収める標準ファイル/ディレクトリがあればいいと思う。ただ、Scheme モジュールを読み込むには正しいパスを指定しなければならないので、不可能かもしれない
    この Lobsters の記事には著者が言いたいことが入っているので、タグは nixlisp だけでも十分に思える

    • linux を外そうというのは説得力がない。両者に共通する唯一のカーネルなのだから :P ただ、言うとおり unix は合わないかもしれない
    • flakes のように、チャネルが何を提供するのかを自動推論する助けになる構造化チャネル型もあるとよい
      例えばこんな感じだ:
      (channel  
        (operating-systems  
          (list my-vm))  
        (services  
          (list my-system-service)))  
      
      そして新しいチャネルの作成や扱いを助ける guix channel コマンドもあるとよい
  • Guix にも Nix flake の .inputs.nixpkgs.follows のように、推移的依存関係の固定値を上書きする機能があるのか気になる
    また、著者の Guix 説明のかなりの部分は flakes 以前の Nix を思い起こさせる。標準エントリポイントがなく、チャネルを使う構造などだ。ただ、Guix には型システムと本物の言語があるので、同じパターンでも痛みは少ないように思える。Nix がもっと良かったか、別の言語だったら生まれていたかもしれないもう一つの歴史のように感じる

    • その機能は何に使うの?
  • 他のコメントで指摘されている使い勝手の問題のせいで、おすすめするのをためらう。私はデフォルトで JavaScript を無効化する NoScript を使っているので気づかなかった
    それでもこの記事はちょうど必要なタイミングで来た。会社で Nix をかなり使う方向に進んでいて、flakes のせいで少し苦労しているのだが、この記事の説明は以前読んだものよりずっと明快だった

    • Coopi によれば、JavaScript や CSS がなくても読めるようプログレッシブエンハンスメントに従うよう努力していて、JavaScript 側は壊してしまったが、少なくともその哲学自体は機能していたとのこと。今は JavaScript も修正されたはずだという
  • Coopi の回答: 今朝変更を入れたが仕事のためテストできておらず、調べてみるとJavaScript に問題があったとのこと

  • このサイトは iOS モバイルでは使えない。ページが下の方で読み込まれたあと即座に上へスクロールされるようで、1画面以上下へスクロールすると何かがトリガーされてまた上へ戻される
    リーダーモードなら動くが、ハイライトと元々かなり良かった細かなスタイリングが失われる

  • flakes のやっていることは Guix の複数のツールでもできると言うのは妥当だが、Nix にも同じ問題を解く小さく直交したツール群が以前からあり、今でもあることは押さえておくべきだ
    flakes が提供するのは標準プロジェクトエントリポイントと、それによって可能になるエコシステム、たとえばレジストリだ。記事でも Guix にはこの部分がないと言っている
    Guix ユーザーは標準エントリポイントは不要だと判断するかもしれないし、多くの Nix ユーザーもそう判断してきた
    しかし、直交的なツールセットで flakes はできると言うのは、FreeBSD は jail で必要なことは全部できるのだから OCI サポートは不要だ、という主張に似て聞こえる。標準化がエコシステムを可能にするという点を見落としている
    Guix に強い関心があり、多少の貢献もしてきたが、channels.scmguix time-machine を使ったビルドが、flake の固定値を変えて Nix 評価を行うよりなぜそんなに遅いのか比較してみたい。3倍程度遅い、たとえば 5〜10 秒が 15〜30 秒になるくらいなら受け入れられるが、私が試したときはそんなレベルではなかった