
@greg Thank you for the reply. I changed the line (regexp-match #rx"(\r\n\|^)\r\n" in)
to (println (regexp-match #rx"(\r\n\|^)\r\n" in))
However, when I visit the url, this is what it prints in the REPL '(#"\r\n\r\n" #"\r\n")
.

> If the client waits to finish writing the request, before trying to read the response, Thanks. That explains why the regexp
line is required. However, shouldn’t the port->string
command also read the whole request? Incidentally, even that does not output the request until after a timeout occurs (or I visit the page twice). I need to figure that out. But it does not print it out immediately.

Anyone who’s used racketscript: is there an easy way to just run the “fully expanded programs to JS” function, instead of using the whole pipeline? (maybe @stchang)

Okay, got an interesting thing I’d like to do, but not sure if it’s doable…
• I want to be able to tell if my program launched from a Racket REPL (I’m OK w/ it being specifically from DrRacket, but knowing it “was executed from REPL” would be ideal) • If the above is #t
, I’d like to be able to “interrupt” my running program, drop back to the same REPL source (not necessarily the same REPL). And - upon either leaving the REPL or calling a (call/cc?) function, continue my previously running code from where it left off. I realize I can create a sandbox and just call something like (read-eval-print-loop)
from within my code, but then it requires me to create my own terminal-like environment to run it in, which I really would like to avoid if possible. I’m running a graphical program, and unless it’s dirt simple to pop open a new terminal window with a REPL, I’d rather just drop back to DrRacket’s terminal (or Emacs) and get all the benefits of those environments.
I’d also prefer to not launch the program from the REPL in another thread, because what I intend to do from the REPL after interrupting the program would require retro-fitting a lot of thread-safety and such.
Example use: imagine I’ve launched an OpenGL program from the REPL, which is now stuck waiting for the function to exit. Now, I’d like to drop back to the REPL in order to play around with something like (set! camera-fov 45.0)
and then continue and see how it changes things.

I’m not sure all the pieces (e.g. what “run from REPL” means and how to detect it), or how to arrange them. But a couple pieces might be:

If you cause a break, you get a continuation to resume. https://docs.racket-lang.org/reference/exns.html#(def._((quote._~23~25kernel)._exn~3abreak-continuation))

Ah, that might be a pretty simple solution! I’ll check into it. Thanks :slightly_smiling_face:

Not sure about GUI programs’ handling of stdin/stdout, but: You could parameterize current-{input output}-port
around (read-eval-print-loop)
, and set them to some other port. Like TCP. Or unix domain socket. That is connected to a terminal via waves hands idk how exactly.

Or maybe there’s a way to capture the original in/out ports, before GUI redirects them (if it even does that), and supply those ports around r-e-p-l.

Also see https://pkgs.racket-lang.org/package/debug. That’s for a predefined point. Not on-demand. But maybe helpful for you anyway, idk.

@massung Is Tony’s reloadable
any use in your use case? https://github.com/tonyg/racket-reloadable

@mflatt for a user-defined method, the Racket’s OO system initially inserts a self
parameter as the first one, but after the program is fully expanded, the self
parameter could be moved to the second or third position. (e.g, keyword methods). However, Typed Racket assumes the first parameter is self
, which might cause problems. Is there any reliable way to tell which parameter is self
? (checking if the prefix of the name of a parameter is “self” is not enough) cc @samth

I’m not sure I understand the question. For a function representing a method, “self” is always the first by-position position. The expansion of a method that has keyword arguments will involve a helper function that takes “self” after keyword arguments, but that helper function isn’t the method; it will be referenced in a make-keyword-function
— really make-optional-keyword-method
or something like that — to construct the method. So, it would be possible to infer that a non-first argument to a helper function corresponds to “self” by seeing it use in a make-optional-keyword-method
that creates a method.

Is anyone else here using a recent build seeing way too much space around the names of tabs? I’ve verified that this does not occur in the release candidate, so it’s either a more recent change, a consequence of packages I have installed, or some other terrible foolishness on my part. To see what I mean, here’s a screenshot:

Thank you for the explanation. I didn’t make myself clear. The problem is about those helper functions. (e.g. https://gist.github.com/capfredf/b3f9e4411daa068c9ca2cd1c653a0bb0#file-exanded-rkt-L72) TR checks every lambda form in a fully expanded program. In this case, TR sees x11:51
as self

I’m on gui-lib 8b523ad
from Jan 2th and DrRacket 3a07fc0
from Jan 4th and I don’t see this.
I can update my gui-lib to HEAD later today and see if it’s cause by this flat-portable
style https://github.com/racket/gui/commit/93fd2ebabafcc24cea943a6df8a7eaf1a47f4eb2

I don’t understand why TR would see that lambda
as a method, since it doesn’t flow to the list of methods for a class. The result from line 92 does, though.

Mouse over one of those tabs, and you’ll see an “x” to close the tab appear.

Ah, yes I also see this (with hidden "X"s) if I open more files.

Does anyone have a nice scribble hack for conditionally showing content based on the date the document is built? I’d like to set up a course web page where each assignments is it’s own include-section’d document and each assignment module provide a release-date; if the document is built before the release date, it shows a placeholder; otherwise it includes the document as usual?

include-section is pretty simple, so I was able to make my own variant that is pretty close to what I’m after #lang racket
(provide include-section-if-released)
(require racket/date)
(define-syntax (include-section-if-released stx)
(syntax-case stx ()
[(_ mod)
(with-syntax ([doc-from-mod (datum->syntax #'mod 'doc)]
[rel-from-mod (datum->syntax #'mod 'release-date)])
(unless (module-path? (syntax->datum #'mod))
(raise-syntax-error #f
"not a module path"
stx
#'mod))
#'(begin
(require (only-in mod [doc-from-mod doc] [rel-from-mod release-date]))
(if (< (date->seconds release-date) (current-seconds))
doc
"Not yet released")))]))


Just changed the text-area to a monospace as well, but this is a hack I put together today using racket/sandbox

Interesting… but it looks like the space for the “X” is being left blank on both sides of the tab?

I have some relevant code (by @ccshan) that I can post in a bit

thanks

Yeah, seems weird that tab captions are centered with blank spaces on both sides.

Would anyone happen to know where the implementation of the default DrRacket s-expression indenter is?

A couple months ago I could have told you offhand, because I was deep into a branch exploring having Racket Mode use lang-supplied lexers and indenters.

Let me see if I can find it again…

I recall there’s a method named like find-amount-to-indent or something like that

Oh, it’s compute-amount-to-indent


Close enough

Would it be a bad idea to just… reimplement this without depending on all the gui framework nonsense

Well, from my POV as a non-GUI potential user of it, heck yes. :smile:

The color-lexer thing especially is kind of all wrapped up with the edit% or whatever thingie … my brain has swapped out all the names a couple months ago.

With some warm up, though, I could rant and propose at some length. :smile:

I mean, clean sheet of paper, it’s easy. 10 or 20 years ago, I 100% understand doing things however they were done, just to make something as ambitious as DrRacket a reality, at all.

Maintaining it would be cumbersome though, since any changes to the original implementation will need to be updated in the reimplementation.

But @greg probably did that already, in Emacs

So I guess that’s an improvement from that perspective?

Maybe I’ll rip it out and make it part of the standard distribution somehow?

A couple notes I made:

Simple “syntax highlighting” only needs a lexer: A stream of tokens classifed as various “kinds”, so each kind can get its own appearance, customizable by the end user. An editor or indenter will want to access the resulting “token map” with something like a ~data/interval-map~ interface: Given a position, get the token and its bounds (its position span as a half-open interval, a.k.a. “from” and “upto”).

To do indentation and basic navigation editor commands, slightly more is needed. The tokens need to be consumed by a simple reader — not a full Lisp reader, but one which at least consumes “open” and “close” tokens to discover “expressions” or “blocks” that are nested arbitrarily deeply. (Unlike a full Lisp reader, token values remain strings like “123”, “’symbol”, "#:hash-keyword".) These open and close tokens could be single-character delimters like parens, brackets, and braces. Or they could be multi-character keywords like “begin” and “end”. In an offside rule lexer they could even be “indent” and “outdent” tokens. Then a token-map can provide some helpers to navigate these expressions — much like Emacs and text<%> functions like “forward-sexp”, “up-list”, and so on.
Also, because indentation is line-oriented — it matters if tokens are on the same line, or not — it helps if a whitespace token produced by a lexer like " \n " is transformed to four tokens: " " "\n" "\n" " ".

hmm

lots of thinking to do

After all, it’s old code with 10 yrs of history. Plus you only know how to structure things more reasonable after it has been tried once.
The data structure maintenance code, GUI interaction code and Racket-specific parenthesis matching code are all coupled together in a single mixin so well..

Also I was reading so-called tree-sitter parsers that emit “concrete” syntax trees instead of abstract syntax trees. But that kind of gave me a headache and I convinced myself that a token-map could be updated efficiently given change notifications. But I could have been wrong. shrug

In my case I don’t need something fast, since I’m using it for resyntax
output

I think the TL;DR is that you definitely could split out the sexp indenter stuff from GUI stuff. I think you’ll find you want some basic “sexp nav command” type functions to do indenting. Like at least “forward sexp”, “backward sexp”, “up to parent sexp”. Maybe a couple more.

So it’s natural to just use the DrRacket or Emacs commands for those, when available. Ergo the status quo.

FWIW this is mostly the stuff on that branch that’s relevant, in this folder: https://github.com/greghendershott/racket-mode/tree/lang-lexer/racket/token-map

Well, it’s what I came up with, anyway. shrugs

Oh ha ha I forgot. I wrote a small rant in the form of a long comment, plus an attempt to bandaid the status quo: https://github.com/greghendershott/racket-mode/blob/lang-lexer/racket/token-map/private/core.rkt#L281-L348

wow that profj
comment.. I suppose at that time the #lang
protocol didn’t even exist

Yes I assume that’s the timeline. Again, any “ranting” was re the situation not the history!

I started working on this branch thinking, well, maybe a non-sexp Rhombus is inevitable, so maybe I’d better try to prepare. And also, maybe more importantly, the #lang
vision is people’s own non-sexp langs should work well in Racket Mode, too.

And honestly for Rhombus it ought to be an eat your own dogfood thing where it’s using the same #lang
mechanisms and tooling specs, as everyone else. Regardless of the surface syntax.

That’s not the case for DrRacket and Racket, entirely. Which again is understandable. But probably going forward it’s a good goal.