IRC channel logs

2014-08-29.log

back to list of logs

<taylanub>boot-9.scm does (module-ref (current-module) '%exception-handler) to get the current exception-handler object. I can't seem to do the same?
<taylanub>rather, to get the fluid for it
<taylanub>well no wonder, it removes %exception-handler at the end. uh, this means the fluid is "trapped" within that lexical scope I guess.
<taylanub>ijp: http://sprunge.us/BCIQ tell me if I'm missing something obvious
<taylanub>and `raise' would only differ in that after the (eh exc) call it does another `raise' call with &non-continuable. (I'm missing null-checks, or a top-level handler that quits, of course.)
<taylanub>now `guard' would need to use call/cc I suppose
<taylanub>it seems neither `raise' nor `raise-continuable' actually need to do any stack unwinding at all; they just call/traverse handlers from the stack without touching the dynamic environment except for temporarily popping that stack to prevent a handler from recursing; at the end of the stack there's a handler that quits (or raise* do a null-check on the stack and do that themselves)
<ijp>the combination of with-exception-handler and raise is pretty useless without call/cc
<taylanub>yes, all it does by default is quit the program. the handler itself is responsible for calling some continuation to save the program
<taylanub>this is implemented by `guard'. but other than that, `with-exception-handler' and raise* seem to need no call/cc in their own implementations
*taylanub goes to sleep
<taylanub>g'night!
<ijp>taylanub: all the same, this isn't a very good argument, because raise and guard are the actually useful parts
<ijp>and I still say the srfi 34 behaviour of with-exception-handler is flat out wrong
<taylanub>ok I'm still here :P do you mean wrt. not changing the dyn env except for the handler?
<ijp>yes
<taylanub>could be useful IMO, inspecting the raise call's dyn env from the handler
<ijp>well, that's a tautology
<ijp>In guile we have pre-unwind handlers for a similar purpose, and I'm struggling to come up with a good *user level* usecase
<Gillecomgain>taylanub, it's only needed in guard.
<Gillecomgain>Guard installs a current exception handler that needs to escape, that's all.
<Gillecomgain>The Ikarus implementation does seem to imply that really the only semantic difference between raise and raise-continuable is that the former needs to check for the handler returning and then raise an exception. But in certain implementations this can achieve more efficiently because that also means that it doesn't need to esupport the handler returning
<Gillecomgain>You can probably even setjmp/longjmp it.
***linas__ is now known as linas
<nalaginrut>morning guilers~
<paroneayea>got excited about miniKanren, though it seems to be proprietary, though I suspect that's due to neglect rather than intent
<paroneayea> https://github.com/miniKanren/miniKanren/issues/4 I opened a bug
<pallagun>If I need to get my guile drawing to a 3d canvas should I be using guile-gnome, guile-gtk or possibly guile-sdl?
<pallagun>It seems guile-gtk is a ~subset of guile-gnome. So maybe that's not the best option.
<nalaginrut>3d? maybe guile-opengl
<pallagun>ahh, I didn't even see that. I'll investigate, thanks.
***_zxq9_ is now known as zxq9
<civodul>Hello Guilers!
<taylanub>paroneayea: someone ported some kanren thingy to Guile IIRC
<taylanub>I can't find it via Google right now. I could've sworn there was a "guile-kanren" project
<taylanub>hm, how do I send a feature-request to bug-guile@gnu.org ?
<civodul>mini-kanren works pretty much out of the box IIRC
<civodul>it's in the guildhall even
<civodul> http://github.com/ijp/minikanren/
<taylanub>it seems we implement SRFI-34's `guard' wrong in that we don't re-raise from the original raise call's dyn env but from that of the currently tried guard layer
<taylanub>I know that part of it is criticized for causing a back-and-forth jumping in the stack, but even our docstring is straight from SRFI-34 and thus we don't follow our own documentation either, let alone documenting the diversion from the spec...
<Gillecomgain>taylanub, I seem to have gotten you interested in this.
<Gillecomgain>Truth be told, they get what's coming to them for phrasing it in such vague language from time to time, justice I say.
<taylanub>I'll be writing patches at least to make `raise' and `raise-continuable' work without unwinding. currently I'm under the impression that `guard' diverses from the spec on intention in the case of R6RS (our documentation *is* different from the R6RS there) though it needs documenting under "R6RS Incompatibilities" in that case, and SRFI-34's diversion might or might not been intentional but
<taylanub>definitely goes against the documentation so will need some fix too...
<Gillecomgain>taylanub, is that by the way really a bug, reading again?
<Gillecomgain>I thought you meant the invert.
<Gillecomgain>I'm fairly certain that guard needs to re-raise, at least in r6, from its own dynamic environment
<Gillecomgain>not sure if srfi 34 is different in that?
<Gillecomgain>Ahh, I see
<Gillecomgain>The entire dynamic environment in guile is set to guard, not just the exception handler?
<Gillecomgain>Yeah, that'd be a bug.
<taylanub>the fact that our R6RS raise* implementations unwind might be fine with the spec since it's so ambiguous, but it's not an optimal implementation I think. the fact that R6RS guard diverses from the spec seems to be intentional and just needs more explicit documentation IMO. the fact that SRFI-34 guard diverses from its own Guile documentation is clearly a bug that can be solved either by changing
<taylanub>the implementation or the documentation.
<Gillecomgain>taylanub, how does it differr from r6rs?
<Gillecomgain>In the same way?
<taylanub>Gillecomgain: which?
<Gillecomgain>the guard
<Gillecomgain>Does it also differ in that it sets the entire dynamic environment of the raise to that of the guard?
<taylanub>Gillecomgain: in R6RS guard, if none of the cond clauses match, it needs to re-raise from the dyn env from the original raise call (rewinding the stack, because it was unwound for the cond clauses), meaning that e.g. a bare exception-handler (not guard) that wraps around the guard would be executed in the dyn env of the raise call and not the guard. let me give an example...
*taylanub is puzzled, it actually seems to work as specified in R6RS
<taylanub>oh, it just behaves even more differently than I thought so my test failed
<taylanub>Gillecomgain: http://sprunge.us/ILbM
<Gillecomgain>taylanub, yeah, I gather
<Gillecomgain>it re-raises in the complete same dynamic environment as the original raise, while it should raise in the dynamic environment of guard with the exception of the current-exception handler.
<Gillecomgain>Oh wait
<Gillecomgain>it's even worse.
<Gillecomgain>It takes on the dynamic environment of the call to raise even if it does not re-raise?
<taylanub>it does not unwind at all while evaluating the guard clauses
<taylanub>s/while/before/
<taylanub>I'm still a little confused myself to be honest, haven't wrapped my head around all of throw, with-throw-handler, catch / raise, raise-continuable, with-exception-handler, guard / SRFI-34 raise, with-exception-handler, guard yet. three sets of similar but different procedures/syntaxen, the first implementing the latter two :)
<Gillecomgain>Truth be told, I'm a bit puzzled on how to implement the re-raise in the dynamic environment of the old raise myself.
<Gillecomgain>My own implementation currently has the bug that it re-raises in the dynamic envrionment of the guard and I'm not sure how to fix that.
<taylanub>`raise' needs to use call/cc so it can pass its continuation to the handler, which if the cond clauses fail calls it
<Gillecomgain>Hmm, it doesn't do that in Ikarus.
<Gillecomgain>But maybe Ikarus suffers fromt he same bug.
<Gillecomgain>So the handler needs to be a two argument procedure, grabbing the condition and the continuation?
<taylanub>however you want; two args or one object encapsulating the two.
<Gillecomgain>Well, that's actually not true, you can get the continuation from the exception handler itself right?
<Gillecomgain>They are the same are they not?
<Gillecomgain>So you can expand guard to something like (with-exception-handler [lambda [con] (call/cc [lambda [this-is-the-continuation-you-want] .....
<taylanub>please don't use square brackets
<taylanub>the problem with that is that you can't rewind back to the 'raise' environment once that continuation there is called to unwind to the 'guard' environment, which you want to do if the guard's clauses fail
<nalaginrut>implement Artanis as green-threaded is so big work, I realized I need: 1. non-blocking; 2. scheduling based on delimited-continuations; 3. guile-dbi needs non-blocking too; 4. enhanced connection pool; 5. epoll/kqueue wrapper
<nalaginrut>but I still excited, maybe do it in Artanis-2.0
<taylanub>I *think* I finally understand why ijp said raise-continuable needs to use call/cc, although it doesn't apply to Guile because it doesn't conform to the guard spec
<Gillecomgain>taylanub, I'm not sure I follow, both continuations are identical.
<Gillecomgain>raise-continuable needs to call the handler in tail context no?
<taylanub>Gillecomgain: the 'raise' and 'guard' continuations are obviously not identical. when 'raise' is called, it rolls down to the 'guard' continuation/dynenv and tries the cond clauses. if they don't match it rolls back up to the raise continuation/dynenv. so you need call/cc both ways
<Gillecomgain>taylanub, no, the raise and guard ones aren't, but the one of raise-continuable and the handler are.
<Gillecomgain>Like you said, (define-round-braces (raise-continuable con) ((current-exception-handler) con)) comes close with the exception of some minor things.
<Gillecomgain>So you can get the continuation of raise-continuable from within the handler.
<taylanub>the continuation of 'raise-continuable' and the 'guard' clauses need be the same, but not the dyn envs, so you want to call/cc there and back to temporarily change the dyn env but then get back to the same continuation
<taylanub>by the way, the implementation I gave ijp was fine only at the absence of a corresponding 'guard' implementation. I thought that 'guard' could be implemented independently without causing changes to those definitions I pasted, but I realize this is wrong, because when 'guard' causes a stack unwind, it has no way to do a rewind (when the clauses fail) unless 'raise'/'raise-continuable' use call/cc
<taylanub>to give 'guard' their continuation
<Gillecomgain>taylanub, well, that's the part I don't get. So you re saying that it should be something like (define (raise-continuable con) (call/cc (lambda (k) ((current-exception-handler) con k)) right?
<Gillecomgain>That k has to be pasesed to )current-exception-handler)?
<taylanub>yes, though in an encapsulated fashion, since the user-provided handlers are unary procedures and don't see the continuation argument
<Gillecomgain>taylanub, yeah, so you can get k from within the current exception handler without passing it to it. That's the part I don't get.
<Gillecomgain>The continuation of the ((current-exception-handler con k) is the same as that of the call to raise-continuable itself.
<Gillecomgain>IT's a tail call.
<taylanub>the cont of that is fine, yes, but 'guard' jumps to another one before trying its cond clauses, and needs a way to jump back
<Gillecomgain>Yeah, but the continiuation of the current exception handler is not that of guard.
<Gillecomgain>It's that of raise.
<Gillecomgain>We're talking about guard expanding to a with-exception-handler call right?
<Gillecomgain>Like (guard <else-forms> <body>) is basically to expand to something like (with-exception-handler <some-handler> (lambda () <body>)) right?
<Gillecomgain>And the implementation of the <some-handler> is the tricky part
<taylanub>'guard' sets up an exception handler which jumps to the continuation of the 'guard' form, thus losing the original continuation of the exception handler
<taylanub>that's why the handler needs to be given a continuation by raise/continuable. a handler installed by 'with-exception-handler' simply ignores that continuation; one installed by 'guard' uses it to jump back when the clauses fail
***DerGuteM1 is now known as DerGuteMoritz
<Gillecomgain>taylanub, I don't follow: http://hastebin.com/raw/gorudegaqe
<Gillecomgain>This implementation captures both the continuation of the guard and that of raise without needing either passed, no?
<Gillecomgain>Forgot the (lambda () <body>)
<Gillecomgain>But youget what I mean
***siel_ is now known as siel
<taylanub>oh, I think you're right. I get what you mean now when you emphasize that the handler's continuation is that of the 'raise'; it means guard can just capture the raise continuation there in the handler it installs and doesn't need the help of 'raise' itself
***nalaginrut_ is now known as nalaginrut
<Gillecomgain>taylanub, yeah
<Gillecomgain>inspecting this in guile, while the continuations do not eq?, they do print identically.
<Gillecomgain>displaying a continuation seems to give it a number and they match up
<Gillecomgain>I guess guile just doesn't want to call functions eq? easily.
<taylanub>if they're the same procedure in memory, they're eq?
<Gillecomgain>taylanub, well, apparently they aren't, even though they write out as the same continuation.
<Gillecomgain>Same number in display
<Gillecomgain>One assumes that number is a memory address, so hmm
<taylanub>oh, no idea
<Gillecomgain>So that brings us back to the original point, why would raise and raise-continuable need call/cc?
***ft_ is now known as ft
***siel_ is now known as siel
<mark_weaver>taylanub: I suggest you look at the SRFI-34 reference implementation
<taylanub>Gillecomgain: you know, you're free to write bug reports / feature requests and (better yet) send patches :) the more I delve into this the more it seems I underestimate its complexity and Guile somehow does the right thing after all though
<taylanub>mark_weaver: thanks for the pointer. that one's missing raise-continuable though which spices things up a bit
<Gillecomgain>taylanub, that would require me to understand any of this though, every time I think there's a bug I actually made an error myself.
<Gillecomgain>34 seems to leave it opaque whether or not it can continue or not, free for implementations to choose
<Gillecomgain>I guess r6 didn't like that and wanted to standardize so they split it up.
<Gillecomgain>Maybe they could've made raised-continuable optional
<Gillecomgain>mark_weaver, would you hapen to know if the number it prints when you display a continuation is a memory address?
<Gillecomgain>And if so, why do two continuations with the same rpinted number do not eq?
<mark_weaver>Gillecomgain: example code to demonstrate?
<nalaginrut>I wonder how can you capture another continuation with same Vaddr rather than ref the same one
<Gillecomgain>mark_weaver: http://hastebin.com/raw/digonuduwi
<Gillecomgain>Hmm
<Gillecomgain>the numbers were different thisone time
<nalaginrut>it's different for me too
<Gillecomgain>Yeah
<Gillecomgain>I think it must have used the old cached version for me which used a wrong display.
<Gillecomgain>Nothing to see here I guess
<Gillecomgain>I had a (display k) instead of (display k*) this morning.
***heroux_ is now known as heroux
<Gillecomgain>taylanub, by the way, how does one extract the dynamic environment from a continuation?
<Gillecomgain>My current implementation of guard basically has '[else (raise non-continuable-exception)]' which raises it in the dynamic environment of guard obviously.
<taylanub>Gillecomgain: you can't; you need to call it. which is causing me huge trouble in trying to implement guard :(
<Gillecomgain>Ah, you too eh.
<mark_weaver>srfi-34 reference implementation
<Gillecomgain>But that's no sport, cheating.
<Gillecomgain>We have been challenged by ijp and intend to do it honourably.
<mark_weaver>:)
<taylanub>I thought that one doesn't support raise-continuable, or can that be implemented on top of that with no change to the 'guard' definition?
<mark_weaver>The SRFI-34 reference implementation could extended to support raise-continuable very easily, afaict.
<mark_weaver>*could be
<mark_weaver>one hint when reading that code: the variable 'handler-k' is confusingly named. it is not actually the handler's continuation.
<lloda>is (max +nan.0 3.) => +nan standard? C99 fmax says 3. I can't find what IEEE 754 says.
<mark_weaver>interesting
<lloda>i found a paper by Kahan http://www.eecs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF
<lloda>he says
<lloda>Some familiar functions have yet to be defined for NaN . For instance max{x, y} should deliver the same result
<lloda>as max{y, x} but almost no implementations do that when x is NaN . There are good reasons to define
<lloda>max{NaN, 5} := max{5, NaN} := 5 though many would disagree.
<lloda>end quote.
<mark_weaver>lloda: ah yes, the R6RS library document specifies that 'flmin' and 'flmax' "always return a NaN when one or more of the arguments is a NaN."
<mark_weaver>(section 11.3)
<taylanub>TIL of the pattern ((call/cc (lambda (k) ... (k (lambda () ...)))))
<mark_weaver>ignoring the NaN in min and max seems dubious to me, although I generally respect Kahan's work and IEEE 754
<mark_weaver>what does "TIL" stand for?
<taylanub>Today I Learned
<mark_weaver>ah, yes :)
<mark_weaver>lloda: IEEE 754-2008 agrees with C99 about min and max.
<mark_weaver>maybe we should add variants of min and max that follow the IEEE and C99
<taylanub>I just invented(?) something crazy: http://sprunge.us/Jjdj this returns a procedure that calls the given proc in the current dyn env. might make the guard implementation cleaner...
<taylanub>(to be clear, I know that this whole "stack dancing" of guard is undesired; I don't plan on proposing a patch for it. maybe for its documentation)
***paroneay` is now known as paroneayea
<dsmith-w`>Happy Friday, Guilers!!
***dsmith-w` is now known as dsmith-work
<Svetlana>aww <3 I'm about to enter a saturday night
<Svetlana>have a nice day i guess :)
<paroneayea>yay, minikanren now clarified to be MIT/Expat
<paroneayea> https://github.com/miniKanren/miniKanren
<paroneayea>as opposed to nonfree
<taylanub>wow, this was a crazy exercise: http://sprunge.us/LAij didn't test it much
<lloda>is call/cc necessary at all? http://lists.scheme-reports.org/pipermail/scheme-reports/2012-February/001824.html ff.
<taylanub>I'm also convinced that composable continuations > uncomposable continuations. what I attempted is an R6RS exceptions implementation in pure Scheme though
<taylanub>for self-educational purposes mostly. hopefully I can now return to looking into how Guile does things and conclude it's OK or in need of improvement. (our raise-continuable *does* use call/cc, that's kind of why this whole topic started yesterday)
<mark_weaver>it does seem to me that we should fix Guile's implementations of 'guard' in SRFI-34 and R6RS to conform to the specs.
<mark_weaver>I also want to make SRFI-34/35/36 compatible with R6RS exceptions/conditions, and to be able to catch native guile exceptions in the same way that R6RS guard now does.
<taylanub>if you want I can work on that, I think I have an OK understanding of the situation now
<mark_weaver>well, it's tricky because of backward compatibility issues and ABI
<dsmith-w`>sneek: botsnack
<sneek>:)
***dsmith-w` is now known as dsmith-work
<taylanub>it seems partial continuations don't capture their dynamic environment? http://sprunge.us/BNNP
<taylanub>hm, that makes sense I guess. could maybe implement a `with-captured-dynenv' instead that limits the extent of the captured dynenv and thus can be implemented with partial continuations
<mark_weaver>taylanub: hmm, interesting
<mark_weaver>sneek: later tell wingo: does this look right to you? I'd expect it to return 1. http://sprunge.us/BNNP (example code by taylanub)
<sneek>Got it.
<taylanub>oh, I have to test this on 2.0.11, this is actually bipt's wip branch! I figure ey might have touched the handling of dynamic environments for Elisp
<taylanub>ok, same result
<mark_weaver>taylanub: can you file a bug?
<taylanub>ok
<mark_weaver>(please include the code inline rather than via the link)
<mark_weaver>thanks!
<mark_weaver>sneek: later tell wingo: here's the bug report: http://bugs.gnu.org/18356
<sneek>Got it.
<taylanub>Mailed another pair of examples, one of which works with partial continuations.
<Gillecomgain>taylanub, I must admit, I am at a loss how to implement guard.
<Gillecomgain>Or wait
<Gillecomgain>No, I'm an idiot.
<Gillecomgain>My implementation already works.
<DeeEff>If I want to build guile on windows (natively, no cygwin) what are the biggest things to watch out for?
<DeeEff>I know Eli was doing some work to make this better, but I'm wondering how bad it really is now that some work to transition the code over has been done
<taylanub>bipt: ping! sneek has messages for you :)
<taylanub>sneek: later tell bipt Elisp prints Scheme's null as "()", which however is read back in as nil. Probably it should print as something different to avoid this; possibly something that we will also make the reader understand. False is printed as "#f" which will just make the reader error.
<sneek>Will do.
***mario-go` is now known as mario-goulart
***Gillecomgain is now known as DavidXanatos
***DavidXanatos is now known as DXanatos
*taylanub wonders if Scheme macros could be used in Elisp. It should probably be possible.