From e660a3935e1d91b27347ece794cd120fe8b06330 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anselm=20Sch=C3=BCler?= Date: Thu, 26 May 2022 17:50:24 +0200 Subject: [PATCH] [RFC 0126] Standardize magic properties --- rfcs/0126-standardize-magic-properties.md | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 rfcs/0126-standardize-magic-properties.md diff --git a/rfcs/0126-standardize-magic-properties.md b/rfcs/0126-standardize-magic-properties.md new file mode 100644 index 000000000..e4288bb83 --- /dev/null +++ b/rfcs/0126-standardize-magic-properties.md @@ -0,0 +1,81 @@ +--- +feature: standardize-magic-properties +start-date: 2022-05-26 +author: Anselm Schüler +co-authors: None +shepherd-team: None +shepherd-leader: None +related-issues: None +--- + +# Summary +[summary]: #summary + +Rename attrset attribute names treated specially by Nix to start with a double underscore. +Add a builtin function `guardMagic` that returns `null` for double underscore prefixed strings. + +# Motivation +[motivation]: #motivation + +Nix treats many attributes specially with unique behaviours. Some of these are prefixed with double underscores to disambiguate them from everything else. But some aren’t: `recurseForDerivations` isn’t, `type`, when set to `"derivation"`, changes visual output. + +It would also be a good idea to avoid accidentally using reserved special attribute names. Therefore I suggest `guardMagic` that can be used in dynamic attribute names to avoid this. + +# Detailed design +[design]: #detailed-design + +Properties treated specially by the Nix tools and Nix language when dealing with arbitrary are renamed to start with a double underscore. Instances where this is not necessary are `__functor` and `__toString`. `recurseForDerivations` is renamed `__recurseForDerivations` and `type` is renamed `__type`. + +A new builtin function is introduced, `builtins.guardMagic`. +If called on a string, it returns the string if it does not start with a double underscore, and `null` otherwise. This can be used by semantically charged non-generic functions that update attrs dynamically to avoid unwanted interactions. + +Nixpkgs & Nix need to be updated to reflect this. Therefore, it may be advisable to have a grace period during which unprefixed magic properties are still supported, but warn. + +# Examples and Interactions +[examples-and-interactions]: #examples-and-interactions + +```nix +rec { + set-val-to-null = k: attrs: attrs // { + ${guardMagic k} = null; + }; + x = set-val-to-null "__functor" { __functor = _: _: { }; }; + y = set-val-to-null "y" { __functor = _: _: { }; }; +} +``` +evaluates to +```nix +{ + set-val-to-null = «lambda»; + x = { __functor = «lambda»; }; + y = { y = null; __functor = «lambda»; }; +} +``` + +# Drawbacks +[drawbacks]: #drawbacks + +- This change is backwards-incompatible +- This requires judging if certain properties count as magic attributes + +# Alternatives +[alternatives]: #alternatives + +- `guardMagic` could be introduced on its own, thereby complicating its implementation +- These could be left alone + +# Unresolved questions +[unresolved]: #unresolved-questions + +I honestly don’t have a full list of these magic names, I only listed the ones I know about. + +It’s also unclear what exactly counts. I think attrsets passed to functions as de-facto named arguments shouldn’t count (e.g. for `derivation`). You could even argue the outputs of `listToAttrs` should be prefixed! + +The name of `guardMagic` might need some work. + +# Future work +[future]: #future-work + +This eases introduction of any future magic names. + +It can also be assumed the implementation of `guardMagic` won’t need to be updated if this standard naming convention is adhered to.