Skip to content

doc: Document "evaluation order", some strictness, equality quirk, ||, &&#14728

Merged
xokdvium merged 3 commits intoNixOS:masterfrom
roberth:doc-evaluation-infinite-recursion
Dec 7, 2025
Merged

doc: Document "evaluation order", some strictness, equality quirk, ||, &&#14728
xokdvium merged 3 commits intoNixOS:masterfrom
roberth:doc-evaluation-infinite-recursion

Conversation

@roberth
Copy link
Member

@roberth roberth commented Dec 7, 2025

Correct and clarify evaluation semantics including to help users understand Nix language behavior without unnecessarily pinning down the implementation.


Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

Correct and clarify evaluation semantics including to help users
understand Nix language behavior without unnecessarily pinning down
the implementation.
@xokdvium
Copy link
Contributor

xokdvium commented Dec 7, 2025

NaNs also suffer from pointer equality "optimization". Not sure it's worth mentioning. We could also maybe document the quirks of NaN <= NaN == true but NaN > NaN == false.

@xokdvium
Copy link
Contributor

xokdvium commented Dec 7, 2025

Also maybe the test suite could use some more attention to these details. I'm not 100% sure it covers all of these cases currently. NaNs and pointer equality tricks -- certainly not.

@roberth
Copy link
Member Author

roberth commented Dec 7, 2025

For sure that would be great, but I believe you are better informed about those NaN aspects.

@roberth roberth changed the title doc: Document "evaluation order", some strictness, equality quirk doc: Document "evaluation order", some strictness, equality quirk, ||, && Dec 7, 2025
Add tests for function equality covering both direct comparisons and
comparisons within composite types (lists and attribute sets).

Tests verify:
- Direct function comparisons always return false
- Value identity optimization in composite types allows identical
  functions to compare as equal when both references point to the
  same function value
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Dec 7, 2025
@roberth
Copy link
Member Author

roberth commented Dec 7, 2025

I've added the equality tests, thanks for reminding me of that!


- [Attribute sets][attribute set] and [lists][list] are compared recursively, and therefore are fully evaluated.
- Comparison of [functions][function] always returns `false`.
- [Attribute sets][attribute set] are compared first by attribute names and then by items until a difference is found.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

by attribute names

Might be a tad confusing, since attribute name order depends on the symbol table order and that can be a source of unsoundness. Not sure this is worth documenting yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we have an unsoundness problem, but a nondeterminism problem in terms of whether it succeeds to even evaluate or not, which is not a soundness problem if you define equality to be strict in deepSeq [a b].
But yeah. See that comment with "woeful" in it I guess.

Copy link
Contributor

@xokdvium xokdvium Dec 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nondeterminism problem in terms of whether it succeeds to even evaluate or not

Pretty much, yeah. It's deterministic in a sense that at least it doesn't change from one run to another for a particular nix version (modulo any sort of parallel evaluation that has been floating around). But for the user it might as well be unspecified and we must be able to add stuff to the static pre-filled symbol table, which will change attribute ordering anyway. It's a very messy situation to be in tbh if one wants to compare attribute sets deterministically.

This discussion opens up the notion that changing anything around which symbols get added to the symbol table and in which order have the opportunity to change what code succeeds to evaluate and which doesn't...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Value equality is something to avoid anyway, so maybe just make it alphabetic? Slightly slower, but problem solved.

If I may apologize in advance for this writing style while I have some fun...

Why bad, you may ask?

  • Equality is deeply strict
  • Equality is slow, as a consequence
  • If things are the same, you should probably already know
  • If things are the same, why did you put them in different places at all

"But I'm not comparing for equality, but values being unequal!"

  • Have you not learned from the French Revolution?
    • which one
  • If they're unequal wouldn't you want to know why?
  • If they're equal, that was bad

"But I have a functional key that's not a string, so I can use an attrset!"

  • You should still be comparing a derived key, because comparing the whole object is foolish and error prone
  • Presumably you have a list of these things? An association list. Those have O(n) lookup time, with costly equality every step of the way.

@xokdvium xokdvium added this pull request to the merge queue Dec 7, 2025
Merged via the queue into NixOS:master with commit 1d56f41 Dec 7, 2025
16 checks passed
@roberth
Copy link
Member Author

roberth commented Dec 7, 2025

Thanks!

@edolstra edolstra mentioned this pull request Dec 9, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation with-tests Issues related to testing. PRs with tests have some priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants