IRC channel logs

2014-01-19.log

back to list of logs

<davexunit>when using prompts, does a parameter's bound value persist in the partial continuation?
<davexunit>I would expect yes, but in practice I'm not seeing it. I'm not sure if I did something wrong or if it's just not possible.
***sneek_ is now known as sneek
<taylanub>davexunit: I don't think so, unless you use `parameterize' (or directly `dynamic-wind').
<davexunit>taylanub: I'm using parameterize.
<davexunit>I think the issue is with me, but I wanted to make sure that I wasn't misunderstanding the way parameters worked.
<taylanub>Now I'm also unsure.
<davexunit>my instinct is that it must work.
<davexunit>yeah it works.
<davexunit>my code was bad.
<davexunit>as expected.
<taylanub> http://sprunge.us/UaWi http://sprunge.us/ffif Is the first one that confused you ? Because it confused me.
<davexunit>I got confused because I was trying to refer to the value of a parameter that is called from outside the prompt!
<davexunit>it was in the prompt's abort handler.
<davexunit>so of course the parameter's value was not what I was expecting.
<davexunit>well, I now have a "cooperative" repl that works that uses prompts. additionally, each repl prompt carries it's own state so there can be many cooperative repl's running at one time but only one can evaluate code at a time.
<davexunit>it's a bit ugly though, but it's a start.
<mark_weaver>sounds great!
<mark_weaver>only one should be able to evaluate code at a time.
<mark_weaver>that's good :)
<davexunit>I was feeling overwhelmed a couple of days ago, but I figured out a way to break up the problems.
<davexunit>next step: integrate with server.
<davexunit>now that multiple repls can run, the clients shouldn't interfere with each other, but I suspect that there will be an issue with output ports.
<davexunit>but that might not be the case, actually. I'll just have to try it and see. :)
<mark_weaver>indeed, you need to protect the output port.
<mark_weaver>you need to make sure that prompting-meta-read (in one thread) never runs at the same time as the REPL in the main thread. it's a straightforward use of a mutex, I think.
<mark_weaver>input port too.
<davexunit>hmmm.
<mark_weaver>but you don't need to protect each port independently. just make sure that your REPL is only running in one thread at a time, with a mutex.
<mark_weaver>well, you could arrange it using MVars as well, and I think that's what we did in the version we wrote at GNU 30th.
<davexunit>I'm not sure I follow.
<mark_weaver>two mvars (one for each direction) can be used to pass a baton back and forth, essentially.
<davexunit>yeah, that's how it's implemented now.
<mark_weaver>I think that should cover it.
<davexunit>the repl runs in the main thread (and server clients will run in their own thread) and when it reads an expression, it passes the baton to the reader thread and aborts the prompt.
<davexunit>the main event loop polls an mvar for an expression to evaluate
<mark_weaver>sounds good.
<davexunit>it receives the expression and the associated repl instance.
<davexunit>it evaluates and resumes the continuation.
<davexunit>rinse and repeat.
<mark_weaver>I wonder why it needs to receive the repl instance. each repl instance should have its own pair of mvars, no?
<mark_weaver>I'd think that the repl instance could just be part of the lexical environment.
<davexunit>maybe you can help me with that part, then.
<davexunit>I ran into some issues there.
<mark_weaver>what issues?
<davexunit>I'll try to explain my approach.
<davexunit>each repl instance has *one* mvar, the mvar that the reader thread waits for.
<davexunit>and there is one mvar that I call the "eval-mvar" that all repl's share.
<davexunit>that way only one repl can evaluate code at a time.
<mark_weaver>well, I suppose that's a valid approach.
<davexunit>there's a procedure that the main loop calls periodically to evaluate code, if the eval-mvar is fun. that's outside of the lexical environment of the repl prompt.
<mark_weaver>but I don't think you need to make any special effort to make sure that only one repl can evaluate code at the same time.
<davexunit>s/fun/full/
<mark_weaver>they are all running in the same thread.
<davexunit>yeah you're right. that's an unnecessary complication.
<mark_weaver>so you'd need to make a special effort to get them to run concurrently.
<mark_weaver>still, your approach might be better than what I had in mind, anyway.
<mark_weaver>because this way, you have only one mvar to poll instead of several.
<davexunit>yeah, I was about to raise that problem.
<mark_weaver>so yeah, nevermind what I said. what you have sounds good to me.
<davexunit>the way I have it now, the repl instance is closed over within the prompt.
<davexunit>okay cool.
<mark_weaver>thanks for working on this! sounds like it's coming along nicely :)
<mark_weaver>it sounds like mvars will go in as-is, also. I still need to write the docs and tests though.
<davexunit>I'm not so happy with the code quality yet, but ince I'm exploring what it takes to make this all work, I'm trying to not get bent out of shape over it yet.
<davexunit>sans the redundant "yet".
<mark_weaver>heh, my code often starts out very ugly, if the task is difficult.
<davexunit>but with whitespace and the license header, my new module is only at 90 lines so far.
<mark_weaver>sounds reasonable. this will be a nice addition to Guile. I've spoken to several people on irc who wanted something like this.
<davexunit>oh cool. so it's not just me. :)
<mark_weaver>no, not at all.
<davexunit>I did the @@ hackiness to access some procedures from (system repl repl)
<davexunit>and I may have to do the same with (system repl server)
<mark_weaver>a slightly nicer way to do that is to use #:select when importing the module.
<davexunit>ooh neat.
<mark_weaver>you can select bindings that aren't exported that way.
<mark_weaver>beware that if you use #:select, you must give the full list of bindings that you want from that module.
<davexunit>roger that.
<davexunit>the server stuff should prove simple. just need generalize serve-client to call start-coop-repl instead of start-repl.
<davexunit>I've been calling it a coop-repl, btw. I haven't come up with a better name. I figure that I'll ask the ML what a better name would be when I submit the patch.
<mark_weaver>naming things is hard, but that sounds like a reasonable name to me.
<davexunit>okay. I expect to change things a lot in the code review phase to get things up to snuff so I won't worry about the name anymore.
***linas__ is now known as linas
<Fuuzetsu>I see you mention #:select, is there a way to import stuff qualified or the ability to rename
<Fuuzetsu>something like in Agda: import Foo renaming (_+_ to _+f_; _ᵀ to _ᵀᶠ_)
<Fuuzetsu>oops, ignore that last _
<davexunit>morning guilers
<Fuuzetsu>It's 13:33.
<Fuuzetsu>(everywhere)
<davexunit>seems that my approach to the cooperative repl doesn't work so well when dealing with the server.
<davexunit>once the prompt aborts it closes the client connection. boo.
<davexunit>I see why it happens now, but not sure how to resolve the issue.
<davexunit>I have to solve a problem with a continuation barrier, but I have the cooperative REPL server working now! :)
<stis>heya guilers!
*stis is back to iso-prolog in guile development, just remains the prolog io code to work.
<davexunit>morning mark_weaver. made a more progress this morning. the cooperative repl server seems to be running well with multiple clients. :)
<mark_weaver>sweet!
<davexunit>s/a more/more/
<davexunit>now the boring stuff: clean up the code and write docs. :P
<mark_weaver>yeah, that's always the least fun part, but nonetheless important.
<mark_weaver>but think how nice it will be when this part of Guile 2.0.10 :)
<mark_weaver>s/this/this is/
<davexunit>yes, it will be very nice indeed.
<davexunit>since each client runs in its own thread, I think that some of the baton passing becomes unnecessary.
<davexunit>maybe...
<mark_weaver>well, you have to protect the ports from concurrent access.
<davexunit>well, right now I abort the prompt before prompting-meta-read and have a second thread per client that reads input.
<davexunit>but that part seems unnecessary to me now.
<mark_weaver>what seems unnecessary?
<davexunit>needing to keep a second thread for reading input.
<davexunit>the client is already in its own thread so it's not blocking the main thread.
<davexunit>I needed this originally before I built the server part.
<mark_weaver>wait.
<mark_weaver>I thought the whole point was that everything except for the reading should be happening within the main thread.
<mark_weaver>that's important.
<mark_weaver>especially for opengl programs, where each thread has its own opengl context, right? (I confess I know very little about opengl)
<davexunit>yeah, I think I've recreated part of the problem I had with my other repl implementation...
<davexunit>the evaluation happens in the main thread.
<davexunit>but I think that there will be a problem with the current-module
<mark_weaver>do you do the thing where you pass a thunk to the main thread, but the repl itself is running in a different thread?
<davexunit>it seems that's what I've made again, sort of by accident.
<mark_weaver>that's not good. the entire REPL should be running in the main thread.
<davexunit>okay, so I need to get the repl client's themselves to run from the main thread.
<davexunit>yes, back to work I go.
<mark_weaver>sorry :-/
<davexunit>that's fine. I think I see how I can solve this.
<davexunit>I just got lost in all of this threading madness.
<mark_weaver>it happens :)
<davexunit>(system repl server) has a line like this: (make-thread serve-client client-socket client-addr)
<mark_weaver>well, the repl server does indeed put each new repl in its own thread.
<davexunit>I want that new thread to only do the reading.
<mark_weaver>but for coop-repl, you need to arrange for the new repls to be created in the main thread.
<mark_weaver>which I guess means sending a special message to the mvar that's checked by the main thread.
<mark_weaver>a special "create new repl on this socket" kind of thing.
<davexunit>yeah, something like that.
<mark_weaver>so maybe the MVar message should start with a symbol, indicating what kind of message it is.
<davexunit>yeah, time to think this over a bit.
<mark_weaver>okay, good luck!
<davexunit>as a quick hack, I just removed make-thread from that expression and things still worked. :)
<davexunit>though, it's still within the server thread.
<davexunit>but it's a start.
<mark_weaver>basically, when the main thread recieves this special "create new repl" message, it should call 'run-repl' (or its analogue) within a prompt. and that 'run-repl' should abort to the prompt when it tries to call 'prompting-meta-read'.
<davexunit>yeah, that's what I'm writing now.
<mark_weaver>cool :)
<davexunit>it will be ugly and hacky for now, but it should work.
<davexunit>can I use (ice-9 match) to match message types within the mvar?
<mark_weaver>yes, definitely. we like (ice-9 match) :)
<mark_weaver>it generates fairly efficient code, too.
<davexunit>can I match an arbitrary symbol? since the first item of the list contains the message type, I want to match that. reading the docs but it's still slightly confusing.
<mark_weaver>you have to quote the symbol, if you mean to match a particular symbol.
<mark_weaver>otherwise it's a pattern variable.
<davexunit>okay, cool. that's what I was wondering
<mark_weaver>so you want a pattern like ('new-repl a b c)
<davexunit>perfect.
<mark_weaver>our (ice-9 match) docs could use some work. they also completely fail to document some important features of ice-9 match.
<davexunit>well, it seems to be working!
<davexunit>match makes the opcode matching a lot nicer.
<mark_weaver>excellent!
<mark_weaver>please test running an erroreous expression to enter the debugger, which should work properly but block the main thread.
<mark_weaver>(in the debugger, the main thread should be doing the reading itself)
<davexunit>main thread blocked! perfect.
<mark_weaver>also please test evaluating expressions in geiser, to make sure they are getting evaluated in the main thread. (maybe try evaluating (current-thread))
<davexunit>I also need to test evaluating code in a module besides (guile-user)
<mark_weaver>*nod*
<davexunit>the debugger blocking the main thread is exactly what I've wanted in guile-2d for some time.
<davexunit>gives the user a chance to fix their error before resuming the game.
<mark_weaver>yep
<davexunit>mark_weaver: current-thread is the same.
<davexunit>the same as the main thread.
<mark_weaver>good!
<davexunit>unfortunately, changing modules via ,m isn't working.
<davexunit>not sure how to deal with set-current-module.
<davexunit>or if I even can.
<mark_weaver>hmm, current module should be a fluid or a parameter.
<mark_weaver>let me see..
<davexunit>ah, then I can probably fix this.
<davexunit>I had to deal with the *repl-stack* fluid earlier.
<mark_weaver>when you start a new repl, you should probably wrap it within 'save-module-excursion'
<davexunit>roger that.
<mark_weaver>the save-module-excursion should be within the prompt.
<mark_weaver>save-module-excursion is defined in boot-9.scm line 2324
<davexunit>thanks.
<mark_weaver>this should effectively give each repl its own notion of the current module.
<mark_weaver>every time the prompt is aborted, the exit-thunk of the dynamic-wind in 'save-module-excursion' will be run, and every time it is resumed, the entry-thunk will be run.
<davexunit>hmm, I used save-module-excursion within the prompt but it didn't work.
<mark_weaver>hmm
<mark_weaver>what happens when you try to change the module?
<davexunit>nothing breaks, but the module remains (guile-user)
<davexunit>no error message or anything.
<mark_weaver>what does (current-module) say after you try to change the module?
<mark_weaver>actually, I suspect the module _is_ getting changed in the REPL, but prompting-meta-read, running in it's own thread, prints _its_ current-module, which is different.
<davexunit>ohhh
<davexunit>let
<davexunit>let's see
<davexunit>mark_weaver: you're right.
<davexunit>the module changed.
<davexunit>I can pass the current module to the reader thread
<mark_weaver>I guess you should pass the current-module to the reader thread via the mvar.
<mark_weaver>heh :)
<davexunit>I already do that with the repl-stack
<mark_weaver>we may discover other things that should be passed as well.
<davexunit>I'm using a let-over-lambda for the reader thunk currently.
<davexunit>but maybe later I can pass them via the mvar.
<mark_weaver>I don't understand
<davexunit>before the prompt aborts, I stash a thunk in the reader mvar.
<davexunit>in that thunk's lexical environment there is the repl stack.
<mark_weaver>oh, I see.
<mark_weaver>that seems reasonable too.
<davexunit>I'm not sure if that's a great way to be doing it.
<davexunit>but it was simpler.
<mark_weaver>that's a perfectly valid approach
<davexunit>bam. that worked.
<mark_weaver>nice!
<davexunit>perhaps others will come up with more things that need to be tested, but so far this is looking really good.
<mark_weaver>btw, please keep the 'save-module-excursion' in there. I think it's still important.
<davexunit>I did.
<mark_weaver>good
<mark_weaver>well, I'm glad to hear it's coming along nicely!
<davexunit>it's a relatively small amount of code.
<davexunit>which is cool.
<davexunit>thanks for all of your help, mark_weaver
<davexunit>I hope it was slightly easier for you to assist me instead of having to write all the code yourself.
<mark_weaver>definitely!
<mark_weaver>glad to help. thanks for working on this.
<mark_weaver>I have to go offline for a bit. happy hacking!
<davexunit>see ya!
***Shozan is now known as SHODAN
<civodul>Hello Guilers!
<dje42>Hi.
<civodul>hey dje42
<civodul>seems the review process is coming along nicely no?
<dje42>hope so
<dje42>Is there any function in Guile that returns a string, and says in its documentation what the encoding of that string is? [ASCII, UTF-16, or whatever]
<dje42>Just sanity checking again. I believe the answer is "no". Strings in guile are sequences of unicode code points. Internally they could be utf8, a hybrid of narrow and wide (like today) or whatever.
<wingo>correct
<dje42>Thanks. When I'm trying to convince someone of something, and I'm pretty sure I'm correct, I'm often not sure enough.
<dje42>[even when I'm like 99.99% sure]
<wingo>:)
*davexunit sent a rough draft patch to guile-devel. :)
<wingo> http://wingolog.org/
<wingo>er
<wingo> http://wingolog.org/archives/2014/01/19/elf-in-guile
<mark_weaver>you have a talent for exposition, wingo!
<wingo>tx!
<mark_weaver>One question: in q.go, I'm curious what's in that fairly large "(unnamed)" section after .data.
<mark_weaver>it's the third largest section in that file, and unremarked :)
<wingo>it's a good question, and i don't know :)
<wingo>the first one is the program table
<wingo>hummmm, i really am at a loss :)
<mark_weaver>maybe the NSA put it there :)
<wingo>haha :)
<wingo>the linker must be inserting it somehow...
<wingo>well. some other day. i am headed sleepwards i think
<mark_weaver>okay, good night!
<mark_weaver>and thanks, as always, for all the awesomeness :)
*civodul goes to read the blog post :-)
<civodul>woow, excellent
<dje42>civodul: I see %default-port-conversion-strategy is also used by string->pointer, et.al. (i.e., not just ports)
<civodul>yes, string->pointer and scm_from_locale_string
<dje42>So I guess the question is %default-port-conversion-strategy available for public use.
<civodul>for string->pointer this is really a mistake
<civodul>yes
<civodul>well, it's documented and everything :-)
<civodul>string->pointer should be like string->bytevector
<dje42>Ah, cool. scm_port_conversion_strategy is publically exported, and I can just pass it SCM_BOOL_F to get the default.
<civodul>yes, though (fluid-ref %default-port-conversion-strategy) is clearer IMO
<civodul>well, less convenient from C
<dje42>biaw
<civodul>./check-guile runs in 1m24 for 2.0, and 1m02 for 2.2, wee!
<davexunit>not too shabby.
<civodul>coverage.test alone goes from 9s to 2s
<mark_weaver>nice!
<civodul>all this is really looking super cool