IRC channel logs

2014-02-06.log

back to list of logs

<mark_weaver>ah, interesting. refresh my memory, does windows use CR LF ?
<mark_weaver>i.e. \\r\\n
<madsy>yes
<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>oh, wait.
<mark_weaver>oh, nevermind. yeah, like I said :)
<mark_weaver>if MSDOS is defined, then read also considers Ctrl-Z to be a space, in addition to the others.
<madsy>Now I'm getting somewhere.
<mark_weaver>that's good!
<madsy>Running 00-initial-env.test
<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.
<mark_weaver>hmm, what did you pass to 'main' there?
<mark_weaver>yeah, I guess something is broken there.
<madsy>The third argument you invoke main with is relative to the primitive-load-path
<mark_weaver>can you get a scheme backtrace from that error?
<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'.
<madsy>Here's how far I get now. http://paste.lisp.org/display/141155#1
<mark_weaver>in fact, it should just be "<NAME>.test" where <NAME> has no directory separators.
*mark_weaver looks
<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>Yayy
<madsy>Ran the first test now without a hitch
<mark_weaver>sweet!
<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>(one can hope :)
<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
<mark_weaver>so what fixed it?
<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>oh, that's great news!
<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>I'm not sure what's up with that one.
<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>madsy: sounds good, thanks!
<mark_weaver>I have to go afk for a bit. but this is great progress!
<madsy>Yep
<madsy>Sorry for being so thick about the windows console bug
<madsy>I should have thought of that earlier
<madsy>mark_weaver: https://gist.github.com/Madsy/8836126
<mark_weaver>madsy: looks great!
<mark_weaver>the documentation errors are just because it can't find guile-procedures.txt
<mark_weaver>that's most of the failures.
<mark_weaver>there are some search-path issues to be fixed.
<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>Glad I could help
<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 :)
<nalaginrut>morning guilers~
*davexunit is using the tiling wm in guile-wm
<davexunit>weeee
<nalaginrut>oooh
<davexunit>it's pretty solid.
<davexunit>have to manually create all the keybinds though
<nalaginrut>yeah
*davexunit crashed guile-wm
<davexunit>heh
<nalaginrut>comments for comparing with xmonad? ;-)
<davexunit>never used xmonad.
<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!
<davexunit>designers don't mix well with hackers.
<nalaginrut>well, I think this kind of WM is hard to be accepted by a designer
<davexunit>yeah, they look ugly on purpose.
<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>well that's good. :)
<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
<davexunit>:)
<nalaginrut>s/will/willing
<nalaginrut>davexunit: I'd like to try guile-wm on hurd, have you tried it?
<davexunit>nalaginrut: I have never used hurd.
<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
<davexunit>all you need is guile and xorg
<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>neat.
<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
<nalaginrut>well, it's personal taste
<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
<davexunit>zRecursive: guile-wm is pretty good
*nalaginrut 's brand new blog hasn't had a post yet...
<zRecursive>nalaginrut: is it working now ?
<nalaginrut>zRecursive: my hurd machine is in my office, but I'm still on vacation ;-)
<zRecursive>wait for your blog
<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
<nalaginrut>s/fixed/fix
<civodul>Hello Guilers!
<civodul>hey, jemarch! :-)
<civodul>it's a bit early, uh? ;-)
<jemarch>civodul: :)
<madsy>Hey all :)
<jmd>How do I return a value from a guile script?
<civodul>hey jmd
<civodul>jmd: with 'exit' or 'primitive-exit'
<civodul>or the return value of the entry point
<jmd>Thanks Ludo.
<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 ?
<wingo>good day
<civodul>hello wingo!
<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)
<jmd>thanks.
*wingo doing lloda's patchseries, finally
<madsy>Hey all :-)
<madsy>Does libguile respect the same environmental variables as the guile interpreter does?
<civodul>yes
<wingo>jaoooooo
<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.
*jao waves at wingo
<wingo>greets
<jmd>Can someone remind me what getvar is in guile?
<civodul>getenv
<jmd>hmm not in the Guile Reference index
<jmd>Oh yes it is.
<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>does cancel-thread work?
<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> http://stackoverflow.com/questions/671049/how-do-you-kill-a-thread-in-java
<wingo>i think the right solution is to use a wakeup fd
<mark_weaver>wingo: sorry, was afk for a while.
<wingo>np :)
<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?
<mark_weaver>I don't want to take on that much for 2.0.10.
<wingo>cool
<mark_weaver>I used a wakeup fd for the server listener though.
<wingo>yes i think that's what we want to do eventually but agreed, for 2.0.10 this sounds fine
<wingo>we can always revisit
<mark_weaver>okay, sounds good. thanks!
<wingo>thanks for hacking on 2.0! that's great stuff
<mark_weaver>np :) thanks for the new VM work :)
<mark_weaver>damn. cancel-thread doesn't unwind the stack :-(
<mark_weaver>so it could leave abandoned mutexes.
<mark_weaver>I guess I have to close the underlying fd after all...
<mark_weaver>I have to do that for coop-repl-servers anyway.
<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>*and fat mutex locks.
<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 :-(
<mark_weaver>damn :-(
<wingo>mho: do the minimal thing that helps this use case in 2.0.10, fix it properly later.
<wingo>don't let it block you.
<wingo>just mho :)
<mark_weaver>yeah
<madsy>hey mark
<mark_weaver>hi madsy!
<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>what test file didn't exist?
<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>I think that's all of them
<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.
<wingo>yes of course
<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
<mark_weaver>but I think this solution is almost proper.
<mark_weaver>and probably the best we can do in 2.0 at least.
<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>good question...
*mark_weaver looks it up
<wingo>read(2) says that read may return fewer bytes, but it doesn't mention that it's required
<wingo>so again, an 80% solution.
<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>yeah, I downloaded the zip file.
<mark_weaver>or the .lzma, rather.
*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
<mark_weaver>ah, okay
<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>there are a lot of things like that.
<madsy>Right
<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.
<mark_weaver>and I hope to get 2.0.11 out in maybe 2-3 months.
<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>I will tonight
<madsy>Just need to eat dinner first
<davexunit>what 3d engine?
<mark_weaver>if the number of fixes is small, maybe we can get some of them into 2.0.10
<mark_weaver>madsy: okay, sounds good.
<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
<davexunit>oh, okay. :)
<davexunit>carry on, then.
<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>s/if it/if the/
<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, this requires more research.
<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>yeah
<mark_weaver>wingo: fwiw, having now read http://pubs.opengroup.org/onlinepubs/9699919799/functions/read.html , I get the strong impression that 'read' is not supposed to block if there's at least one byte available.
<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>I admit that it's not as clear as I'd like.
<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>s/is the one case/are the two cases/
<mark_weaver>maybe I should ask the question in some forum where experts on this subject can be found.
<wingo>neat
<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>s/reads/reads from/
<mark_weaver>s/one concern/main concern/
<mark_weaver>The buffered I/O code in glibc would have to cope with this exact issue.
*mark_weaver looks
<mark_weaver>I actually have commit access to the glibc repo.
<wingo>woo :)
<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
<madsy>yeah
<mark_weaver>right, I meant an ML.
<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
<wingo>it seems ok to me
<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?
<madsy>17 hours? woah
<wingo> https://github.com/ivmai/bdwgc/pull/30
<mark_weaver>wingo: this is using b914b23, which is the last non-array commit.
<mark_weaver>so I think there's still a problem with GC.
<wingo>libgc git i mean
<mark_weaver>ah, okay.
<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>humm.
<mark_weaver>well, that's not your problem though :)
<wingo>in that case set GC_MARKERS=1 when you build :)
<wingo>in the environment
<mark_weaver>fair enough :)
<wingo>parallel marking does speed things up considerably, when it works :)
<mark_weaver>we could also cherry-pick a bug fix for guix.
<mark_weaver>okay, that patch is nice and small.
<mark_weaver>thanks for the link.
<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 :)
<mark_weaver>*nod*
<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
<wingo>(long == hundreds of mb)
<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>it's on the same order
<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>r7rs does define this fwiw
<wingo>recursive map does have clearer advantages over reverse (as opposed to reverse!)
<wingo>heap size stays lower
<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>(says R7RS)
<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>yes
<mark_weaver>okay, then it's fine with me.
<wingo>cool
<mark_weaver>thanks for asking :)
<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
<wingo>mark_weaver: no idea
<mark_weaver>"twice as slow" compared to what? 'reverse!' based map?
<wingo>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
<wingo>for a GC_MARKERS=1 run
<mark_weaver>oh, I think it's a no brainer then :)
<mark_weaver>what is the current story with stack limits on master?
<wingo>on that workload "reverse" has a heap size of 488361984
<mark_weaver>ouch :)
<wingo>whereas the recursive one has a size of 328507392
<wingo>64-bit system of course
<wingo>that's the size from gc-stats
<mark_weaver>is there a stack limit in master?
<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
<wingo>that's a bug to fix
<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
<mark_weaver>stacks are just an efficiency hack, really.
<mark_weaver>cool :)
***ozzloy_ is now known as ozzloy
<wingo>man, arrays code. the worst.
<mark_weaver>heh, yeah.
<wingo>hum i think i broke the tests somehows
<mark_weaver>I see that lloda is busy on the "ra0" branch :)
<wingo>that's me pushing his branch :)
<mark_weaver>ah...
<wingo>it's his patchset from last april/may
<wingo>i rebase it as i merge and change things
<mark_weaver>makes sense
<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 always mess up my pronouns with /me)
<mark_weaver>I wonder how many different 'map' and 'for-each' implementations we have in Guile now. Quite a few.
<wingo>:)
<wingo>i think we have three
<davexunit>I was recently wondering about how map has been implemented.
<wingo>boot-9, srfi-1, and r6rs
<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.
<davexunit>wingo: well, color me impressed.
<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>mark_weaver: that's very cool.
<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.
<mark_weaver>and in many ways it's better.
<davexunit>okay, that makes sense. thanks.
<davexunit>I figured iterative approaches are still preferable.
<mark_weaver>anyway, I have to go offline for a while. heading to radio..
<mark_weaver>ttyl!
<davexunit>mark_weaver: bye!
<davexunit>I dig MIT radio, btw :)
<mark_weaver>:)
<cluck>:)
<taylanub>cluck: Fancy seeing you here :)