One of the pet peeves I have with writing documentation in Racket is that fact that it’s not attached to the source code. Does anyone have any suggestions on libraries or code out there that merges define
with defproc
into an all powerful code+doc definition? Happy to contribute to something if there’s already something done, otherwise I will put something together.
Not sure if you’re looking for this: https://docs.racket-lang.org/scribble/srcdoc.html?q=in%20source%20documentation
:stuck_out_tongue:
Related (but probably not what you are thinking of): https://docs.racket-lang.org/scribble/lp.html
I had seen srcdoc
in the past but forgot about it. Thanks for the reference to mcfly
.
I will take a look.
Also found this while looking for projects using srcdoc
, which apparently is under-utilized: https://github.com/greghendershott/frog/blob/master/frog/private/define-doc.rkt
@greg should probably refactor it into its own package. :slightly_smiling_face:
hint hint
Also that’s a great example for the syntax-parse
bee… cc: @spdegabrielle
I just didn’t/don’t have time to polish and support another package.
But I’m happy if it’s a small head start for folks.
So having the source available, but under private/
, feels ideal from my POV.
Also:
This feels like something that would invite a lot of FRs; people might have different feelings about how it ought to work. (So that goes to the maintenance bandwidth aspect.)
I feel like flavors of
define
need a better way to compose — something likematch
expanders?? So in the meantime I feel like I shouldn’t offer the world moredefine
flavors? Instead, in the meantime, maybe it’s not ideal but more realistic if people write bespoke, per-project macros for the specific composition they actually need/want. (So that’s the “head start” aspect.)
Anyway those are my excuses ^W
justifications for now. :slightly_smiling_face:
Is it just that the error starts “read-compiled-linklet” (which I agree is unhelpful), or something else?
In scribble, is it possible to link keywords that appear in an example block to a tech entry? @deftech{Hello} is a function that comes before a world
@examples[(Hello 100)]
Makes sense @greg . Thanks for the input.
Maybe someone else could adapt it fir the purpose of making an entry? (Assuming licence allows)
I think you’d have to use eval:alts
, which has the drawback of writing things twice.
It would be nice if it offered suggestions about possible fixes.
What’s a racket-y approach if I want to print fixed-width, word-wrapped lines with indentation to console? I’ve got a bunch of long strings, and I’d like to print them so that each line is max X characters wide, and indented by Y characters. This looks like a wheel I don’t particularly want to reinvent, if I can avoid it.
Is there any guidance on what main.rkt
is used for? I’ve seen it in a handful of places, but I can’t tell if it’s considered a “special file” (à la info.rkt
) or not, and searching didn’t turn up much
I’d use pretty-print-columns
for pretty-print
Great, thanks, this looks precisely what I’m looking for
“main.rkt” is special as a module in a collection, because a collection name C
used as a module reference is a shorthand for C/main
. For example, racket
as a module path means racket/main
. That only works for a C
with that doesn’t contain a /
, though.
I’ll add “main.rkt” to the Guide index where it’s mentioned on this page: https://docs.racket-lang.org/guide/module-paths.html
ah, thanks. does that mean if a collection is, say, foo/bar
, you have to specify foo/bar/main
otherwise?
and, IIRC, this is used specially for #lang
support? but I could be making that bit up
The obvious fix to offer is “run raco make foo.rkt
for whatever foo.rkt you were trying to run”. That works for other linklet-level errors too, but it has a couple drawbacks.
First, the file where the error is detected isn’t the right place to run raco make
, you want to run it on the top-level thing you were trying to run.
Second, in @pavpanchekha’s case, where there’s a version mismatch, you probably want to run raco setup
more generally, because lots of things are out of date, or you’ll keep getting that error.
Yes, you’d have to refer to foo/bar/main
that way (which foo/bar
would refer to “bar.rkt” in the “foo” collection — which could just re-export foo/bar/main
if that was somehow useful).
Third, it can take a long time, which isn’t really a problem with the suggestion but it’s one reason why people don’t do it.
It’s not just for #lang
. Using (require pict)
is common, for example.
Right. And #lang foo
is kind of short for (module ? foo)
, so then you end up using foo/main.rkt
, right? That’s what I meant by “specially”
Finally it could be hard to actually give the right suggestion, eg if you’re running an unsaved file in DrRacket you can get the error but there’s no way to suggest the correct command and suggesting the command line in an error message in DrRacket isn’t great.
Another suggestion might be to re-run without loading compiled files, but that will make running much much slower.
It’s true that there’s special rules for #lang
but you can do #lang a/b
and that doesn’t use main.rkt
.
The special rules for #lang foo
are that it doesn’t just turn into (module name foo)
, it uses a reader specified by foo/lang/reader
or (submod foo reader)
.
My solution has always been to delete all compiled files that I can find. I’m happy to just skip bad files
In the latter case, it would be the same as (submod foo/main reader)
because of the semantics @mflatt mentioned, but there isn’t anything special beyond the meaning of foo
as a collection.
This happens with the local cache in Pollen projects all the time. Maybe the message could be changed depending on whether the .zo is in a collections folder?
I might be more interested in using compiled racket if it didn’t sometimes break in this way
Pollen has some special behaviors that make this happen a lot more
@pavpanchekha have you tried using raco make
in those situations?
It will likely be faster and more effective.
If I’m running something that works. If I’m installing a package it doesn’t—I need to find that package to make it, etc
I’m trying to do (define text "oontz oontz oontz oontz")
(parameterize ([pretty-print-columns 6])
(pretty-display text))
but it prints everything on one line. Is there something I’m missing here?
I do recall raco make not working and it being really frustrating
The same happens for pretty-print
instead of pretty-display
, I’m just using display for dropping the quotes
try (define text '(oontz oontz oontz oontz))
I’m not sure what you mean about installing a package. If you mean that you ran racket -l a/b/c
and it gave that error, then raco make -l a/b/c
should do what you want. If you’re getting that error during the course of raco pkg install
then that’s different and seems like a bug, since it should be running raco setup
automatically.
that does print as '(oontz
oontz
oontz
oontz)
By “raco make not working” do you mean that you still got the error after running raco make (that can happen, it is frustrating, usually due to code that does tricky things with requires) or that raco make itself failed?
but if it’s a quoted list, how would that handle longer strings w/ special characters and whatnot?
the example was a bit too contrived maybe :smile: i’m essentially trying to sort of pre-format or pre-line-wrap blocks of text, and i’m actually interested in paragraphs of maybe couple sentences or so
Now my confusion feels justified :slightly_smiling_face: a section or more in the guide would be nice. Recap, based on what I’m reading: • a module path for a named collection with no /
will actually refer to that collection’s main.rkt
library • similarly, a #lang
line with a named lang with no /
uses a reader in (submod foo/main reader)
(if foo/lang/reader
doesn’t exist) • in both cases, using names with /
do not do anything with a main.rkt
, and the reader is (submod foo reader)
when the foo/lang/reader
doesn’t exist
The second bullet is just the composition of how #lang works with the first bullet.
The guide description of bullets 1 and 3 is what Matthew linked above
Right. I’m assuming the reader submodule usage is documented somewhere… at any rate, thanks all for clarifying that
I don’t think pretty-print/format can do line-wrapping for a single string.
I think making that section more example-driven would be helpful, if you’re interested.
right, well, this has been helpful nevertheless, so thanks!
I would love too! I’m in the middle of a move, actually (unpacking/dealing with finances/insurance/cars/etc.), so I’m a bit busy. I can happily review some changes, but I’m not familiar enough with Scribble yet to make them quickly.
yes great example for the (upcoming) bee — we want head starts & hints
I am considering extending @greg start into a library so I can use it in racket-binaryen
which could seriously use defs+docs in one.
For “while installing a package” I meant yeah during raco pkg install
. For “raco make not working” yeah I mean I still got the error afterwards.
Getting that error when running raco pkg install
is definitely a bug somewhere, so if you see it again please report it.
Ok
See, I didn’t even know that that was a bug. From my perspective, as someone who does not know the Racket internals, running Racket just fails sometimes…
I think we all agree that the current situation isn’t great, it’s just genuinely hard to fix
I made a thing for describing steps of a function’s execution (like logging, but more for CLI programs). It also happens to self-document the code. https://gist.github.com/benknoble/a01e20f09ee42fbfc6eca42e72200e84 • I debated between define-steps
and just a steps
form that could be used anywhere, since define-
s don’t compose all that well • I originally had each step as a splicing syntax with just (~seq message:string form:expr)
, but it was awkward to write (begin …)
when the step was more than one expression. I then tried (~seq {~literal step} message:string form:expr ...)
, but after the first step "message" form…
the parser (probably correctly) gets to step
, calls it an expression, and you get “unbound identifier”. So, suggestions for ergonomics accepted.
I asked this a while ago and this answer may help: https://gist.github.com/sschwarzer/5aaf9f203c552f1bf13a167dd08ded11#wrapping-a-paragraph-of-text Is this what you’re looking for?
The function doesn’t seem to handle indentation, but you could format for a smaller width and then prepend your indentation to each line (with a regexp anchored at line starts, for example).
I think a function like Python’s textwrap.wrap
should be in the Racket standard library. :slightly_smiling_face: But for a start it doesn’t have to be <https://docs.python.org/3/library/textwrap.html#textwrap.TextWrapper|that sophisticated>.
Thanks, this looks also very relevant! :+1: I actually ended up rolling my own implementation of line breaking, but I won’t be surprised to see it eventually blow up. The scribble function seems to be quite a lot more robust than what I have :smiley:
in the approach where you use a literal step
separator, change form:expr …
to: (~and form:expr (~not (~literal step))) ...
that way, the form:expr
part won’t match later uses of step
also, if you add #:literals (step)
to your uses of define-syntax-class
, you won’t need to write (~literal step)
and can instead just write step