IRC channel logs

2022-10-30.log

back to list of logs

***jpoiret9 is now known as jpoiret
<Zelphir>I've got a weird error: I have code, where I call `(get-line input-port)` multiple times, to make the user press enter/return to let the program continue (no ncurses tool here). At some point I press Ctrl+c, to stop my program showing me output and calling that get-line, because I've seen enough. However, that exits the Guile program. When I then press `up`, I get the following error over and over spamming my terminal emulator: `While reading
<Zelphir>expression:\nIn procedure %readline: readline is not reentrant` (if I read it correctly, because the lines are rushing so by so quickly.))
<Zelphir>Then I can hammer Ctrl+c and Ctrl+d to exit my terminal emulator to make it stop, but then I cannot copy paste the error, because that window is gone.
<Zelphir>In my code I am not using the result of get-line at all. Only calling it to force a "confirmation" by pressing return/enter.
<Zelphir>Any ideas, why this is happening, or what to do about it? (except switching to something like ncurses)
<yosik>You can try to redirect output to file, that way you'll get exact error message
<Zelphir>Seems there is another error before the spam of what I quoted already: http://0x0.st/oYQC.log
<Zelphir>And the repeating error is on stdout. Had to redirect stdout to a file to see it: http://0x0.st/oY1i.log
<Zelphir>Also just noticed: Even when I close the terminal emulator (xfce4-terminal 0.8.9.1) there is still CPU load caused by the guile process, which still seems to be running, probably endlessly still repeating that error. Killed it via a task manager.
<lilyp>Zelphir: something in your workflow seems extremely cursed
<Zelphir>:D
<lilyp>I think you're missing proper cleanup in get-line while hitting Ctrl-C
<Zelphir>I am thinking of catching any ctrl+c and handling it properly in my program.
<Zelphir>I found (sigaction ...) but not sure I should use that, or what the exception handling alternative is.
<Zelphir>So I explored a bit and came up with this: https://notabug.org/ZelphirKaltstahl/guile-examples/src/c7043fea34a17dd702db08741b6f00222cf4a9b0/prompts/example.scm
<lilyp>I don't think this captures the semantics of your program well enough
<lilyp>the usleep should probably be a getline, so that you get the sigint during the getline call
<Zelphir>I know, that maybe at some point, I might do some ncurses thingy, or, if I get the hang of any of the gtk libs for guile, maybe a gtk thingy, but for now, I only need very few things. Just showing some vocabulary or word (natural language) information and then go on with the next word. What I am confused about is, that this leads to strange behavior, when interrupting with ctrl+c.
<lilyp>I don't think this makes a huge differenc
<lilyp>for instance, with gtk you just need to remember to quit the main loop
<Zelphir>I don't understand yet, what you mean by "usleep should probably be a getline". Do you mean in the example prompts code? I only tried out, how to capture ctrl+c at all, aside from doing that in my program. Let me link the program's code: https://notabug.org/ZelphirKaltstahl/guile-vocabulary-explorer/src/da0e78cac3b94a0e3bfa604ff06ff22b45136687/lib/training.scm#L29 Here I call `(io:read-line)`. Which is only: https://notabug.org/ZelphirKaltstahl/guile-
<Zelphir>vocabulary-explorer/src/da0e78cac3b94a0e3bfa604ff06ff22b45136687/lib/io.scm#L15 a (get-line ...).
<Zelphir>But I am wondering, whether the example with the prompt is the correct way to catch a ctrl+c?
<lilyp>note that you're not at all handling the result of get-line, which can return that it's eof and that subsequent calls to getline will result in horrors
<lilyp>C 101
<Zelphir>huh, OK, didn't think about that / didn't know that I had to handle it ^^'
<Zelphir>So is there a recommended way to simply "wait for the user to press enter"?
<lilyp>you could wrap your getline call in one that raises an eof error and catch that
<lilyp>though more importantly simply "wait to press enter" is a stupid UI
<lilyp>Give the user an actual prompt and read the response with the translated yes/no regexps
<Zelphir>It feels "not proper", but what are other ideas, of how I could show information "step-wise" and let the user step through it? I do have a "library" for getting input from the user, but I felt like that is a lot of code for my project to add: https://notabug.org/ZelphirKaltstahl/guile-user-input-output/src/master/user-input-output.scm
<Zelphir>I definitely did not want to get into learning ncurses only for this.
<lilyp>yes/no regexps are from i18n, no ncurses
<rlb>I don't know, depending on the program "hit return to see the next thing" seems fine to me (e.g. less), particularly for an initial prototype...
<Zelphir>With that lib, I am not even using regexps. Basically getting input, until it matches one of the answer possibilies.
<rlb>For what it's worth, I've long thought that guile's handling of C-c from the repl was suprising i.e. it doesn't do anything until I cause it to present the next prompt.
<rlb>(though likely not relevant here unless you're relying on the repl)
<rlb>Without knowing the details, I might suggest pulling out a minimal bit of your program if that's easy to test the signal/get-line behavior (e.g. the output flood). See if you can reproduce it with a small test program.
<Zelphir>> yes/no regexps are from i18n -- So that users get their language's yes/no. Ah!
<rlb>Might either demonstrate a real problem, or reveal whatever you've missed.
<Zelphir>I need to think about handling ctrl+c at get-line, I guess. If I understand correctly, it will result in that EOF case?
<Zelphir>In my lib for user input output I am also not handling it.
<lilyp>hmm, now that I consider it, actually C-d causes eof, not sure at all how C-c interacts with it
<lilyp>you'd have to look at the repl code to see how it catches the C-c case
<rlb>If the docs don't specify what happens by default, make a trivial program and see what at least the current behavior is there?
<lilyp>(displaying a delayed user interrupt is still preferable to the behaviour you're observing)
<Zelphir>I think I only want to do a Python's `_unused = input("press enter!")` ^^'
<Zelphir>But with the option to cancel showing more and more words. Which is where I thought handling Ctrl+c might come in.
<Zelphir>But also don't want to do it dirty, but properly, learning how to do this stuff in Guile.
<lilyp>from a purely functional perspective, that python statement is cursed
<Zelphir>Hm. At some point I need to get some kind of sign from the user, that the user is ready to see the next word (or whatever it is in any kind of program). That is an input. I don't know of other ways to write some code, which would accomplish something like this. Maybe there is a completely different way out there, which I am not even thinking about?
<Zelphir>Maybe intercept key presses directly somehow?
<rlb>If the input isn't currently your primary focus, I'd guess that get-line might be a plausible choice for now. But if you just want "press any key", I suppose you could consider something like get-char (and then perhaps drain-input might be interesting, etc.). Not sure.
<rlb>But it sounded like the problem wasn't get-line per-se? i.e. the problem was a runaway process, which I'd guess is related to "other issues" in the code (or in guile), offhand.
<rlb>(If so, that's why I mentioned maybe trying to "narrow it down" with a smaller test program.)
<Zelphir>I mean, that makes sense. Just a bit annoying, that I run into this, while wanting to do something "so simple".
<rlb>If I had to guess offhand, I'd imagine that maybe you weren't checking the results of everything in your loops, or rather might be missing some exit check in the loop guard that causes your loop to not notice when it really should quit (i.e. after the C-c has started trying to kill the process).
<rlb>As I think mentioned before, not checking for EOF is one of "those kinds of things".
<rlb>But certainly not the only one (generally speaking).
<Zelphir>In the manual at https://www.gnu.org/software/guile/manual/html_node/Textual-I_002fO.html it says: "If a linefeed character is read, a string containing all of the text up to (but not including) the linefeed character is returned, and the port is updated to point just past the linefeed character. If an end of file is encountered before any linefeed character is read, but some characters have been read and decoded as characters, a string containing
<Zelphir>those characters is returned. If an end of file is encountered before any characters are read, the end-of-file object is returned." -- But there is no mention of what happens, if one calls (get-line ...) again or anything. If I am to handle the EOF, I wouldn't even know what to do with it. I mean, the description sounds like the procedure always returns a value, but I don't really care about the value, actually.
<lechner>Hi, is this still the best way to preserve the mtime of precompiled .go files in Automake? Thanks! https://gitlab.com/a-sassmannshausen/guile-config/-/blob/master/Makefile.am#L21-27
<lechner>Also, was my previous message from the lechner- nick silenced because it was not authenticated?
<lilyp>Zelphir: the canonical way is to loop until you see eof and never touch the file again (or even close it)
<Zelphir>How would I do that with the REPL?
<rlb>Zelphir: "what lilyp said", i.e. you have to check every get-line call for (eof-object? result) and if that's ever true, then you're "done" -- that port is 'dead".
<Zelphir>But the REPL is not supposed to die? Or is that different from the input port?
<rlb>I don't know what your context is, but if you're running your function from the repl, then you're likely both using stdin, and if stdin closes, you're both "done".
<rlb>i.e. your function and the repl, but you'd definitely need to make sure your code handles it correctly.
<rlb>Also, I'm not sure offhand how competing with the repl for stdin is expected to work.
<rlb>might be fine - just hadn't thought about it.
<Zelphir>Imagine you have a list of things and you want to display those things, one-by-one. Not all at once, forcing the user to scroll up and down and already displaying too much. But I don't want the Guile REPL to die. I just want to the user to have a way to "continue displaying the next item" by pressing a button. (In my case it is words I want to learn, so I first need to show them in native language and then show their other attributes.)
<Zelphir>I imagine, that I only get EOF when the REPL is exited. For example with ctrl+d.
<rlb>I imagine, but don't know, you might alsoo get it via C-c. But if you're trying to interleave your work with the repl *and* compete with it on too fine a grain level for stdin, then I'm not sure if that's going to work well -- haven't really thought about it.
<rlb>"also"
<lilyp>Zelphir: there is also this technique called piping to less
<Zelphir>Can you link an example?
<lilyp>See call-with-paginated-output in Guix.
<Zelphir>OK thank you! Sounds exactly like my thing^^