Is there a way to view a function's source code from within the Racket REPL?
Asked Answered
C

3

7

I'm currently trying to dive into Racket/Scheme a bit. I have an instance of the (X)REPL running next to my editor, which helps me immensely to explore the language. However, I can't seem to find an XREPL command or macro (or whatever) which would show me the source code of a function.

All the needed parts seem to be there:

XREPL's describe command knows the file:

-> ,describe string-join
; `string-join' is a bound identifier,
;   defined in racket/string.rkt
;   required directly

and get-collects-search-dirs knows the path:

-> (require setup/dirs)
-> (get-collects-search-dirs)
'(#<path:/home/richard/.racket/5.2.1/collects>
  #<path:/usr/local/lib/racket/collects>)

And on the reflection side of things we have:

-> (procedure-arity string-join)
2

But it all stops short of being useful if all you want to know is how to call the function. Is there a way to access the function's implementation, or at least the parameter names?

Or, which would also work for me - some kind of in-REPL plain text equivalent of the documentation that help opens?

Casebound answered 11/4, 2012 at 21:30 Comment(0)
D
5

A couple weeks ago the XREPL ,describe command was enhanced to print the function argument names and contract; source.

This is the "blue box" from Racket documentation -- so called because they used to be blue before the Racket 6 CSS redesign; now they're actually grey :).

You can get this by building Racket from HEAD. Otherwise, it should be in the next release after 6.1.

Keep in mind that this appears to be limited to functions that have Scribble documentation in installed packages.

Disruption answered 11/8, 2014 at 15:0 Comment(1)
accepted this one now since ,describe is in 6.1.1 and does exactly what I wanted - thanks for the update!Casebound
I
5

I'm not sure if this applies to Racket, but in MIT scheme there are a couple built-in procedures that will get you close. (Below, proc just stands for any procedure)

  1. (procedure-arity proc) as you mentioned will give you the number of arguments
  2. (pa proc) will print the argument list
  3. (pp proc) will print the body of the procedure

This will work for many of the built in procedures as well any that you define yourself, but if you try to call any of these on a special form like define or set! you will get an error.

Intercontinental answered 22/4, 2012 at 14:37 Comment(1)
pa and pp are exactly the kind of thing I'm looking for - sadly, racket doesn't provide themCasebound
D
5

A couple weeks ago the XREPL ,describe command was enhanced to print the function argument names and contract; source.

This is the "blue box" from Racket documentation -- so called because they used to be blue before the Racket 6 CSS redesign; now they're actually grey :).

You can get this by building Racket from HEAD. Otherwise, it should be in the next release after 6.1.

Keep in mind that this appears to be limited to functions that have Scribble documentation in installed packages.

Disruption answered 11/8, 2014 at 15:0 Comment(1)
accepted this one now since ,describe is in 6.1.1 and does exactly what I wanted - thanks for the update!Casebound
S
4

Eli Barzilay notes that the Geiser project includes code to extract this documentation.


I do have an experimental bit of source code that extracts the text out of the HTML documentation, though that code may have bitrotted.

See: https://github.com/dyoo/wescheme-docs/blob/master/test-extract-docstring.rkt

and its dependencies, which live in: https://github.com/dyoo/wescheme-docs.

The extract-docstring.rkt library I wrote up works under Racket 5.2.1, but I'm admittedly doing some really icky, hacky things to extract text from the documentation.

It may be worthwhile to tell the folks on the Racket Users mailing list that being able to access the text-based documentation from xrepl is an important thing; perhaps it'll get the impetus moving.

Spandau answered 12/4, 2012 at 17:38 Comment(3)
This came up a number of times on the mailing list, there is no good way to do that since functions can have pretty complicated argument lists (for example, it might use case-lambda with different argument names and purpose for 2 and for 3 arguments). The most serious attempt to do this is probably geiser.Gonsalves
Thanks, I'll have a look at it! @EliBarzilay: I don't use emacs, but geiser's solutions look like a good starting point. Thanks!Casebound
@rwos: you can also search the mailing list archives -- we've had a discussion about these problems with Jao when he worked on this.Gonsalves

© 2022 - 2024 — McMap. All rights reserved.