IRC channel logs

2014-08-28.log

back to list of logs

***nalaginrut_ is now known as nalaginrut
<nalaginrut>morning guilers~
<Jaffa_kree>nalaginrut, I have slept.
<Jaffa_kree>I feel rejuvenated.
<nalaginrut>congrats
<Jaffa_kree>Thu Aug 28 04:32:47 CEST 2014
<Jaffa_kree>Also
<Jaffa_kree>My timezone is clearly better than yours.
***Jaffa_kree is now known as Gillecomgain
***rlb` is now known as rlb
<nalaginrut>sneek: later tell wingo Could please you take a look at my patch of built-in server? ;-)
<sneek>Okay.
<civodul>Hello Guilers!
<nalaginrut>civodul: hi ludo! could you take look at my patch of built-in server? ;-)
<civodul>nalaginrut: the sendfile thing?
<nalaginrut>yes
<civodul>i was planning to look at the issue in more detail but haven't done yet
<civodul>i'll try to do it in the next couple of days
<nalaginrut>thanks! But I think it's better to ask if there's given way to call sendfile in current built-in server implementation
<nalaginrut>My conclusion is no, but I think it's better to ask
<nalaginrut>civodul: anyway, please do it when you're free ;-)
<civodul>sure!
<civodul>i agree it'd be nice to be able to use sendfile for these things
<civodul>that's the typical use case
<nalaginrut>yes, I'd like to use sendfile in Artanis, but I have to keep built-in server interface too, so there'd be a way to combine them
<civodul>ok
<nalaginrut>thanks in advanced
<Gillecomgain>wingo, ah, you are here.
<Gillecomgain>Do you know what the rationale is for r6's non continuable exceptions.
<ijp>people are accustomed to non-continuable exceptions
<wingo>it's not exceptions that are continuable or not -- it's the continuation
<sneek>wingo, you have 1 message.
<sneek>wingo, nalaginrut says: Could please you take a look at my patch of built-in server? ;-)
<wingo>i.e. whether the site uses raise or raise-continuable
<wleslie>thanks for the excellent blog posts, Andy
<wleslie>and for the new compiler too.
<wingo>thanks for the kind words :)
<Gillecomgain>wingo, well, I mean why does raise exist and isn't raise-continuable just called raise.
<Gillecomgain>Surely with raise-continuable you can also just jump out of the handler as guard does
<ijp>Gillecomgain: the r6rs design came from srfi 34, try that mailing list
<ijp>archive
<ijp>but IME even where they are continuable, most people don't bother
<Gillecomgain>ijp, hmm, 34 seems to only define 'raise' and seems to leave it opaque whether or not it's continuable.
<Gillecomgain>Well, at this point my concern is no longer practica, just interested in the motivation since raise-continuable seems to assume all use cases of raise.
<ijp>hmm, you are right, it must have been a later addition
<ijp>Gillecomgain: well, whether or not an exception is continuable, is determined by a field in the condition. so you can think of one as being sugar for the other which adds/removes that field
<Gillecomgain>Yes, which makes me even more curious to its motivations.
<Gillecomgain>Really? I thought the continuableness was simply determined by invoking the exception with raise or raise-continuable?
<Gillecomgain>Ohh, I see what you mean.
<Gillecomgain>I'm still very much curious to its rationale though.
*taylanub updated http://www.emacswiki.org/emacs/GuileEmacs to be more relevant to the current state of things
<civodul>taylanub: some new stuff in the "wip" branch, cool
<taylanub>civodul: yup, Elisp engine actually replaced now :) still some big quirks unfortunately
<civodul>have you run it?
<taylanub>yup. startup very slow since .el aren't compiled, errors when I try to load my .emacs, and is very slow and very memory hungry...
<taylanub>nevertheless, I can use Dired, rcirc, Info, etc. with it, open and edit files...
<taylanub>and (symbol-function 'foo) usually returns #<procedure ...> :)
<civodul>woow, sounds like quite an achievement already :-)
<Gillecomgain>wingo, so I take it you don't know the rational, or?
<wingo>dunno
<Gillecomgain>Aww man
<Gillecomgain>I am held bereft of the knowledge I desire most.
<ijp>welcome to humanity
<ijp>"why we are here" is to the left, "what is the universe made of" to the right, "is induction valid" is on the shelf behind you
<Gillecomgain>Yes well, that's not that interesting.
<taylanub>Gillecomgain: would it be satisfactory if I said it just makes sense to intuitively divide between exceptional situations where it does and doesn't make sense for the program to continue in some way?
<Gillecomgain>And not that relevant really, but the point is, they made a conscious choice to make a difference between raise and raise-continuable so there has got to be a reason why not simply every exception should be continuable.
<Gillecomgain>taylanub, hmm.
<Gillecomgain>taylanub, surely that is more part of the condition type being raised if anything?
<taylanub>Gillecomgain: yes, the code that raises it can determine whether it's one that can be said "go back and continue with this value"
<Gillecomgain>Yeah, so why isn't it in the condition isntead of the raising mechanism
<Gillecomgain>Would you say that (raise-continuable (make-assertion-violation ....)) is an error?
<taylanub>oh you mean why there's two procedures instead of us doing (raise (continuable-exception foo)) and (raise (uncontinuable-exception foo)) ?
<Gillecomgain>Yeah, the continuable part should be part of the severity level of the condition one assumes.
<ijp>well, that would not work
<Gillecomgain>Explain.
<ijp>because the condition maker would need to capture the continuation
<ijp>but you really need the continuation of the call to raise
<taylanub>ijp: the exception object could just be a description for `raise' which dispatches to the appropriate "real" raise?
<taylanub>but yeah, it's thus just a layer of indirection / fake decoupling
<Gillecomgain>ijp, why would the condition maker need to capture the continuation? In this case every raise is continuable so the continuation is always that of raise[-continuable]
<taylanub>anyway, assuming it's possible to implement either way, the reason it's done the way it is is just historical. considering the other is splitting hairs / bikeshedding
<ijp>the whole argument is stupid to begin with because no-one uses continuable exceptions
<taylanub>I can imagine it being handy being able to (define ..) your continuable/uncontinuable conditions beforehand, then just raising them agnostically to their nature, but you can trivially implement that with the current machinery
<ijp>raise is clearly the more primitive of the two
<Gillecomgain>Really.
<Gillecomgain>Isn't raise harder to implement than raise-continuable?
<Gillecomgain>raise-continuable is little more than just applying the current exception handler to its argument right?
<ijp>no, that's what raise is
<ijp>basically
<ijp>assuming the exception-handler is a continuation
<Gillecomgain>Well, say the current exception handler is (lambda (x) #t)
<Gillecomgain>(raise-continuable 'derp) ==> #t
<Gillecomgain>But raise in that case needs to raise a &non-continuable exception
<ijp>sure, if you redefine everything, you can make any argument
<taylanub>sure about that? doesn't the handler receive a continuation and needs to call it explicitly for the raising code to continue?
<ijp>when you raise, you also change the dynamic environment
<ijp>the most trivial reason being what if the exception handler raises an exception?
<Gillecomgain>taylanub, what do you mean with receive it?
<taylanub>really the only difference is raise-continuable passes on its captured continuation to the handler as an argument, whereas raise drops it on the floor. (the compiler can also see that and omit its allocation, so you get a little performance boost for using that instead of always using a continuable one and leaving it up to the handler to continue or not)
<Gillecomgain>THe continuation the handler is called with is the continuation of the call to raise itself.
<Gillecomgain>to raise-continuable*
<Gillecomgain>Right?
<taylanub>oh sorry, I forgot that the handler is normally called before unwinding
<Gillecomgain>Correct me if I'm wrong, but I always thought that raise-continuable was just something like (define (raise-continuable con) ((current-exception-handler) con)) basically
<Gillecomgain>Where current-exception-handler is the implicit paramater.
<taylanub>I need to read up on that myself, sorry if I caused confusion. I think you're right
<Gillecomgain>Aww man.
<Gillecomgain>I like to feel stupid.
<Gillecomgain>MAkes me feel safe.
<Gillecomgain>wingo, surely you know all this.
<taylanub>find balance :)
<taylanub>and stop pestering wingo :)
<Gillecomgain>THey told me your deeds are worthy of song and your intellect surpasses that of david Xanatos.
<ijp>think of handlers not as functions, but continuations
<Gillecomgain>Mark_weaver told me to do that, told me wingo knew all the answers I sought.
<taylanub>ijp: are you sure about that?
<ijp>taylanub: the actual implementation is irrelevant
<Gillecomgain>ijp, only in the case of raise because it can't handle handlers that return.
<Gillecomgain>as far as raise-continuable goes, it's a normal function
<ijp>Gillecomgain: what if you don't continue?
<ijp>that isn't always the sensible thing to do
<Gillecomgain>If the handler doesn't return, then raise and raise-continuable have identical behaviour.
<ijp>Gillecomgain: but in that case, it isn't a function
<ijp>QED
<Gillecomgain>Which is why I don't get the existence of raise, raise-continuable seems to assume all its uses and more.
<taylanub>ijp: if you mean delimited continuations, then yeah, they're interchangeable with procedures anyway, but the handler's return *normally* causes the code to simply continue, because no unwinding happens before calling it. raising is literally just calling a procedure; plus if it's uncontinuable then `raise' throws *again* (to the higher handler) because it wants to prevent execution from
<taylanub>continuing
<ijp>as such, the trivial model you have above fails
<Gillecomgain>Well, semantics, and if a function returns or not can also depend on its arguments.
<ijp>the difference between raise and raise-continuable is given in the name. one cannot continue, the other may continue
<taylanub>Gillecomgain: if you have questions on low-level things that are hard to figure out, feel free to ask the developers, but nobody here is your tutor :)
<Gillecomgain>I'm not sure what the difference is between escaping a function with a continuation, thereby never returning, or simply an infinite loop, thereby never returning.
<Gillecomgain>ijp, yes, in that sense raise-continuable is a superset of raise, right?
<ijp>but it's not the more primitive one
<Gillecomgain>Depends on if you define it in scheme directly in term of continuations as a macro or a different way I guess.
<ijp>but I've repeated myself half a dozen times in different ways already
<Gillecomgain>Truth be told, I'm not sure how to define raise in scheme itself, how to check if the handler returns and if it does then raise an exception
<Gillecomgain>How would one do that.
<Gillecomgain>Well, I guess simply in terms of a control hack
<taylanub>Gillecomgain: I think `raise' might be impossible to implement with `raise-continuable' because with the latter you have no way of throwing to the *higher* handler, which is what `raise' does. I might be wrong.
<taylanub>.oO( Why not just read the code? )
<Gillecomgain>(define (raise con) (begin ((current-exception-handler) con) (raise (make-non-continuable))) or something like that.
<taylanub>`make-foo' just makes an object. someone needs to call the higher handler; what you wrote will just loop with the current one
<Gillecomgain>taylanub, yeah, which I feel makes raise harder to implement than raise-continuable.
<Gillecomgain>THe re-raise mechanism of raise is particular.
<Gillecomgain>in particular*
<taylanub>yes, I agree. any worries left?
<ijp>try implementing it, you'll see why raise is easier to implement
<Gillecomgain>taylanub, in your agreeance, that makes me even more puzzled why raise exists if raise-continuable is easier to implement and assumes all the cases of raise.
<Gillecomgain>But I must admit that the better part of my brain fell asleep a while ago, the part that steers my fingers fights it in defiance.
<taylanub>because it doesn't assume all the cases; it doesn't prevent continued execution
<Gillecomgain>Well yeah, that's true I guess.
<Gillecomgain>Just seems weird that raise has the shorter name then
<Gillecomgain>rather than raise vs raise-noncontinuable.
<taylanub>the names are irrelevant to how simple the implementation is, obviously :) when throwing exceptions, stopping execution is the norm. continuable exceptions are the odd ones, *even* if simpler to implement.
<ijp>because they aren't simpler to implement...
<taylanub>ijp: I'm not 100% sure yet but I think raise-continuable is literally just (apply (current-exception-handler) key args).
<Gillecomgain>It seems that way to me.
<ijp>for a start, that doesn't fix the dynamic environment of the handler
<ijp>(as I already mentioned)
<ijp>which (again) means that if your exception handler reraises, you get a loop
<taylanub>at least `throw' does explicitly not fix it. I'm trying to figure out whether raise-continuable is also as simplistic
<taylanub>ijp: http://sprunge.us/gOfd
<ijp>then that's a bug, as I understand the spec
<ijp>taylanub: but ignoring parameters, it still applies for the example given
<Gillecomgain>As far as I understand the spec, the only difference in the dynamic environment is the implicit current-exception-handler.
<taylanub>hm, yeah, the `raise-continuable' spec clearly says that it needs to install the higher one as current while invoking the handler
<Gillecomgain>Which should be reset to the one it was when the handler was being installed, all other paramatres should remain the same as the environment of the call to raise-continuable.
<taylanub>in fact `raise' is just the same. it says the dynamic env is that of the `raise' call, with the special exception of the handler becoming the higher one
<taylanub>so my test doesn't tell us much, let me try another
<Gillecomgain>If you put (raise-continuable 'x) after (newline) it probably has some other behaviour.
<Gillecomgain>It doesn't re-invoke itself in any case
<ijp>it makes no sense for the exception handler to be in the dynamic environment of the throw
<taylanub>ijp: but it says that's what happens
<taylanub>oh wait, sorry!
<ijp>consider (call-with-output-file "foo" (lambda (out) ..... (close out) (raise "foo")))
<ijp>sorry with-output-to-file
<ijp>then your repl couldn't print out the error
*taylanub needs to chill down, read properly, and make some tests. BBL :P
<Gillecomgain>taylanub, by the way: https://github.com/fanchylee/ikarus_fanchy/blob/master/scheme/ikarus.exceptions.ss
<Gillecomgain>This is how Ikarus does it
<Gillecomgain>Which uses the control hack I spoke of, both definitions are fairly similar, only exception is that raise raise-raises.
<ijp>I'll need to fix with-exception-handler and guard
<taylanub>ijp: I can't figure out from R6RS's wording what the dyn env of the *handler* should be, when using raise(-continuable). it only mentions the dyn env of the *continuation* of the handler call
<ijp>the specification for guard is more clear
<ijp>you can infer my interpretation for with-exception-handler, but it is not as explicit
<Gillecomgain>r6 often has remarkably ambiguous language for a specification
<ijp>yes, and it's the best scheme has managed so far
<ijp>taylanub: e.g. "The handler is called with a continuation whose dynamic environment is that of the call to raise, except that the current exception handler is the one that was in place when the handler being called was installed." you could infer by "the exception proves the rule" that the handler does not have that dynamic environment
<ijp>real meaning of that term, not the common joke
<taylanub>yeah, so if the handler raises it *will* loop?
<ijp>you can also infer it from the fact that the exception handler is explicitly mentioned as part of the dynamic environment
<taylanub>ijp: when you said you need to patch them, did you mean to *make* them loop?
<ijp>no, to make that parameterize return 0
<taylanub>ah
<Gillecomgain>In any case, looking at the Ikarus code, the raise code is exactly the code of raise-continuable with the added check to re-raise when the handler returns.
<Gillecomgain>So I'm not sure how raise is more primitive than raise-continuable, it's just the latter with an extra check.
<taylanub>but the spec implies it *would* loop, no? let alone having the parameter be 1
<ijp>Gillecomgain: in guile, they are both implemented in terms of throw, but with raise-continuable getting a call/cc
<ijp>taylanub: no
<Gillecomgain>Hmm
<ijp>taylanub: as I said, guard is very clear about its dynamic environment
<taylanub>but guard != with-exception-handler
<Gillecomgain>I guess this depends on how expensive your continuations are. I believe that in Ikarus they're fairly cheap.
<Gillecomgain>I think, but am not sure that ikarus uses CPS
<ijp>taylanub: it makes no sense for them to differ here
<ijp>Gillecomgain: I doubt it, it probably uses the same trick chez does
<Gillecomgain>But in any case, the core of the function in both cases comes down to basically calling the current exception handler with the object.
<Gillecomgain>chez is the one that uses that trick of CPS in C right?
<Gillecomgain>Where it garbage collects the stack
<ijp>no
<Gillecomgain>Was that chicken then?
<ijp>yes
<taylanub>but see Guile's catch vs. with-throw-handler which are *explicitly* different in that a throw-handler call does not unwind and can thus loop if you throw to the same key from a handler for that key
<ijp>we have a bug about that
<taylanub>ugh
<taylanub>doesn't it make sense as the most low-level mechanism?
<ijp>I think it is responsible for the loop in the (sterror 1.5) bug
<taylanub>you have keys to prevent the looping
<ijp>taylanub: and while they are different constructs, I see no reason why they would differ here
<taylanub>ijp: it seems `with-throw-handler' does *not* lead to a loop.
<ijp>taylanub: sorry, in that last remark, I was still talking about guard and with-exception-handler
<taylanub>ok
<taylanub>well the looping seems to be prevented from the lowest layer which is with-throw-handler/throw, and the behavior carried over to with-exception-handler/raise
<Gillecomgain>ijp, what is the chez trick then?
<ijp> http://www.cs.indiana.edu/~dyb/pubs/stack-abstract.html
<Gillecomgain>Smalltalk has continuations?
<ijp>yes
<taylanub>so an *outer* handler can invoke an *inner* one by throwing a different key that matches the inner handler, but it cannot loop on itself. http://sprunge.us/Zbba (note the handler comes at the bottom here, as opposed to with-exception-handler where it comes first)
<taylanub>so, this behavior is pretty perfect actually
<taylanub>no expensive unwinding, but does just enough to prevent looping (presumably simply removes a handler itself from the handler set before calling it)
<taylanub>and this behavior carries over to with-exception-handler in the form of removing any handler being called from the handler stack (in R6RS there's no key so you always call the innermost handler anyway). perfect.
<taylanub>ijp: you say raise should always fully unwind (change the whole dyn env, not just the current handler)? do you think throw should as well?
<Gillecomgain>taylanub, isn't the point of both raises that the only thing in the dynamic environment it should change is the current exception handler?
<taylanub>Gillecomgain: seems so, though R6RS is ambiguous
<Gillecomgain>Well, it says that that is the only exception.
<taylanub>it says that for the *continuation* of the handler only
<Gillecomgain>Well, and that it should revert when it returns.
<taylanub>it doesn't say it for the dyn env of the handler itself, if I'm reading it right
<Gillecomgain> The handler is called with a continuation that is equivalent to the continuation of the call to raise-continuable, with these two exceptions: (1) the current exception handler is the one that was in place when the handler being called was installed
<Gillecomgain>How so?
<ijp>taylanub: it is only ambiguous for with-exception-handler
<ijp>it is very clear about guard
<taylanub>yes
<ijp>Gillecomgain: what you've quoted refers to the continuation of handler, not the handler itself
<ijp>which is why I said to apply "the exception proves the rule" to claim they were different
<Gillecomgain>The continuation of a function call is a superset of its dynamic environment as far as I know.
<Gillecomgain>call/cc also captures the dynamic environment anyway.
<ijp>certainly not a superset
<taylanub>aha, SRFI-34 is much more direct: "The handler is called in the dynamic environment of the call to raise, except that the current exception handler ..."
<taylanub>and R6RS refers to it saying it's based on that ...
<taylanub>but it remains a mystery why they'd change the wording to introduce that ambiguity
<Gillecomgain>Hmm
<Gillecomgain>For me, a continuation has a dynamic environment packaged with it.
<Gillecomgain>Which call/cc also captures anyway.
<taylanub>ugh, I think R6RS simply messed up its wording; it seems to confuse the continuation of the handler with its dynamic env
<Gillecomgain>Well, a dynamic environment is part of a continuation, if you restore a continuation the dynamic environment of the original call/cc call is restored as well.
<ijp>Gillecomgain: I think you are missing the point
<Gillecomgain>Probably, because I don't get it.
<ijp>the handler is not a continuation, so it wouldn't package its dynamic environment
<taylanub>supposedly the *continuation* of the handler invoked by raise-continuable does *not* have the same handler, which doesn't make sense because a second raise-continuable after a return from the handler *should* certainly call the same handler again, since it's a return to the same point in the program...
<Gillecomgain>It says aequivalent to the continuation of the call to raise-continuable, to me that implies that the dynamic environment of that call also follows.
<ijp>and the same applies to calling something that is not a continuation with a continuation
<taylanub>so I think we should just ignore R6RS's weird wording that talks about continuations, and assume it meant what is pretty obviously The Right Thing and specified by SRFI-34 and implemented by Guile already. (however, R6RS rightfully specifies the continuation of the `raise' handler, which should logically rethrow, which SRFI-34 leaves unspecified instead)
<taylanub>all in all, use Guile's behavior for reference :P
***karswell` is now known as karswell
<ijp> http://blog.regehr.org/archives/1180
<ijp>title "Proposal for a Friendly Dialect of C"
<taylanub>saw that the other day; didn't realize it's something new
<taylanub>I'm probably unaware of how great of a proposal it is because I wrote so little bare C in my life
<ijp>well the blog post is only a day old, so by definition it is new
<ijp>trying to make a better C is nothing new, except this time it's just C+change some undefined behaviours
<civodul>sounds exciting
<lloda>i like the one about allowing a pointer to point out of an array
<lloda>it happens naturally when running over a strided array
<lloda>the rule that you can only point inside or one past the end is a pain
<lloda>I mean, why one? it
<lloda>it's 100% ad hoc
<dsmith-work>lloda: It comes from post-incremneting
<lloda>I know. But it's an invalid position, so if you can point there, you can also point past 2 and no harm done.
<dsmith-work>No harm as long as the only thing you do is compare against the array bounds. Actually dereferncing the pointer is incorrect.
<lloda>That in any case.
<lloda>But just pointing beyond +1 is UB, which is my beef.
<dsmith-work>IS there any valid reason for having a pointer be more than one beyond? +1 yes. +N no I think.
<dsmith-work>I dunno.
<dsmith-work>Point yer pointerers whereever you want.
<lloda>strided arrays. You do something every N elements.
<dsmith-work>And enjoy.
<dsmith-work>Hmm. In that case, each stride is sort of a larger object. And incrementing +1 by that larger size does indeed make sense to me.
<lloda>it need not be a larger object. e.g., run over the diagonal of an NxN array. The stride is N+1.
<dsmith-work>ok
<daviid>heya guilers!
<dsmith-work>Hey hey
<Gillecomgain>taylanub, anyway, I think mark_weaver's original explanation probably holds that implementations who have more expensive continuations can choose to implement raise without resorting to call/cc whereas raise-continue requires it.
<taylanub>I do not think `raise-continuable' requires call/cc
<Gillecomgain>I mean escaping out of it for things like guard.
<Gillecomgain>At least, ijp said that in guile, raise is implemented more simply but raise-continuable required call/cc
<ijp>actually, there is barely any difference in the code
<Gillecomgain>Though, expanding guard in guile just exposes call/cc regardless.
<Gillecomgain>Ah, then you lied to me.
<Gillecomgain>I thoiught we had this bond of trust.
<taylanub>just look at guile-source/module/rnrs/records/procedural.scm, at the end of the file
<ijp>Gillecomgain: I did not
<taylanub>indeed, raise-continuable uses call/cc .. I don't get yet why
<ijp>taylanub: because throws always escape
<mark_weaver>hydra is responding again
***linas_ is now known as linas
<taylanub>ijp: you mean this is an implementation detail of Guile, because of the simple implementation of `raise-continuable'? if it had direct access to the throw handler stack it could work without unwinding, no?
<ijp>throw is not an rnrs construct, but a guile one
<taylanub>I just mean it's not inherent to raise-continuable that it would need to use call/cc, and it's just Guile's current implementation of it doing so, which could also avoid it...
<ijp>taylanub: call/cc needs to be involved in any useful exception mechanism, the only question is where
<taylanub>and I'd say in `raise' and `guard' but not in `with-exception-handler' and `raise-continuable' :)
<taylanub>unless I'm still missing something
<ijp>try implementing it
<ijp>you'll remember quickly enough then