-
Notifications
You must be signed in to change notification settings - Fork 114
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggested improvements to NExpr #377
Comments
|
Should |
@infinisil I'm rather open to PRs for these suggestions. Perhaps doing them one at a time would be simplest? |
@Synthetica9 Nix has a primitive that retrieves source location for those things internal to the language, so they are semantically significant. The other source locations are used just for error reporting and such. It may be possible to unify them to some extent, but it's not quite as easy as one would hope. |
#666 (comment) is somewhat related. |
This comment has been minimized.
This comment has been minimized.
Just wanted to mention:
To formulate tersely: Any (majority) of smart constructor logic checking, even as simple mas uniqueness of keys in attrset, - is Eval which is of course before any corporeal Exec. So the threads talks about grammar strictly. |
Once started organizing, it is hard to stop. Somehow forgot to `bytestring 0.11`, thought we updated to it. During it found & made a couple of small optimizations here and there. And left notes for future to introduce breaking changes to provide more optimization. Some `NExprF` arguments need reordering (for performance) & synonymizing (for readability) (it is a close topic to the #377). Organization in `Parser`. Use of `liftA*` in it. Big reorganization in `Type.Infer`. Sprinkled with some docs here and there. declared `{AnnE, NExprLocF}` patterns as complete, which reduced a bunch of according bottoms & would allow GHC to optimize. Used `AnnE` pattern across the code, and added docs so it is understandable what it is.
So, 2.5 years in the making. I arrived to it. The major part of your proposition, several points of it depends on the - that binding key names should differentiate between static & dynamic, and a lot follows from that. I looked into the suggestion & so far have not understood the vector of them. Well, I understand the direction, I do not understand how abstractions align in the suggestion, there may be a typo around use of
🅸 ~/s/n/pkgs:master◦>nrg 'inherit.*\$'
pkgs/applications/kde/default.nix
inherit (srcs.${pname}) src version;
pkgs/stdenv/darwin/default.nix
inherit (pkgs."${finalLlvmPackages}") compiler-rt; So, I would agree with this: type StaticAttributes r = Map VarName (StaticAttributeValue r)
type DynamicAttributes r = [(NDynamicAttrPath r, r)] The current is: Lines 289 to 297 in f92a283
Separating statics from dynamics is a good idea & is a guide for further improvements. |
inherit (foo) bar baz; is Inherit (Just (NSym "foo")) ["bar", "baz"] The |
Thank you for correcting. That is true. |
Our discussion on ( By guys this was done in this low orbit ion cannon way, because the language allows:
there is a single case of its use inside Nixpkgs:
So there are indeed no dynamic keys inheritance, but there is this allowance to enclose a static key in Removing the dynamic key here is a proper action, but now VarName processing need to be expanded, or have a new abstraction simply for this quirk, otherwise, that quirk requires to split the It is not a feature. This is a quirk, unneeded language complication semantic & complicates the understanding of the type system to user (my exp) it is easier to refactor that line in Nixpkgs & reduce a bug. We must remember our main audience, it is Haskellers, they would appreciate the well-formed type system in the language. For HNix it is wiser & easier to "forget" (add the property of forgetful functor on these particular types of cases (quirks that are vacuous, rare & unused)) & just lint them out of existence (otherwise - get a feature report on it). Suggest users a cleaner code & give them the proper type (to guide (also ones who learn) through the language type system, as I know what it was like). I moved the |
Thread: #377 (comment) `inherit x y` in y` position always takes a variable name. Nix allows `inherit x "y"`, but there is no use (in the wild real life use) for it, it seems a misfeature and would be considered a quirk of the original type system/implementation, until the use case of it would be clear (which is hard, since there is a single use of it in Nixpkgs, which is mentioned in the thread).
Thread: #377 (comment) `inherit x y` in y` position always takes a variable name. Nix allows `inherit x "y"`, but there is no use (in the wild real life use) for it, it seems a misfeature and would be considered a quirk of the original type system/implementation, until the use case of it would be clear (which is hard, since there is a single use of it in Nixpkgs, which is mentioned in the thread).
regarding type DynamicVarName r = (Antiquoted (NString r) r)
NAttrPath -> newtype NStaticAttrPath (NonEmpty (VarName)) | newtype NDynamicAttrPath NonEmpty (DynamicVarName r)
data StaticAttributeValue r
= NamedVar [NKeyName r] r SourcePos
| Inherit (Maybe r) SourcePos
newtype StaticAttributes r = StaticAttributes (HashMap VarName (StaticAttributeValue r))
newtype DynamicAttributes r = DynamicAttributes [(NDynamicAttrPath r, r)]
data Bindings r = Bindings !(StaticAttributes r) (DynamicAttributes r) I started, but would finish a bit later - for obvious reasons. The data type change is massive, while also needs to land properly, types need to be chosen to keep instance inference & whole code needs to be refactored. If I would receive a hunch on the data types to use - would appreciate it. |
It looks like Nix treats
|
Yes, it has some simplification logic in the parser. Which has an impact on semantics, because it make it tolerate one level of dynamic attributes, but fail on nested ones.
See https://github.com/NixOS/nix/blob/e6150de90d8db101209fc6363f5f7696ee8192c4/src/libexpr/parser.y#L501-L522 and string_parts_interpolated. |
We can do it through additional abstraction & the very same But why? My current positionMy current way is refactoring (clean-up & simplification) of the code. I am interested in how clean & how far HNix code can go implementing the alike preferentially transparent language.This thread topic is "improvements to NExpr", not "how much of quirks we can duplicate". The quirks that need to be duplicated would show themselves during work. *these syntax quirks is what created deep puzzlement in me & strongly slowed the learning of the language. Wondering on every corner on these types of strange semantic inflaxions. So So since Keeping the language semantics simple & clean is a core piece to have a great productive language & tooling. For example - less code, simpler code, precise type inference. Keeping language semantics in check is especially important when we are having very limited resources. In other words - I am happy with the decision to put proper clear use & in the cases where the 99% of use is this way - we need to not imagine & give the Not every time I decide to reduce, for example I put a lot of effort in carefully preserving the builtins.replaceStrings ["" "e"] [" " "i"] "Hello world"
" H e l l o w o r l d " Is definitely not "a feature". If we'd to reduce it - the In short - those are obviously not features, those are bugs that are better (in an ideal situation) to not be there. "A feature" that is not used at all is generally a misfeature and can be reduced (not in terms of GNOME degree of feature removal). A good software design is to postpone this type of (especially this particular) decision until would be necessary to make a decision (if ever - reality would ask for it to be implemented). Haskell allows that path very much. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This commit takes-put the NApp out of NBinaryOp & places it as a proper citizen on NExprF. Addresses haskell-nix#1041 & haskell-nix#377.
[Binding r]
contains static and dynamic attributes, whereas static ones have to have a different key:[Antiquoted Text r]
, they should beNAttrPath
should differentiate between${a}.b.c
anda.b.c
with 2 different typesNStaticAttrPath
andNDynamicAttrPath
#977NBinary NApp f arg
, it should beNApp f arg
#1041NSet bindings
andNRecSet bindings
, it should be a singleNSet rec bindings
(first argument indicates it being recursive or not)Inherit !(Maybe r) ![NKeyName r] !SourcePos
should beInherit !(Maybe r) ![VarName] !SourcePos
#976Maybe other improvements are possible too. I really dislike how some things are representable using the current one but never occur in parsing Nix.
The text was updated successfully, but these errors were encountered: