conjure icon indicating copy to clipboard operation
conjure copied to clipboard

`K` (`doc-str`) does not work with `hy`

Open jsquaredosquared opened this issue 2 months ago • 4 comments

First of all, thanks for this amazing tool!

As the title says, looking up the documentation with K does not work in Hy. I think the problem is this section using outdated Hy features:

https://github.com/Olical/conjure/blob/dab027e0cb710beb070424a117b9065279f6083d/fnl/conjure/client/hy/stdio.fnl#L88-L90

The following changes could make it work, though I haven't been able to test it:

        code (.. "(if (in (hy.mangle '" obj ") _hy_macros)
                    (help (get _hy_macros (hy.mangle '" obj ")))
                    (help " obj "))")]

Explanation of changes:

  • mangle now is in the hy namespace; without importing, it can be accessed like hy.mangle
  • --macros-- no longer exists; I think the equivalent is now _hy_macros
  • doc no longer exists; to get help for macros, first the object must be mangled and the result used to look up the function object in _hy_macros

I tried following the instructions in CONTRIBUTING.md, but the docker environment installs a version of Neovim that is no longer supported by Conjure. (Running sudo apt show neovim on 24.04 returns version 0.9.5-6ubuntu2).

I would appreciate it if you could look into these issues.

Thanks :D

jsquaredosquared avatar Nov 08 '25 14:11 jsquaredosquared

Thanks for raising this and explaining it. I've made the changes you suggested and tested them out inside Conjure and the REPL (I fetched Hy from the Arch repos so I think it's the latest).

Seemed to work as expected, I could get (help ...) for things like print, my custom functions and my custom macros. It didn't work for built ins like if etc but I'm not sure if that's expected. In Clojure and some other LISPs the help system can introspect language built ins like that, if you're supposed to be able to do that in Hy somehow maybe we could include that too.

The changes you suggested are pushed to the main branch.

Olical avatar Nov 09 '25 12:11 Olical

Thanks for the quick fix.

I just found out that the code can be simplified using the get-macro syntactic sugar (e.g., (help (get-macro ->)) -- no need for quoting the object or mangling and dictionary lookup).

As for the builtins, I think the way they are implemented means that they do not have any docstrings attached. For example, running (help (get-macro if)) works, but the "help" it returns is just the signature of the implementation. This is for the builtin if Hy macro. Running (help "if") returns help for the Python builtin if.

Another thing is that if the macro is a reader macro, the invocation to get-macro has to be modified slightly: e.g., (help (get-macro :reader $)). Furthermore, while local macros can be looked up in _hy_macros and _hy_reader_macros, builtin macros are accessed separately in builtins._hy_macros and builtins._hy_reader_macros.

jsquaredosquared avatar Nov 09 '25 14:11 jsquaredosquared

I just found out that the code can be simplified using the get-macro syntactic sugar (e.g., (help (get-macro ->)) -- no need for quoting the object or mangling and dictionary lookup).

Looks like this is either a compile-time or parse-time macro and the error cannot be caught, so best not to use it.

I don't see any way other than a series of nested checks:

"(let [mangled-name (hy.mangle '" obj ")]
  (try (help (get hy.I.builtins._hy_macros mangled-name))
       (except [KeyError]
               (try (help (get hy.I.builtins._hy_reader_macros mangled-name))
                    (except [KeyError]
                            (try (help (get _hy_macros mangled-name))
                                 (except [KeyError]
                                         (try (help (get _hy_reader_macros mangled-name))
                                              (except [KeyError]
                                                      (try (help " obj ")
                                                           (except [NameError] (help #[[" obj "]]))))))))))))"

jsquaredosquared avatar Nov 09 '25 15:11 jsquaredosquared

Sorry, this is probably a better way:

"(let [mangled-name (hy.mangle '" obj ")]
  (cond (in mangled-name _hy_macros) (help (get _hy_macros mangled-name))
        (in mangled-name _hy_reader_macros) (help (get _hy_reader_macros mangled-name))
        (in mangled-name hy.I.builtins._hy_macros)
          (help (get hy.I.builtins._hy_macros mangled-name))
        (in mangled-name hy.I.builtins._hy_reader_macros)
          (help (get hy.I.builtins._hy_reader_macros mangled-name))
        True (try (help " obj ") (except [NameError] (help mangled-name)))))"

(p.s., the # would have to be stripped from obj if obj is a reader macro)

jsquaredosquared avatar Nov 09 '25 15:11 jsquaredosquared