-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
:doc: support __functor
#11304
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
:doc: support __functor
#11304
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| Nix <nix version> | ||
| Type :? for help. | ||
|
|
||
| nix-repl> :l doc-functor.nix | ||
| Added <number omitted> variables. | ||
|
|
||
| nix-repl> :doc multiplier | ||
| Function `__functor`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:12:23 | ||
|
|
||
|
|
||
| Multiply the argument by the factor stored in the factor attribute. | ||
|
|
||
| nix-repl> :doc doubler | ||
| Function `multiply`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:5:17 | ||
|
|
||
|
|
||
| Look, it's just like a function! | ||
|
|
||
| nix-repl> :doc recursive | ||
| Function `__functor`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:77:23 | ||
|
|
||
|
|
||
| This looks bad, but the docs are ok because of the eta expansion. | ||
|
|
||
| nix-repl> :doc recursive2 | ||
| error: | ||
| … while partially calling '__functor' to retrieve documentation | ||
|
|
||
| … while calling '__functor' | ||
| at /path/to/tests/functional/repl/doc-functor.nix:85:17: | ||
| 84| */ | ||
| 85| __functor = self: self.__functor self; | ||
| | ^ | ||
| 86| }; | ||
|
|
||
| … from call site | ||
| at /path/to/tests/functional/repl/doc-functor.nix:85:23: | ||
| 84| */ | ||
| 85| __functor = self: self.__functor self; | ||
| | ^ | ||
| 86| }; | ||
|
|
||
| (19999 duplicate frames omitted) | ||
|
|
||
| error: stack overflow; max-call-depth exceeded | ||
| at /path/to/tests/functional/repl/doc-functor.nix:85:23: | ||
| 84| */ | ||
| 85| __functor = self: self.__functor self; | ||
| | ^ | ||
| 86| }; | ||
|
|
||
| nix-repl> :doc diverging | ||
| error: | ||
| … while partially calling '__functor' to retrieve documentation | ||
|
|
||
| (10000 duplicate frames omitted) | ||
|
|
||
| … while calling '__functor' | ||
| at /path/to/tests/functional/repl/doc-functor.nix:97:19: | ||
| 96| f = x: { | ||
| 97| __functor = self: (f (x + 1)); | ||
| | ^ | ||
| 98| }; | ||
|
|
||
| error: stack overflow; max-call-depth exceeded | ||
| at /path/to/tests/functional/repl/doc-functor.nix:97:26: | ||
| 96| f = x: { | ||
| 97| __functor = self: (f (x + 1)); | ||
| | ^ | ||
| 98| }; | ||
|
|
||
| nix-repl> :doc helper | ||
| Function `square`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:36:12 | ||
|
|
||
|
|
||
| Compute x^2 | ||
|
|
||
| nix-repl> :doc helper2 | ||
| Function `__functor`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 | ||
|
|
||
|
|
||
| This is a function that can be overridden. | ||
|
|
||
| nix-repl> :doc lib.helper3 | ||
| Function `__functor`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 | ||
|
|
||
|
|
||
| This is a function that can be overridden. | ||
|
|
||
| nix-repl> :doc helper3 | ||
| Function `__functor`\ | ||
| … defined at /path/to/tests/functional/repl/doc-functor.nix:45:23 | ||
|
|
||
|
|
||
| This is a function that can be overridden. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| :l doc-functor.nix | ||
| :doc multiplier | ||
| :doc doubler | ||
| :doc recursive | ||
| :doc recursive2 | ||
| :doc diverging | ||
| :doc helper | ||
| :doc helper2 | ||
| :doc lib.helper3 | ||
| :doc helper3 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| rec { | ||
| /** | ||
| Look, it's just like a function! | ||
| */ | ||
| multiply = p: q: p * q; | ||
|
|
||
| multiplier = { | ||
| factor = 2; | ||
| /** | ||
| Multiply the argument by the factor stored in the factor attribute. | ||
| */ | ||
| __functor = self: x: x * self.factor; | ||
| }; | ||
|
|
||
| doubler = { | ||
| description = "bla"; | ||
| /** | ||
| Multiply by two. This doc probably won't be rendered because the | ||
| returned partial application won't have any reference to this location; | ||
| only pointing to the second lambda in the multiply function. | ||
| */ | ||
| __functor = self: multiply 2; | ||
| }; | ||
|
|
||
| makeOverridable = f: { | ||
| /** | ||
| This is a function that can be overridden. | ||
| */ | ||
| __functor = self: f; | ||
| override = throw "not implemented"; | ||
| }; | ||
|
|
||
| /** | ||
| Compute x^2 | ||
| */ | ||
| square = x: x * x; | ||
|
|
||
| helper = makeOverridable square; | ||
|
|
||
| # Somewhat analogous to the Nixpkgs makeOverridable function. | ||
| makeVeryOverridable = f: { | ||
| /** | ||
| This is a function that can be overridden. | ||
| */ | ||
| __functor = self: arg: f arg // { override = throw "not implemented"; overrideAttrs = throw "not implemented"; }; | ||
| override = throw "not implemented"; | ||
| }; | ||
|
|
||
| helper2 = makeVeryOverridable square; | ||
|
|
||
| # The RFC might be ambiguous here. The doc comment from makeVeryOverridable | ||
| # is "inner" in terms of values, but not inner in terms of expressions. | ||
| # Returning the following attribute comment might be allowed. | ||
| # TODO: I suppose we could look whether the attribute value expression | ||
| # contains a doc, and if not, return the attribute comment anyway? | ||
|
Comment on lines
+51
to
+55
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hsjobeki What do you think?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes. But functors are polymorph. I would show (maybe concatenate) both, or add an option for the user to decide what he is interested in. As a user i would expect The property that the function is wrapped with
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For example this one edge case that i couldn't solve on a value level, because lamdbas are opaque. If you try to unwrap this at the value level: Maybe we need some annotation for higher order functions like this. (like |
||
|
|
||
| /** | ||
| Compute x^3 | ||
| */ | ||
| lib.helper3 = makeVeryOverridable (x: x * x * x); | ||
|
|
||
| /** | ||
| Compute x^3... | ||
| */ | ||
| helper3 = makeVeryOverridable (x: x * x * x); | ||
|
|
||
|
|
||
| # ------ | ||
|
|
||
| # getDoc traverses a potentially infinite structure in case of __functor, so | ||
| # we need to test with recursive inputs and diverging inputs. | ||
|
|
||
| recursive = { | ||
| /** | ||
| This looks bad, but the docs are ok because of the eta expansion. | ||
| */ | ||
| __functor = self: x: self x; | ||
| }; | ||
|
|
||
| recursive2 = { | ||
| /** | ||
| Docs probably won't work in this case, because the "partial" application | ||
| of self results in an infinite recursion. | ||
| */ | ||
| __functor = self: self.__functor self; | ||
| }; | ||
|
|
||
| diverging = let | ||
| /** | ||
| Docs probably won't work in this case, because the "partial" application | ||
| of self results in an diverging computation that causes a stack overflow. | ||
| It's not an infinite recursion because each call is different. | ||
| This must be handled by the documentation retrieval logic, as it | ||
| reimplements the __functor invocation to be partial. | ||
| */ | ||
| f = x: { | ||
| __functor = self: (f (x + 1)); | ||
| }; | ||
| in f null; | ||
|
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.