<mark_weaver>ah, interesting. refresh my memory, does windows use CR LF ? <mark_weaver>I'm surprised that makes a difference, at least outside of string literals. \\r is treated as whitespace by Guile's 'read'. <mark_weaver>if MSDOS is defined, then read also considers Ctrl-Z to be a space, in addition to the others. <madsy>ERROR: In procedure primitive-load-path: <madsy>ERROR: In procedure primitive-load-path: Unable to find file "C:\\\\bin\\\\guile-source\\\\test-suite/C:/bin/guile-source/test-suite/tests/00-initial-env.test" in load path <madsy>Seems like some paths are relative? <mark_weaver>'primitive-load-path' wants a path relative to something in the load-path. <mark_weaver>'primitive-load' passes what you give it directly to the open call. <madsy>The third argument you invoke main with is relative to the primitive-load-path <madsy>Sure, but specifying a relative path seems to have addressed it <mark_weaver>oh, I see. yes, you need to pass a relative path to 'main'. <mark_weaver>in fact, it should just be "<NAME>.test" where <NAME> has no directory separators. <mark_weaver>if you loaded 'guile-test' more than once in the same guile session, it might explain the error you found. maybe try relaunching guile? <mark_weaver>(the error was "register-reporter: reporter already registered ...") <madsy>Ran the first test now without a hitch <mark_weaver>now that you have POSIX, you might be able to omit the list of tests, in which case it should scan the filesystem and run all tests. <mark_weaver>out of curiosity, what was the breakthrough? did you find out why 'main' was blocking before? <madsy>For some reason, guile was waiting for input even after seemingly legal and finished s-expressions <madsy>Like it was inside a string or something <madsy>I wrote everything by hand without adding extra newlines <madsy>Maybe the copy-paste function for the Windows console was playing tricks on me <madsy>All the tests complete now, except 3 so far <madsy>I mean, they run. 3 have errored because the tests don't exist or because of some missing function <mark_weaver>fwiw, there's a popen test that fails if TEST_SUITE_DIR isn't set. I'm going to fix that. and there's also another test that fails when I run it outside of "make check". FAIL: foreign.test: pointer<->string: %default-port-conversion-strategy is substitute <mark_weaver>anyway, those two failures are not windows specific. <madsy>I'm commenting out each test that fails to start <madsy>So I can run them all and give you the testsuite log, as well as a list of tests that failed to run <mark_weaver>I have to go afk for a bit. but this is great progress! <madsy>Sorry for being so thick about the windows console bug <madsy>I should have thought of that earlier <mark_weaver>the documentation errors are just because it can't find guile-procedures.txt <mark_weaver>a few other little things, but for the most part, it looks very good! <mark_weaver>I have to go afk again for a while, but this is very encouraging! :) <madsy>I've used all day on this, so I guess it's time for bed :P <mark_weaver>madsy: I very much appreciate your efforts! sleep well :) *davexunit is using the tiling wm in guile-wm <davexunit>have to manually create all the keybinds though *davexunit crashed guile-wm <nalaginrut>last Christmas I went to DSL in HK, there's a guy uses xmonad, very cool playing with tiling windows <nalaginrut>when we're playing, a designer come and say: oh! it's terrible! remove it! <nalaginrut>well, I think this kind of WM is hard to be accepted by a designer <nalaginrut>it's interesting that our community in Shenzhen is similar with DSL in HK, which is mixed with software/hardware hackers, and designers, tri-hackers <nalaginrut>although we have very different opinions and taste, we're happy to play together ;=D <davexunit>I'm always in disagreement with the user experience people at work. <nalaginrut>well, when we're trying a non-pure-hacking community project, we're listening to designer carefully, it's becoming a habit in our community. <nalaginrut>Anyway, I'm interested in hacking with very different people, only if they're will to work together <nalaginrut>davexunit: I'd like to try guile-wm on hurd, have you tried it? <nalaginrut>since hurd can't support gnome at present, I have to find a cool WM <davexunit>I don't see why guile-wm wouldn't work on hurd <nalaginrut>I'll try it when I back to my work, I'm still on vacation now <nalaginrut>I have a desktop machine running hurd in my office <davexunit>I've just never had the motivation to try hurd. <nalaginrut>well, I have greater interesting in OS than compiler, since I was an embedded software engineer, so I don't fear low-level. But anyway, Hurd is not a thing you'll face low-level... <nalaginrut>I wish there's a guile OS based on Hurd, because micro-kernel could be written with any languages rather than C <zRecursive>nalaginrut: i wish there is a guile based WM first, which must beyond STUMPWM :) <nalaginrut>zRecursive: I'll share it in my blog when I done guile-wm config *nalaginrut 's brand new blog hasn't had a post yet... <nalaginrut>zRecursive: my hurd machine is in my office, but I'm still on vacation ;-) <nalaginrut>anyway, davexunix is playing it on Linux now, I think there shouldn't be problem to run it on hurd <nalaginrut>I helped to fixed a bug in eglibc on hurd, so guile should run on it now <nalaginrut>but I don't know if it's in the latest repo, anyway, I can run it definitely in my machine, because I have the latest package ;-D <jmd>How do I return a value from a guile script? <civodul>jmd: with 'exit' or 'primitive-exit' <civodul>or the return value of the entry point <jmd>the return value of the entry point means that I should be able to have a file with a single line "23" and it should return the status 23 ? <civodul>jmd: it depends on how that script is started <civodul>with #!guile -ds that would work this way, yes <jmd>Ugg. I thought it might. <jmd>ok. I'll use (exit 23) *wingo doing lloda's patchseries, finally <madsy>Does libguile respect the same environmental variables as the guile interpreter does? <madsy>Sweet, If I'm careful, I can make my guile application work no matter what the path is. <jmd>wingo: It isn't a full moon yet. <jmd>Can someone remind me what getvar is in guile? <jmd>hmm not in the Guile Reference index <mark_weaver>wingo: do you want to look at my 'stop-server-and-clients!' patch before I push it? <mark_weaver>(you needn't; I'm reasonably confident that it's good, or at least a major improvement from what's there now) <wingo>mark_weaver: i'm sure it's fine; i'll just take a look out of curiosity :) <wingo>seems like it's an extraordinarily underused part of guile, but whatev's :) <wingo>apparently java removed their equivalent of pthread_cancel, or deprecated it or something <wingo>i think the right solution is to use a wakeup fd <mark_weaver>wingo: 'cancel-thread' seems to work well. I tried canceling REPLs doing various things (sleeping, waiting for input, in the middle of writing large things) and it always seemed to kill it relatively quickly and cleanly. <mark_weaver>how do we implement a wakeup fd? wouldn't it require modifying everything that might block in guile to use select/poll/epoll? <wingo>yes i think that's what we want to do eventually but agreed, for 2.0.10 this sounds fine <wingo>thanks for hacking on 2.0! that's great stuff <mark_weaver>I guess I have to close the underlying fd after all... <mark_weaver>actually, I notice that guile already implements a wakeup fd behind-the-scenes for several blocking operations, including 'select', 'sleep', and mutex locks. but not for reading from file ports. <mark_weaver>if that last piece was there, it would be sufficient to queue an async on the thread to wake it up. <mark_weaver>actually, we're already screwed. a blocked read from the closed socket will never wake up. so mutexes held while reading from the closed socket will be permanently held :-( <wingo>mho: do the minimal thing that helps this use case in 2.0.10, fix it properly later. <madsy>Was the testsuite log useful at all? <mark_weaver>yes, it was. the first time I looked, I grepped only for ^FAIL, and was pleased with the results. later I remembered to also grep for ^ERROR, and see that there's more work to do than I thought. <mark_weaver>but it makes a nice little TODO list for Guile on Windows. <madsy>Also, about 10 tests wouldn't run at all because the test files didn't exist, or because of some other error <mark_weaver>wingo: an easy fix would be to do a 'scm_std_select' before 'read' in 'fport_fill_input'. <madsy>compiler.test, pairs.test, records.test, sort.test, srfi-17.test, srfi-18.test, srfi-98.test, streams.test, vectors.test and web-client.test <madsy>About 4-5 extra tests didn't run because of some misc error. <mark_weaver>'read' could still block, in theory, if something else read from the same FD between the 'select' and the 'read', but any program that reads from the same port from two threads in 2.0 is already playing russian roulette. <wingo>mark_weaver: you still need the fd to be in nonblocking mode <wingo>i mean, in a proper solution <madsy>mark_weaver: open-file often errored with "illegal argument" or "no such file or directory" <wingo>but we are talking about hacks :) <mark_weaver>wingo: agreed, but that has major backward-compatibility issues, given that we allow users to get the FDs. <mark_weaver>I agree that the FD should ideally be in non-blocking mode, of course. <madsy>mark_weaver: And i18n.test failed to set the locale, and errored <wingo>the ethreads/nio stuff is like that <wingo>scm_std_select doesn't tell you how many bytes are readable though, does it? <mark_weaver>no two threads can read from the same port at the same time. if they do that, the program is already broken. the only case that's theoretically legit that this would fail for is if the program reads from the underlying FD from another thread, while reading from the port. <wingo>i guess there is code for that <mark_weaver>wingo: hmm. am I remembering wrong that read(2) only blocks if there's no bytes available? (maybe I'm embarrassing myself here :) <wingo>read(2) says that read may return fewer bytes, but it doesn't mention that it's required <mark_weaver>if it could block when there's a byte available, then we're already in trouble, again. <mark_weaver>it would mean that 'read-u8' could block even when there's a byte available, if there's not enough to fill the whole buffer. <mark_weaver>it seems like it would be very bad if that was the case. <mark_weaver>any library that supports buffered reading would run into this problem. <madsy>mark_weaver: You downloaded the raw log file, right? The full file is about 3 MiB. The direct link you got was truncated. *mark_weaver wishes github would just give me the file itself, rather than a tarball, but whatevs :) <madsy>mark_weaver: It does if you click the "view raw" link <madsy>Anyway, just had to check. Didn't want to all this work for you to base a TODO list on a truncated file <mark_weaver>madsy: so, one thing I noticed: 'lstat' is not available in your Guile build. there's a gnulib module for 'lstat' that we could include, but currently we don't. <mark_weaver>we won't be able to fix all of this before 2.0.10 is out, but I'd like to fix these things for 2.0.11. <madsy>None of the bugs/limitations is something that will impact me anyway <madsy>At least not for my demo 3D engine <mark_weaver>cool. have you tried your 3D engine on the windows build? <madsy>Just need to eat dinner first <mark_weaver>if the number of fixes is small, maybe we can get some of them into 2.0.10 <madsy>davexunit: My own. It doesn't have a name. <madsy>It's a high level wrapper for a subset of OpenGL <davexunit>madsy: cool. :) do you know about guile-figl? <davexunit>it's a pure guile opengl wrapper that I use for my 2D engine/library/thing. <madsy>davexunit: Yep, you've mentioned it before. <madsy>But I call guile from a C++ process, I'm not using the guile executable <madsy>Also, I'm doing some magic with OpenGL shared contexts <madsy>I have a separate render thread <madsy>But I'll keep guile-figl in mind if I want to do something in pure scheme later :) <wingo>mark_weaver: yes, that's why putting the fd into nonblocking mode is the only correct solution <mark_weaver>wingo: agreed (though I worry that we will break a lot of software) <mark_weaver>but at some point, we should probably bite the bullet and do that. <mark_weaver>well, I suppose there are other options, like using platform-specific interfaces on the common platforms that avoid blocking without setting that mode. <mark_weaver>if it fallout of setting non-blocking mode is bad enough, it might be worth considering. <mark_weaver>and on platforms that never block for long in read(2) if there's at least one byte available, we wouldn't have to do anything. <mark_weaver>on platforms that allow sending a signal to a specific thread, that's another option. <mark_weaver>well, I suppose writing tons of platform-specific code is too terrible to really consider. <wingo>yeah we really need to rely on posix here; imo anyway <mark_weaver>Here's a relevant quote: "When attempting to read a file (other than a pipe or FIFO) that supports non-blocking reads and has no data currently available: [...] The use of the O_NONBLOCK flag has no effect if there is some data available." <mark_weaver>but buffered I/O reads from FDs without O_NONBLOCK would have serious problems if 'read' blocked otherwise. <mark_weaver>especially for pipes or FIFOs, which is the one case not covered by the POSIX language above. <mark_weaver>maybe I should ask the question in some forum where experts on this subject can be found. <mark_weaver>my one concern is that inserting a call to 'scm_std_sleep' before 'read' might significantly slow down reads unbuffered ports. <mark_weaver>The buffered I/O code in glibc would have to cope with this exact issue. <madsy>mark_weaver: On what forums do these mythical glibc experts frequent? ;-) <madsy>I meet a lot of clever people on FreeNode, but I've never met any open-source developer on online forums <wingo>mailing lists only, methinks <wingo>mark_weaver: wdyt about blessing arrays (proper arrays, with tc7_array) as the only possible "array implementation" for rank >1 arrays in guile? *wingo been going through lloda's thing today <mark_weaver>wingo: btw, my Thinkpad X200 has been building eval.go for 17 hours so far, current master. gc-7.4 <wingo>mark_weaver: pull from git, methinks <wingo>did you see the link i pasted? <mark_weaver>wingo: this is using b914b23, which is the last non-array commit. <wingo>see above pull request, seems we had a user actually track down the infinite loop <mark_weaver>unfortunately, GNU Guix has a policy to only use tarballs, and is on gc-7.4 <wingo>in that case set GC_MARKERS=1 when you build :) <wingo>parallel marking does speed things up considerably, when it works :) <wingo>np, hope it works; i haven't had the iloop behavior since pulling from libgc git <wingo>but that doesn't mean that everything is perfect :) <wingo>an amusing thing i saw with the recursive map investigations was that parallel heap marking was making it so that serial stack walking and marking was a bottleneck for long stack traces (!) <wingo>not clear how to fix that nicely, and i'm not going to try :P <mark_weaver>wingo: the other thing about recursive map is that the amount of memory used on the stack is probably a lot bigger than the amount of memory needed by the original list. <wingo>it's not necessarily a lot bigger <wingo>depends on how you compile it; it could be the same size <mark_weaver>wingo: so, the one potential semantic problem I see with using 'reverse!' is that the proc might invoke its continuation more than once. <wingo>each link in the original list would be one RA and one mapped value <mark_weaver>but, then it occurred to me that the behavior in that case is already somewhat undefined, given that the order of application is not specified. <wingo>mark_weaver: of course; that's why (rnrs base) uses reverse and not reverse! <wingo>recursive map does have clearer advantages over reverse (as opposed to reverse!) <wingo>and the stack usage is just a memory transient <mark_weaver>ah, yes: "If multiple returns occur from map, the values returned by earlier returns are not mutated." <mark_weaver>wingo: regarding the array thing: are multidimensional uniform numeric arrays supported by "proper arrays"? <mark_weaver>and are they represented in a way that allows efficient loops to be compiled? e.g. for implementing efficient matrix operations. <wingo>np, thanks for thinking about it :) <mark_weaver>regarding recursive map, I'd be okay with some reduction in performance in return for better semantics, as long as the stack usage is efficient, and as long as it can handle lists approximately as long as a 'reverse' based implementation could handle. <mark_weaver>i.e. as long as there's not some arbitrary stack limit that will be hit long before memory is exhausted. <wingo>cool, i was thinking something like that <wingo>will have to try a few more compilation-related things <wingo>not sure how to improve perf for deep stacks; or what the situation is for smaller stacks <wingo>worst case is twice as slow (e.g. 3s versus 1.5s, something like that) <wingo>which I'd like to improve... <mark_weaver>how much slower is it for typical-size lists, say under 100? <wingo>dunno, the $callk stuff might help (skip prelude, jump directly into body), and closure optimization <mark_weaver>"twice as slow" compared to what? 'reverse!' based map? <wingo>compared to "reverse" it's better of course <mark_weaver>well, given that both R6RS and R7RS rule out 'reverse!'-based map, I think that's just a bug to be fixed anyway. <mark_weaver>I'm willing to pay more for a standards-conforming map. <wingo>e.g on a 1e7 sized list mapping identity, the recursive version is 1.6s whereas "reverse" is 1.35s <mark_weaver>what is the current story with stack limits on master? <wingo>on that workload "reverse" has a heap size of 488361984 <wingo>whereas the recursive one has a size of 328507392 <wingo>that's the size from gc-stats <wingo>anyway, more testing to do, and i should see if i can make more progress with lloda's thing; there are good things and questionable things in that patch series... <wingo>mark_weaver: yes, and it's low; you have to set a higher thing via GUILE_STACK_SIZE to test that out <wingo>figuring out the limit at which to throw stack overflow is tricky <mark_weaver>I guess I think that rlimits are the proper solution there. <mark_weaver>I realize that infinite recursion is a very common error, but it's also quite possible to write a program that allocates without bound. <wingo>could be, but c's rlimits aren't thought out to work like this <mark_weaver>well, maybe not rlimits, but a maximum heap size anyway. <mark_weaver>I'd prefer to treat the stack like any other memory, I guess. maybe I'm being too simplistic, but semantically Scheme doesn't even have a stack, it's all heap. <wingo>yeah, sounds about right to me too ***ozzloy_ is now known as ozzloy
<wingo>man, arrays code. the worst. <wingo>hum i think i broke the tests somehows <wingo>that's me pushing his branch :) <wingo>it's his patchset from last april/may <wingo>i rebase it as i merge and change things <wingo>a number of questions remaining though... *mark_weaver just realized that I used SRFI-1's map in my R7RS branch, but that's not correct since SRFI-1 map uses 'reverse!'. <mark_weaver>I wonder how many different 'map' and 'for-each' implementations we have in Guile now. Quite a few. <davexunit>I was recently wondering about how map has been implemented. <mark_weaver>we'll have a fourth soon, unless some of these can be combined :) <davexunit>since defining map recursively reads nicely but is no good in practice. <wingo>srfi-1 and r7rs should be the same, no? <wingo>davexunit: why do you say it is no good in practice? :) <mark_weaver>that's what I thought, but our current SRFI-1 map uses 'reverse!'. *mark_weaver looks at the SRFI-1 spec to see if this is allowed. <davexunit>wingo: well, the naive implementation would have a call like: (cons (proc (car lst)) (map proc (cdr lst))) <davexunit>input a big list and you get a nice stack overflow. :) you know that, of course. <davexunit>and now you can educate me about your approach :) <mark_weaver>SRFI-1 doesn't talk about multiple returns, so I guess it's allowed to use 'reverse!'. <wingo>davexunit: in master you can have a stack as big as your heap, and it's cheap :) <wingo>and when you return from the call chain the memory is returned to the os. <mark_weaver>it's a beautiful thing. one less case where code has to be mucked up to be scalable :) <davexunit>using reverse was the only way I knew how to write something like map with tail calls that didn't output stuff backwards. <davexunit>but using reverse seems unpleasant since you've already iterated over the entire list, and now you have to do it again to reverse it. <mark_weaver>it's also possible to build the list in the correct order as you go, using 'set-cdr!', but that's ugly too. <mark_weaver>and it doesn't conform to the requirements of R6RS and R7RS regarding <davexunit>yeah I don't like to mutate unless necessary. <mark_weaver>"multiple returns", i.e. the 'proc' invoking its continuation more than once. <mark_weaver>davexunit: anyway, in case it's not clear, wingo's recent "expandable stacks" work on 'master' means that you can use the naive implementation of map that you wrote above. <wingo>the only tricky thing is when to decide to throw a "stack overflow" exception :) <davexunit>now, is this a "with great power comes great responsibility" thing? <mark_weaver>it's still better to use tail calls where possible, but in this case you have to allocate memory for each iteration anyway, so it's not really any worse. <davexunit>I figured iterative approaches are still preferable. <mark_weaver>anyway, I have to go offline for a while. heading to radio..