Created
March 16, 2012 22:21
-
-
Save manuel/2053247 to your computer and use it in GitHub Desktop.
Integrating conditions and exceptions chat (german)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (10:56:17 PM) msimoni: also: ein lisp mit CS verwendet native exceptions ja für BLOCK/RETURN-FROM | |
| (10:56:30 PM) Chris Neukirchen: ok | |
| (10:56:48 PM) msimoni: ich habe (js-throw obj) === throw obj | |
| (10:57:22 PM) msimoni: und ($js-try handler body-expr) === try { eval(body-expr) } catch(e) { apply(handler, e) } | |
| (10:57:35 PM) msimoni: das sind die primitives in der VM | |
| (10:57:51 PM) msimoni: darauf baue ich BLOCK/RETURN-FROM so: | |
| (10:58:06 PM) msimoni: | |
| (def Block-Escape (make-class ())) | |
| (def make-block-escape (lambda () (make-instance Block-Escape))) | |
| (def block | |
| (vau (name . body) env | |
| (let ((tag (make-block-escape)) (val #void)) | |
| ($js-try (lambda (exc) (if (eq? tag exc) val (js-throw exc))) | |
| (apply (eval (list* lambda name body) env) | |
| (lambda (the-val) (set! val the-val) (js-throw tag))))))) | |
| (def return-from (lambda (exit val) (exit val))) | |
| (10:58:26 PM) msimoni: ist jetzt nicht so wichtig, du weisst eh wies geht :) | |
| (10:58:32 PM) Chris Neukirchen: ja | |
| (10:58:40 PM) Chris Neukirchen: und was ist der trick? | |
| (10:59:13 PM) msimoni: die einzige schwierigkeit ist dass jetzt bei einer unachtsamkeit in JS auch eine exception ausgelöst wird | |
| (10:59:34 PM) msimoni: die das ganze system durcheinanderbringt, weil condition handler ja eben nicht auf try/catch basiert | |
| (10:59:40 PM) Chris Neukirchen: jo | |
| (11:00:06 PM) msimoni: die vorige implementierung des CS war: | |
| (11:00:23 PM) msimoni: | |
| (define *handler-stack* none) | |
| (define-class Handler-Frame () | |
| (parent-option | |
| matcher | |
| handler) | |
| (:constructor make-handler-frame (parent-option matcher handler))) | |
| (define call-with-handler | |
| (lambda (matcher handler thunk) | |
| (let ((saved-stack *handler-stack*)) | |
| (set! *handler-stack* (option (make-handler-frame *handler-stack* | |
| matcher | |
| handler))) | |
| (unwind-protect (thunk) | |
| (set! *handler-stack* saved-stack))))) | |
| (define signal | |
| (lambda (condition) | |
| (define do-signal | |
| (lambda (frame-option) | |
| (if-option (frame frame-option) | |
| (if ((.matcher frame) condition) | |
| ((.handler frame) condition) | |
| (do-signal (.parent-option frame))) | |
| (default-handler condition)))) | |
| (do-signal *handler-stack*))) | |
| (11:00:48 PM) msimoni: wie zuletzt auf ll-next in JS gepostet: man hat einen stack, der in einer dynamischen variable die aktuellen handler haltet | |
| (11:01:03 PM) msimoni: ein handler hat matcher funktion, die schaut ob die condition zutrifft | |
| (11:01:23 PM) msimoni: und eine handler function die aufgerufen wird, wenn condition zutrifft | |
| (11:01:33 PM) msimoni: none, und option sind None/Some | |
| (11:02:39 PM) msimoni: der trick ist jetzt: man muss call-with-handler so erweitern, dass es während der ausführung des thunks nicht nur auf signals reagiert, sondern auch auf JS exceptions | |
| (11:03:04 PM) msimoni: und da die VM selber exceptions verwendet, muss man jetzt jene die von BLOCK/RETURN-FROM rethrowen, die anderen SIGNALEN: | |
| (11:03:10 PM) msimoni: | |
| (def call-with-handler | |
| (lambda (matcher handler thunk) | |
| (let ((saved-stack *handler-stack*)) | |
| (set! *handler-stack* (option (make-handler-frame *handler-stack* | |
| matcher | |
| handler))) | |
| (unwind-protect ($js-try (lambda (exc) | |
| (if (instance? exc Block-Escape) | |
| (js-throw exc) | |
| (signal exc))) | |
| (thunk)) | |
| (set! *handler-stack* saved-stack))))) | |
| (11:03:17 PM) msimoni: it's sick :) | |
| (11:03:50 PM) msimoni: also wenn eine exception daherkommt und sie ist gut - also eine die wir für BLOCK/RETURN verwenden, dann rethrowen wir sie | |
| (11:04:05 PM) msimoni: wenn sie eine "böse" exception ist, signallen wir sie, und betten sie so in das CS ein | |
| (11:04:14 PM) Chris Neukirchen: mhm, ok | |
| (11:04:24 PM) msimoni: nicht ganz fidel: bei einer condition wird ja nicht der stack abgebaut | |
| (11:04:35 PM) msimoni: aber bei einer exception kann man das einfach nicht verhindern | |
| (11:05:05 PM) Chris Neukirchen: wie ist unwind-protect definiert | |
| (11:05:05 PM) msimoni: es darf also niemals jemand eine instanz von Condition THROWen | |
| (11:05:17 PM) msimoni: das ist einfach finally, als built-in | |
| (11:05:35 PM) Chris Neukirchen: ok | |
| (11:05:35 PM) msimoni: | |
| /*** $unwind-protect ***/ | |
| /* Performs a cleanup expression whether or not a protected expression | |
| exits normally. Returns the result of the protected expression. | |
| ($unwind-protect protected cleanup) -> result */ | |
| var Lisp_Unwind_Protect = lisp_make_system_class(Lisp_Combiner, "Lisp_Unwind_Protect"); | |
| Lisp_Unwind_Protect.lisp_combine = function(cmb, otree, env) { | |
| var protect = lisp_elt(otree, 0); | |
| var cleanup = lisp_elt(otree, 1); | |
| try { | |
| return lisp_eval(protect, env); | |
| } finally { | |
| lisp_eval(cleanup, env); | |
| } | |
| }; | |
| (11:05:43 PM) Chris Neukirchen: aso, du hast ja keine continuations oder? | |
| (11:05:46 PM) msimoni: nein | |
| (11:05:47 PM) Chris Neukirchen: ok | |
| (11:05:51 PM) msimoni: pu, zum glück :) | |
| (11:06:58 PM) msimoni: naja, alles sehr esoterisch, aber sollte passen | |
| (11:08:02 PM) Chris Neukirchen: der handler kann jetzt weitermachen? | |
| (11:08:03 PM) msimoni: das wird jetzt die praxis zeigen :P | |
| (11:08:16 PM) msimoni: jetzt ist er mal in kontrolle | |
| (11:08:42 PM) msimoni: wenn die condition also keine instanz von Condition ist, weiss er ist was doofes passiert | |
| (11:08:50 PM) msimoni: aber nichts genaueres, weil JS exceptions ja strings sind | |
| (11:09:11 PM) msimoni: er kann jetzt also nur mehr von der stelle aus einen wert returnen | |
| (11:09:21 PM) Chris Neukirchen: jo | |
| (11:09:22 PM) msimoni: restarten natürlich nicht, der stack ist ja schon weg | |
| (11:10:03 PM) Chris Neukirchen: hrm | |
| (11:11:36 PM) msimoni: woah, kompliziert | |
| (11:11:49 PM) msimoni: also das ist jetzt die grenze meiner vorstellungskraft | |
| (11:12:01 PM) msimoni: drum bin ich eben froh, keine delim control eingebaut zu haben :) | |
| (11:12:54 PM) Chris Neukirchen: wenn man cps'en würde, könnte man das alles selbst regeln oder? | |
| (11:13:03 PM) Chris Neukirchen: also bis auf die vm-exceptions | |
| (11:13:29 PM) msimoni: LOL >:-> | |
| (11:13:34 PM) Chris Neukirchen: hm? | |
| (11:13:43 PM) msimoni: nein, also das ist völlig orthogonal dazu, afaics | |
| (11:13:49 PM) Chris Neukirchen: wieso? | |
| (11:14:02 PM) Chris Neukirchen: du passt zwei continuations, eine für "lief gut" und eine für "throw" | |
| (11:14:04 PM) msimoni: vllt missverständis was du mit selbst regeln meinst | |
| (11:14:23 PM) Chris Neukirchen: continuations komplett selbst definieren meine ich | |
| (11:14:26 PM) Chris Neukirchen: *exceptions | |
| (11:15:09 PM) msimoni: CPS überleg ich mir nie | |
| (11:15:26 PM) Chris Neukirchen: weiss ja nicht wie schnell js lambdas callt | |
| (11:15:36 PM) msimoni: aber ja, ohne CPS hättest du *eine* abbruchscontinuation | |
| (11:15:45 PM) msimoni: und halt die normale return continuation implizit | |
| (11:15:49 PM) Chris Neukirchen: ja | |
| (11:15:57 PM) Chris Neukirchen: aber in cps kannst du trivial resumen dann | |
| (11:16:02 PM) msimoni: also lambdas sind total egal afaict | |
| (11:16:23 PM) msimoni: das resumen ist immer trivial :) | |
| (11:16:50 PM) Chris Neukirchen: naja, nicht wenns schon zu spät ist | |
| (11:16:53 PM) msimoni: und wenn du das zb in C machst, und sagst der C code darf kein setjmp verwenden ists auch trivial | |
| (11:16:58 PM) Chris Neukirchen: jo | |
| (11:17:14 PM) msimoni: das einzige nichttriviale hier ist eben dass JS überall throwen kann | |
| (11:17:31 PM) msimoni: e.g. wenn du auf undefined.foo zugreifst | |
| (11:17:43 PM) msimoni: also man könnte jetzt sagen, das ist halt dann ein bug | |
| (11:17:48 PM) Chris Neukirchen: :) | |
| (11:18:22 PM) msimoni: und man könnte jeden js-call wrappen, so dass exceptions gecatcht werden, und als conditions gesignallt werden | |
| (11:18:28 PM) Chris Neukirchen: jo | |
| (11:18:30 PM) msimoni: vllt zusätzlich keine schlechte idee | |
| (11:18:30 PM) Chris Neukirchen: halt lahm | |
| (11:18:47 PM) msimoni: aber das grundproblem bleibt dass man eben einfach nicht alle fälle abdecken kann |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment