freenode/#sicl - IRC Chatlog
Search
4:21:09
alandipert
i have started to reconsider implementing restarts in JACL, that their utility might outweigh their runtime heft. and that necessary compiler wizardry isn't as bad as i feared, based on a conversation i had with andy keep awhile ago
4:24:13
alandipert
anyone have insight on compilation techniques/runtime bits involved? when i originally decided to punt on them, and on debugger other than JS, i thought a VM and continuation primitives were required, and i didn't want to go the VM route because my VM and its bytecodes would defeat existing JS optimizers
4:26:05
alandipert
but if i understand the way chez scheme does continuations, an alternate way is to compile to CPS, and then "fuse" intermediate continuations, leaving continuation calls only exactly where they're needed on a subsequent pass
4:28:58
beach
alandipert: Restarts are not particularly hard by themselves, but I guess you want to know how to express them in JavaScript. Since I don't know JavaScript, I don't think I have any useful advice.
4:29:52
alandipert
beach for design purposes i think JS is just "an applicative language with first-class functions and single-use continuations"
4:31:18
alandipert
afaict my implementation options are 1) my own interpreter so i can manipulate the stack on my own terms, or 2) compile to CPS
4:31:28
beach
So I think the entire condition system can be implemented portably, using special variables and non-local control transfers.
4:33:03
alandipert
thanks for that. i think it illuminates what my actual problem is, which is that JS is single-threaded. so if i've stopped the program to open a debugger, the debugger can't respond to input because those events can't be dispatched on until the stack is empty
4:35:02
beach
There are (or were) single-threaded Common Lisp implementations. So I guess now you are talking about a problem with the development process itself, rather than a design issue?
4:37:22
alandipert
i suppose it's not even the single-threaded nature, it's the JS event model - JS programs that are blocked on a loop have no way to respond to events from the browser, such as user input events. those events go to previously-established handler functions, as opposed to registers or something else that could be polled inside the blocking loop
4:39:59
alandipert
yeah i'd prefer not to. but i'm not aware of another way to pause and resume execution in a JS program, without my own interpreter
4:40:09
beach
alandipert: That's an additional profound property of the language in addition to the ones you mentioned. I have no idea of the consequences of that property on restarts.
4:41:46
Bike
well, it sounds like you're worried about the interactive debugger rather than restarts per se? like, if you have dynamic variables and oneshot escapes, restart-case and all should be fine
4:43:00
Bike
i believe most implementations implement conditions in more or less pure lisp, on top of block/return-from and dynamic variable binding.
4:43:55
beach
Interesting. I wonder whether the reason for that is that the condition system was added late? Or wasn't it?
4:45:13
alandipert
i have block/return-from and dynvars, so the magic piece of restarts is definitely the debugger
4:46:12
Colleen
Clhs: function invoke-debugger http://www.lispworks.com/documentation/HyperSpec/Body/f_invoke.htm
4:47:15
alandipert
i don't have a way to get a backtrace without throwing an exception, which unwinds the stack
4:47:56
Bike
you could just have the program stop and print a backtrace whenever the debugger would be invoked.
4:48:32
Bike
but i'm not sure i'd restructure my entire compilation system just to get a debugger...
4:50:20
Bike
i mean it just seems... unrelated. it's like saying you need to write your own FPU to support FORMAT
4:50:40
alandipert
maybe it would help us all if i outlined a more general version of the problem that motivated all this
4:52:33
beach
alandipert: Maybe so. But I think it is near bedtime for Bike, and he is more likely to understand the issues than I am.
4:53:50
alandipert
no problem, sleep is good, i could stand to think about this more on my own anyway
4:56:29
beach
Now that I understand. I think in the past I worked out how to express block/return-from and tagbody/go in terms of catch/throw, and vice versa.
4:57:03
Bike
i mean, lexical escapes in terms of try/catch is pretty much what clasp is doing anyway
4:58:09
alandipert
i think my problem boils down to my inability to return control to where the signal happened, because javascript
4:59:59
Bike
maybe i didn't make it clear - in the usual implementation of the condition system, calling a handler function does not transfer control
5:00:20
alandipert
the problem is that if the JS stack is non-empty (blocked on call to debugger function) the debugger is incapable of receiving user input
5:01:14
beach
It would call the debugger function and the debugger function would read from the user.
5:01:39
beach
That's what would block it, and so user input is what it is waiting for in order to unblock.
5:01:58
Bike
http://home.pipeline.com/~hbaker1/MetaCircular.html ok yeah this does have block/return-from in terms of catch/throw. it even works in a similar way.
5:03:23
alandipert
that's definitely the essence of the problem though, so i'm grateful to you for putting a spotlight on it
5:03:47
alandipert
Bike yeah, it might be possible to do something with developer APIs or extensions or something
5:04:44
Bike
distributed applications with lispworks or sbcl or something are likely to just die with a backtrace
5:04:54
alandipert
that was my thinking until like yesterday when i realized, no, a debugger is a user thing to. to the extent that in the ideal lisp environment you have everything all the time
5:05:16
alandipert
like, i thought it coudl make sense to pop a debugger UI in a user-facing app, and for the options to be meaningful to the user
5:07:55
Bike
https://www.stacktracejs.com/ quick google says you can get a backtrace without transferring control
5:09:41
alandipert
oops, sorry, yeah i was wrong about that. you can throw and then immediately catch in an anonymous function, and inspect the exception object
5:10:30
alandipert
the experience i had writing UI code that motivated the rethink was using pretty-print to scaffold UI elements on an app i worked on many years ago in clojurescript
5:11:29
alandipert
i had a system like tilton's cells, but in cljs. and i would wire my UI output elements to cell values. the cells contained datums, and the UI element logic was transforming the datum to a fragment of HTML
5:12:35
alandipert
a coworker had the good sense to wire everything up first, but use placeholders that were just pretty print instead of nice-looking HTML. anyway we shipped it and realized a bunch of the elements weren't finished, but looked good enough and went un-noticed
5:13:40
alandipert
so i was reading about restarts and i thought hmm, i wonder if a debugger with restarts is the "input" side of that kind of helpful half-assing
5:14:21
alandipert
e.g. i have a means to provide logic to the program to get me to the part i'm more interested in developing at the moment. and i can get rid of the restart later, or never, or whatever
5:15:47
alandipert
man, i should actually sleep myself, but thank you all again so much for your feedback. more helpful than you know. it makes me feel really good not to be completely alone in this effort
5:32:15
alandipert
holy cow. i just remembered there is exactly *one* ancient/obscure way to obtain input synchronously, and it's perfect for a debugger dialog. no compilation model rethinking necessary https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt
6:23:09
beach
For some reason, I started thinking about register allocation. Probably in order to distract me from stuff that absolutely needs to be done, like finishing the papers before the deadline.
6:23:39
beach
Is it possible that existing techniques for register allocation don't take function calls and callee-saves registers into account?
6:29:35
beach
Also, most x86 instructions have an additional restriction that the result register and the first operand register are the same. I have not seen that restriction taken into account either.
6:31:58
beach
And, at a program point where there are not enough registers to hold all lexical variables, which variable is assigned to a register may depend on how soon it is likely to be used again, and whether a register needs to be saved because it has been modified.
6:33:49
beach
I have really looked into only one technique, namely graph coloring, and it takes into account none of these aspects. Nor does it allow for the register assignment to change at some program point. A variable is either permanently assigned to a register, or never assigned to a register.
6:36:07
beach
So it seems to me that external function calls should be looked at first. A variable that is live across such a call should preferably be assigned to callee-saves registers, if it is to be assigned to a register at all.
6:37:15
beach
Then, the assignment of variables to caller-saves registers can be totally different after a function call compared to the assignment before the call.
6:38:04
beach
... simply because all the caller-saves registers must be saved before the call anyway, if it has been modified. And no such register has any known contents after the call.
6:39:55
beach
I wonder whether all these restrictions might make some greedy approach feasible. Or some traditional search algorithm like alpha-beta with a very good heuristic.
6:41:30
beach
If an inner loop is likely to execute several times, the cost of arranging the registers before the loop and re-arranging them after the loop is going to be negligible.
6:45:26
alandipert
i suspect tracing JITs take calls and modifications into account when they (re) allocate registers. at least i vaguely recal reading about something like this in either the HP Dynamo or one of the Truffle papers
6:52:10
alandipert
ie training a model on allocating registers in reference programs and the learning function is the execution profile. or this in concert with various other heuristics as you mention
6:56:30
alandipert
plus you're making SICL, which exactly the kind of thing that would make it easy for interested people to try
7:15:02
beach
That's my secret hope, that once I get something working, more people will be contributing.
7:15:44
beach
And that's why I want the code to be as implementation-independent and as maintainable as possible.
7:32:38
alandipert
battery about to die. i might not be able to sleep, but i definitely won't be back for awhile. so goodnight for real o/