-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
PoC for RFC145: dynamic documentation for lambdas #8778
Conversation
Co-authored-by: sterni <sternenseemann@systemli.org>
I checked out your branch, added two builtins: (Thanks @roberth; @asymmetric for your help, Thx @sternenseemann)
-> hsjobeki/nix/lambda-docstring Almost all test cases are working, and we'll bootstrap a user guide with a bunch of examples here this week. To support the ( last?) edge case we need: #8968. For record, this edge case beeing:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Five years from now we'll look back on builtins.unsafeGetLambdaDoc
the way we look back on Nix function equality today.
... yeah but it seemed like such a useful trick at the time!
void prim_unsafeGetLambdaDoc(EvalState & state, const PosIdx pos, Value * * args, Value & v) | ||
{ | ||
state.forceFunction(*args[0], pos, "while evaluating the first argument to builtins.unsafeGetLambdaDoc"); | ||
|
||
Pos funPos = state.positions[args[0]->lambda.fun->pos]; | ||
|
||
Comment::Doc doc = Comment::lookupDoc(funPos); | ||
|
||
if(doc.comment.empty()) { | ||
v.mkNull(); | ||
} else { | ||
v.mkString(doc.comment); | ||
} | ||
} | ||
|
||
static RegisterPrimOp primop_unsafeGetLambdaDoc(PrimOp { | ||
.name = "__unsafeGetLambdaDoc", | ||
.arity = 1, | ||
.fun = prim_unsafeGetLambdaDoc, | ||
}); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be behind an --experimental
flag to prevent it from being used in nixpkgs.
I do know it is a bad implementation. We should definetly not merge it. It was just for playing around with position tracking. @sternenseemann can you close this PR to prevent people from thinking we should merge it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do know it is a bad implementation. We should definetly not merge it. It was just for playing around with position tracking.
Oh I don't think so!
I just want to make sure we don't make promises that can't be kept in the future.
What do you think about the change below? It basically requires that you must use nix-instantiate
with --eval
and without --read-write-mode
in order to introspect on documentation comments. This means you can't produce derivations, but you can do anything else, including dumping out JSON which other tools then consume.
Would this conflict with any of your envisioned use cases?
If so I'd like to talk about those use cases to understand them better.
My two main concerns are:
-
Small concern: philosophical. Comments are supposed to be... comments. Like, changing them doesn't affect the execution of the program. This is a minor concern though.
-
Bigger concern: making sure that we can "compile-out" doc comment support for use on really big build clusters, like Hydra.
If we disallow writing to the store in doc-comment-introspection-mode, then we don't have to worry about the performance impact of doc-comments at all. For high-performance implementations like tvix we can have a #cfg[doc-comments]
(basically Rust's version of #ifdef
) and compile the interpreter twice: one version that goes really fast and omits any extra fields needed for tracking doc-comments, and another version that can handle doc-comments that are as rich as you like. By not allowing derivations to be created in doc-comments mode we guarantee that nixpkgs can always be built using the high-performance interpreter.
Then you won't have to worry about performance at all when designing this feature. It should give you a lot more freedom.
@@ -2439,6 +2440,27 @@ static RegisterPrimOp primop_unsafeGetAttrPos(PrimOp { | |||
.fun = prim_unsafeGetAttrPos, | |||
}); | |||
|
|||
void prim_unsafeGetLambdaDoc(EvalState & state, const PosIdx pos, Value * * args, Value & v) | |||
{ | |||
state.forceFunction(*args[0], pos, "while evaluating the first argument to builtins.unsafeGetLambdaDoc"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
state.forceFunction(*args[0], pos, "while evaluating the first argument to builtins.unsafeGetLambdaDoc"); | |
if (!settings.readOnlyMode) { | |
throw Error("attempted to introspect on documentation comments in derivation-producing mode"); | |
} | |
state.forceFunction(*args[0], pos, "while evaluating the first argument to builtins.unsafeGetLambdaDoc"); |
Yes, I think it should be behind some secure flags. Currently, we might need to rethink the idea with the new builtins. The new idea would be to have that feature as a nix command (e.g.
|
I think that's a great idea. Also the After thinking a lot about this, the only place I see trouble would be if we added |
Hi @sternenseemann, |
Ref. NixOS/rfcs#145.
The first commit is a faithful rebase of #1652. The later commits change the approach to conform with our more modern ideas and also add everything we'd need to hypothetically generate nixpkgs' documentation using a pure Nix expression.
Currently unfinished:
/** … */
comments:doc
commandbuiltins.unsafeGetLambdaDoc
builtins.unsafeGetAttrDoc
(some work already done)lib
tree walker.Context