Skip to content
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

FUNCTIONNAME inside a function that generates the docstring #149

Open
ArnoStrouwen opened this issue Feb 21, 2023 · 7 comments
Open

FUNCTIONNAME inside a function that generates the docstring #149

ArnoStrouwen opened this issue Feb 21, 2023 · 7 comments

Comments

@ArnoStrouwen
Copy link

Is it possible to get FUNCTIONNAME to work inside a function that generates the docstring? Something similar to

function gen_docstring()
    """
        $(FUNCTIONNAME)(x)
    """
end
@doc gen_docstring()
function f(x)
    x
end
@MichaelHatherly
Copy link
Member

Unlikely to ever be something that's doable due to how the docsystem's macros work.

You could implement a separate version of @doc that inspects the function expression, pulls out the function name and then implicitly passes it as an argument to gen_docstring where you can then use it, which would avoid having to repeat the function name.

What is it you're trying to do with the gen_docstring function? There might be a completely different approach that is workable within the current system.

@mortenpi
Copy link
Member

It came up here: SciML/OrdinaryDiffEq.jl#1866

@MichaelHatherly
Copy link
Member

Ah, thanks for the link.

@mortenpi
Copy link
Member

In reference to SciML/OrdinaryDiffEq.jl#1866 (comment), I don't think an @template would be sufficient for that use case. I would assume that, in general, you might have different templates for different groups of functions. But an @template template would apply to all functions (in a module), if I understand its behavior correctly?

Any thoughts on how we could apply different templates to different groups within a module? The only thing that crosses my mind right now is, as you suggested, re-implementing macro doc ... end in the module. This seems to work, in that it actually takes precedence, but you still have to call out to the Base.Docs version eventually.

With a custom @doc, one potential interface could be to just add "functions as docstrings", that take the documented expression as an argument, and generate the docstring:

macro doc ... end
function my_docstring_generator(ex)
     return "..."
end

@doc my_docstring_generator
function foo end

Closures could maybe be used to add local parameters (like the unique parts of a docstring):

function my_docstring_generator(s)
     ex -> begin
          return "... $s"
     end
end

@doc my_docstring_generator("this function foos")
function foo end

And the custom @doc macro could potentially live here in DocStringExtensions in some form.

@MichaelHatherly
Copy link
Member

I would assume that, in general, you might have different templates for different groups of functions. But an @template template would apply to all functions (in a module), if I understand its behavior correctly?

So maybe the question we need to answer then is how should we mark a particular function/type/thing as being part of a specific group. Once we have that, then getting the template system to handle arbitrary groups would be relatively simple.

Custom @doc seems to me to be a bit much. I don't think it's machinery that package authors should be overridden in that way.

Perhaps just a way to mark a specific docstring as using a particular template would work, e.g.

const CUSTOM_TEMPLATE = @template(
   """
   $SIGNATURE

   $DOCSTRING
   """
)

"""
$CUSTOM_TEMPLATE

...
"""
function func_1()
end

"""
$CUSTOM_TEMPLATE

...
"""
function func_2()
end

And then when we encounter a docstring that happens to be interpolating a Template object like that we expand it to use that template prior to expanding the resulting templated interpolations.

@mortenpi
Copy link
Member

Custom @doc seems to me to be a bit much. I don't think it's machinery that package authors should be overridden in that way.

Yeah, agreed, this feels a bit hacky.

I like the CUSTOM_TEMPLATE approach, if that can be made to work with the DocStringExtension hook. Do you think this could, in principle, be generalized to something that would take e.g. a function callback, so that the user could generate the docstring completely themselves? E.g. something like

const CUSTOM_TEMPLATE = template() do docstring, documented_expr
    ... # returns a String? Markdown.MD?
end

I am not sure if DocStringExtensions has access to the expression you're documenting. I guess it must, since it needs to determine the function names, and arguments, and such?

@MichaelHatherly
Copy link
Member

Do you think this could, in principle, be generalized to something that would take e.g. a function callback, so that the user could generate the docstring completely themselves? E.g. something like

Possibly.

I am not sure if DocStringExtensions has access to the expression you're documenting. I guess it must, since it needs to determine the function names, and arguments, and such?

We do now capture the expression (#133), but all the names, arguments, etc. are being looked up via runtime reflection since that's how it originally was done, and for some data it's probably best to continue using it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants