关于 Nix 包管理的 Nix 表达式是什么?

tor*_*tte 5 nix

即使在阅读了 Nix 手册之后,仍然对 Nix 表达式的真正含义感到困惑。有时它们被称为派生,但存储派生也有其他含义。

Dav*_*son 5

在 Nix 中,Nix 表达式只是您可以用 Nix 语言编写的任何类型值的通用术语。Nix 表达式可以是集合、列表、数字、字符串、函数、名称、算术运算、函数调用等等。

Nix 表达式可以包含其他 Nix 表达式:例如,表达式1 + 2内部包含两个表达式:12

人们通常喜欢编写复杂的 Nix 表达式来表示如何构建一个软件。这些表达式实际上只是具有一些特殊属性的集合。Nix 软件可以计算这样的表达式并将其转换为文件.drv(一种描述如何构建某些软件的非常简单、紧凑的方式),然后可以构建该文件。

您可以使用 Nix 语言和 Nix 表达式做很多不涉及派生或构建软件的事情。该nix eval命令允许您计算 Nix 表达式。运行nix eval --help以查看其帮助屏幕,或运行以下命令来计算一些简单的表达式:

nix eval '(1 + 2)'  # gives 3

nix eval '({ a = 1; b = 2; }.a)'  # gives 1
Run Code Online (Sandbox Code Playgroud)

(出于某种原因,此命令似乎要求在其计算的大多数 Nix 表达式周围添加括号,但这似乎是一个错误或奇怪的设计选择,并且括号并不是每个 Nix 表达式的重要组成部分。)


tor*_*tte 2

Nix 表达式 是一组指令,描述如何使用 Nix 纯函数式语言构建软件组件(包、项目、应用程序等)。

引用 Gabriel Gonzalez 的话:“你可以将派生视为与语言无关的如何构建某些东西(例如 Haskell 包)的方法。


Nix 表达式通常也称为 推导 (如 Nix 推导表达式),但是

*------------------------------------------------------*
|                                                      |
|       STORE DERIVATION =/= NIX EXPRESSION            |
|                                                      |
*------------------------------------------------------*
|                                                      |
| NIX EXPRESSION == function                           |
|                                                      |
| ( Describes how to build a component. That is, how ) |
| ( to  compose  its  input parameters, which can be ) |
| ( other components as well.                        ) |
|                                                      |
| STORE DERIVATION == function application             |
|                                                      |
| ( Call a  Nix  expression with concrete arguments. ) |
| ( Corollary: a single Nix  expression  can produce ) |
| ( different derivations depending on the inputs.   ) |
|                                                      |
*------------------------------------------------------*
Run Code Online (Sandbox Code Playgroud)

Nix 表达式的目的是生成 可以构建到组件(可执行文件、库等)中的存储派生。

对于上下文:

Nix 表达式的两阶段构建。 nix-instantiate 将 Nix 表达式转换为存储派生,而 nix-store --realize 将派生构建到软件组件中。

图片取自Eelco Dolstra 的博士论文,“2.4 Store derivations”部分。

额外的

Nix 表达式的标准形式

根据Eelco Dolstra 博士论文中的“5.4 Translated Nix statements to store derivations”一节:

[Nix 表达式] 的正常形式应该是

  • 致电derivation, 或

  • 包含对 的调用的列表和属性集的嵌套结构derivation

无论如何,这些派生 Nix 表达式随后会被翻译为存储派生。

什么是软件组件?

软件包、应用程序、开发环境、软件库等。

更正式地来自“3.1 什么是组件?” 在Eelco Dolstra 的博士论文中:

A software component is                      

    *-------------------------------------*
1.  | a software artifact that is subject |
    | to automatic composition            |
    *-------------------------------------*

    It can require, and be required by,   
    other components.                     

    *----------------------*              
2.  | a unit of deployment |              
    *----------------------*    
Run Code Online (Sandbox Code Playgroud)

(整个部分都值得阅读。)

  • 不,Nix 表达式实际上是用 Nix 语言表达的任何值或函数。您的定义太狭窄,并且与[Nix手册](https://nixos.org/nix/manual/#chap-writing-nix-expressions)中的句子相矛盾,例如“集合只是键的列表/值对,其中每个键是一个字符串,每个值是任意 Nix 表达式。”。Nix 表达式可以是集合、数字、字符串和列表等内容;它们并不全是派生词。 (3认同)
  • 值得一提的是[ATerms](https://homepages.cwi.nl/~daybuild/daily-books/technology/aterm-guide/aterm-guide.html),它是推导文件的格式。Nix 编程语言只是生成 ATerm 的一种(但不是唯一)方法。正如[此处](http://www.haskellforall.com/2017/11/compare-nix-derivations-using-nix-diff.html)所述,GUIX项目使用Guile而不是Nix生成ATerms。 (2认同)