| 12 Dec 2025 |
emily | (I agree that raw identifier reference syntax is preferable to banning raw identifier binding) | 11:28:25 |
helle (just a stray cat girl) | It will be interesting to do any nixlang2 work in such a way that in addition to writing the spec, we at the same time write the tutorial for people who have never touched nix (and aren't functional language or compiler nerds, etc), because this would show things that are hard to explain to beginners | 11:35:03 |
helle (just a stray cat girl) | and note, if you can write something differently to what you tell beginners, they still need to be able to understand what is written | 11:35:24 |
emily | lazy evaluation is going to be a tough one no matter what (and intimately tied to the nested fixed point structures the package set and module system builds up). in some ways easier to explain to someone without an (imperative) programming background than with | 12:56:15 |
emily | the combination with dynamic typing has the fun side effect of burying errors as deep/late as possible and also making it much harder to trace the causes of them, which is just an awful property for learners | 12:58:24 |
teo (they/he) | fwiw some of the spooky fixed point stuff can be explained to people in terms of inheritance which is a bit more familiar sometimes | 13:11:11 |
teo (they/he) | * fwiw some of the spooky fixed point stuff can be explained to people in terms of inheritance which is a bit more familiar sometimes. although that assumes people actually understand that :) | 13:11:49 |
emily | I think you can get some way with that for the way the package set is built up from overlays, but it's a bit weird since you're talking about using the already-esoteric mixins to form an inheritance chain and even that fails to capture why attrsets being strict in their keys causes tons of infrec unless you're careful
(admittedly one can ignore much of this for most use, but same applies to the vast majority of the Nix language)
| 13:28:56 |
emily | for the module system... I think the analogy is hard to stretch | 13:29:13 |
emily | it is very much taking fixed points of a Weird Monoid | 13:29:44 |
emily | with in fact multiple layers of monoidal structure (merging of module definitioms, overrides, and the individual option types and their merge operations) and where the definitions for some of the monoids involved are themselves part of the values the monoidal structure applies to and also these pervasively recurse into each other 🤪 | 13:32:58 |
emily | I suspect the median NixOS user models each definition in their configuration modules as essentially imperative mutation of global state | 13:34:36 |
teo (they/he) | the module system is a monster! but it is very convenient | 13:34:38 |
emily | which works right up until it really doesn't | 13:34:53 |
emily | it would be fun to see the module system modelled in Haskell including the part where you have mutually recursive options and config where the former define the types for the latter. I suspect you can pull it off with enough {-# LANGUAGE #-} | 13:37:04 |
Arian | https://cuelang.org/docs/concept/the-logic-of-cue/ | 13:39:11 |
Arian | imo cue comes pretty darn close | 13:40:57 |
emily | isn't CUE explicitly dynamically-typed? | 13:48:20 |
emily | I suspect Nickel might be doing something closer | 13:48:59 |
Arian | Depends on what you mean with dynamically typed. It’s a lattice. So you can do static analysis by merging with an abstracter lattice | 13:51:34 |
emily | (I know types-as-values/more general dependent typing can make this a fuzzy question already because you have type-checking recursing into evaluation, so for clarity I mean "you cannot type-check an expression with a free variable of known type but unknown value, right?" - but I could be wrong.) | 13:52:22 |
Arian | the static-ness of a defintion is a nice partial order with types at the top and uninhabited values at the bottom. Slice the lattice was much as yo need | 13:52:23 |
emily | right... I guess you can try evaluating by just setting the variable to its type. hmm... | 13:52:46 |
Arian | yes… or to a static constraint | 13:53:03 |
emily | IIRC CUE has limited control flow, right? I am not sure if the properties would scale to making it a "real PL" | 13:53:45 |
emily | e.g. I don't see how you could typeck a recursive branching function in this way | 13:54:15 |
emily | which sort of scuppers it as a model for Nix | 13:54:24 |
emily | eh, maybe you could with enough memoization. wouldn't work for polymorphic recursion but that's a high bar. | 13:55:11 |
Arian | cue doesn’t have functions. it’s more a model of the NixOS module system; not of nix | 13:55:12 |
Arian | my thesis is that nix is a terrible host language for the NixOS module system :P | 13:55:20 |