<mark_weaver>amk9: I see from the code that it's okay to return a string instead of a bytevector as the body. if you return a string, it will be converted to a bytevector automatically. <mark_weaver>ijp: it looks to me like 'sanitize-response' handles the case where 'body' is a procedure that's called with a port. <mark_weaver>oh, I understand now. it doesn't take a *port*. nvm :) <ijp>i was imagining a case where you returned a port, and it copy-port'ed it <ijp>we have copy-port right? <mark_weaver>we have 'sendfile', which essentially does the same thing. <ijp>yes, I was just looking at that <ijp>that count argument seems a pain <mark_weaver>and actually, the port passed to the procedure by sanitize-response is a string port, so that won't work. <ijp>that restriction bit me once before with the process procedures <ijp>I think I made a pipe, so that I could use a string port <amk9>so there is another command to get the mimetype which is mimetype <amk9>but one gets the css files mime type wrong and the other the html mimetype wrong (: <amk9>I will go with the hash mal I think <amk9>anyway I made *tremendous* progress thx <amk9>btw the web inspector in firefox nightly is verygood <ijp>I think it was 15 or so it arrived, wasn't it? <ijp>unless they've been fiddling with it again while I haven't been paying attention <amk9>now there is more than just html inspection <amk9>also they fixed the stylesheet bar <amk9>anyway at last I got it working without fiddling with commandline tools, <amk9>not providing ContentType let the browser guess it <nalaginrut>mark_weaver: is it meaningful to add more pipes for a process-VM? <nalaginrut>my understanding is process-VM(like our guile-VM) simulates a physical-CPU, so I think it will simulate pipes(fetch/decode/execute), no? <mark_weaver>I've never heard of that being done in software. the issues are different in software. <mark_weaver>in hardware, things can be parallelized very naturally without things like thread synchronization overheads. <nalaginrut>do we use the same/similar data flow analysis algorithm with Appel's book? or we choose a different way <mark_weaver>(in a radically different computer architecture, like say a cellular automaton, it would make sense to have pipelines in a VM, but not in our current mostly-sequential architectures, where parallelism is awkward at best) <nalaginrut>I'm finding a way to catch up the new rtl, or I can't read the code in few weeks <mark_weaver>well, our partial evaluator is largely based on "Fast and Effective Procedure Inlining" by Waddell and Dybvig *nalaginrut is searching... <mark_weaver>but we have a number of algorithms based on different papers. <mark_weaver>wingo is a better person to ask, since he wrote most of the compiler. <nalaginrut>alas~I'm afraid he will throw a bunch of papers to flood me... *nalaginrut is reading the paper... ***chaos_ is now known as Chaos`Eternal
<nalaginrut>I've read about CSE, and I wonder if there's no need to write elegant code for me, any rubbish code could be optimized to be cool one... ;-P <mark_weaver>closures are now working in the rtl compiler. I can now compile quite a bit of non-trivial code. <mark_weaver>on line 331 of slot-allocation.scm, you call (lookup-call-proc-slot k allocation), and I'm not sure what that's supposed to be doing, but k is not in the symbol table (and I wouldn't expect it to be). <wingo>mark_weaver: it should be "label" i think <mark_weaver>exp-k seems to be right, though I confess I'm guessing. <wingo>the idea is that since each continuation has just one body expression (at most), the name of the continuation is a label for the body in some way <mark_weaver>but if you avoid sequences, you can do quite a bit already. loops recursions work fine. <wingo>which is what we need to add body-specific (or continuation-specific) data to the allocation <mark_weaver>(though not very well optimized, I guess because contification isn't done yet) <mark_weaver>basically, I ran into a problem when 'define' or 'set!' was used in tail position. <mark_weaver>in the VM they return 0 values. the arity fixer didn't touch them, because they were in tail position. <mark_weaver>and then the final cps->rtl compiler failed because it assumed that the only things it would find in tail position were returns or tail calls. <mark_weaver>this seemed the simplest way to fix it, but I'm not 100% it's the right thing. <mark_weaver>anyway, I think we need to keep 'set!' returning an unspecified value, for compatibility. (even though I wish it weren't so :) <wingo>yes i don't know where the right place to put that it -- could be it's not there, dunno -- but that is the right fix <mark_weaver>also, in that same patch, see where I added cases to 'emit-seq'. I wonder if that default rule for primcalls, just below the cases I added, is right. it emits something called "primcall/seq", which iirc isn't implemented by the assembler (yet?). what was your thinking there? <mark_weaver>also, that default case doesn't use (slot ...).. it just passes along the bare arguments. is that a sensible default case for primcalls that return no values? <mark_weaver>(we needn't talk about this now; sorry to bombard you with questions as soon as you arrive :) <mark_weaver>man, I gotta fix (ice-9 match) so that when there's a failed match, the error reporting is actually useful. <mark_weaver>(like telling me the source location of the relevant 'match' would be good :) <wingo>mark_weaver: so my idea with emit-seq / emit-val etc for primcalls was to actually special-case all the primcalls that have corresponding ops <wingo>that way we can call the emit-cons procedures from (system vm assembler) directly and get compile-time feedback that the arity is right <wingo>and emit code directly instead of collecting into lists and then writing it out <wingo>it's ok to add "general" cases now while we're working with lists <wingo>but in the end they won't be needed *wingo can start with guile shortly; currently debugging a spidermonkey thing <wingo>each primcall should only be seen in one context, so we'll have at most 100 or 200 clauses like that <wingo>seems fair enough to me; dunno <mark_weaver>new trick: wrap all calls to 'error' within two sets of parens, not just one. for the backtrace. <mark_weaver>omg, one well-placed application of that ((error)) trick in (ice-9 match) has just made my debugging life *so* much better. <wingo>that error should also print the value that failed to match <mark_weaver>wingo: how you would feel about me going on a massive global-find replace of all occurrences of 'error' in guile core? <wingo>what other options are there? <wingo>obviously error in non-tail position would not need this treatment <mark_weaver>well, there's a MIT-scheme trick of keeping the backtrace as a chain of rings. <mark_weaver>well, something to think about. in the meantime, I'm going to apply these debugging improvements for (ice-9 match) to stable-2.0. <wingo>my instinct is that we should think on it a bit more -- e.g. r6rs provides some form to signal an error while explicitly not being in tail position <wingo>i have hated that match behavior for a long time <mark_weaver>it seems like 90% of the time I've spent debugging this new compiler has been tracking down which match is failing. <mark_weaver>of course, you need to manually trigger recompiles of everything that uses match. <mark_weaver>I wonder if it would be more useful to have an "add immediate" instruction, rather than add1 and sub1. <wingo>mark_weaver: yes i was thinking exactly that <wingo>taking a signed 8-bit value as an arg <wingo>the only reason i didn't do it already was because i was too lazy to think through any overflow implications <wingo>but yes, add-immediate sounds good to me <wingo>you get to play around with vm-engine.c :-) <mark_weaver>mainly because I'd like to add a bunch of math VM instructions. <mark_weaver>also, in several the generic arithmetic instructions, I want to steal one bit away from one of the arguments, to act as a "fixnum only" flag. <mark_weaver>the bit will only be observed if the fast (fixnum) path fails. <mark_weaver>that's what will allow me to add only ~50 new instructions rather than ~100 :) <wingo>what do you want to do about flonum-only ops? <mark_weaver>but actually, they'll probably just 'goto' the middle of the generic ops. <mark_weaver>or something like that. I'm mindful of minimizing the size of the VM. <wingo>the only concern i have with that is that we haven't implemented the parts of the compiler that deal with register widths <wingo>currently we have 8-bit registers, 12-bit registers, and 24-bit registers <mark_weaver>to my mind, these wide register indices are just crazy for anything other than move instructions. <wingo>and i was thinking of reserving the last three registers in each class for use as temporaries, if an op needs its arguments shuffled in and out <wingo>think of them as stack slots, more than registers... <wingo>though they are directly addressible stack slots <wingo>anyway it's quite possible for a program to have more than 128 live values at any moment <mark_weaver>and register machines have to do loads and stores every once in a while. a halfway decent register allocator can do a very good job with 128 registers. <wingo>esp. if we start to do stack allocation <wingo>i suppose you're right, but writing a good register allocator is hard <mark_weaver>*nod*, but even a crappy register allocator should do fine with 128 registers. <wingo>i suppose it's necessary to a degree, but still... <wingo>when we do native compilation register allocation won't look like this <wingo>you really want to avoid shuffling values in stack slots <wingo>so the register allocation problem is "what do we allocate in registers", and not "how do we fit live values into the lowest 128 stack slots" <mark_weaver>well, you've already got a problem then, because 256 isn't infinity either. <wingo>right, that's why there are 2**24 registers max <wingo>ops that have 8-bit args will need to shuffle <wingo>hence reservation of temporaries... <wingo>not ideal but not restricted either <mark_weaver>well, I don't know what else to say. I really think we need fast fixnum and flonum ops. and the only ways I see of doing that are by filling up our opcode space with fixnum/flonum ops, or stealing one bit. <mark_weaver>I suppose another option would be to switch from 3 ops to 2 for the math operations. <mark_weaver>but I still think going down to 7-bits worst case isn't so bad. <wingo>i think 7-bits is fine fwiw -- we just reserve registers 125, 126, and 127 as temporaries <wingo>and if the input or output regs are outside of the bounds you shuffle as needed <wingo>it's not ideal but it does work <wingo>my concern wasn't the 7-bit space per se <wingo>it was adding another size of register <wingo>i guess what i mean to say is that if we have more than 125 live values, things should still run <wingo>they will be slower but that is better than failing to compile <mark_weaver>oh, I definitely agree. the silly limits of the current VM is a peeve of mine, I confess :) <wingo>native compilation will make this easier as well :) <ArneBab__>I just found that guile supports standard docstrings, too! *happy* (define (a b) "doc")(object-documentation a) <ArneBab__>(define (a b) "doc")(object-documentation a) <ArneBab__>well, rather (define (a b) "doc" b)(object-documentation a) ← must not be the last item in the function. <wingo>ArneBab_: tx for the note; that page is years out of date unfortunately ;) <mark_weaver>(and maybe that 'cont' variable should be renamed to something less confusing. <wingo>a $cont is just a src + name + $kargs/$kif/... <wingo>so if you put it in a hash table as a name -> $kargs/$kif/... then you have all of the info <mark_weaver>it doesn't matter to me which of these things is changed. which would you prefer? <wingo>probably the later use is incorrect <wingo>i would change the definition of lookup-bound-syms <wingo>when a call happens, there is some set of live slots <wingo>the call gets allocated above those live slots <wingo>with three slots reserved for the call frame (saved fp, RA, MVRA) <wingo>and then there is the slot for the procedure: the proc slot <wingo>following that there are slots for the arguments <wingo>lookup-call-proc-slot returns the slot that corresponds to the procedure for a given call <wingo>you could think of it as local0 i guess <mark_weaver>from within the called procedure, it is accessed as slot 0 <mark_weaver>so another way of thinking about it is that the proc slot is the adjustment of the frame pointer made during the call? <wingo>at some point we should change the frame pointer to actually point at the procedure and not the next slot, but that comes after we remove the old vm <wingo>an implementation detail i guess, we wouldn't have to change the compiler <mark_weaver>do you mean that fp should point at the next slot, and not at the procedure? <wingo>i mean that right now it points at the next slot <wingo>and that it should point at the procedure <wingo>it points to the next slot because that's the way the old vm does it <mark_weaver>so the register indices are not the same as the offset from fp? <wingo>and you want the same backtrace code to work on both... <wingo>mark_weaver: currently no, they are offset by one <wingo>use LOCAL_REF and LOCAL_SET in instruction implementations <nalaginrut>constant folding was done in partial-evaluation, right? It seems there's no explicit named "data-flow-analysis" process in Guile2 <nalaginrut>and peval is done between tree-il to glil/cps, right? <mark_weaver>peval itself outputs tree-il, but that's done before conversion to the next layer down (glil or cps) <mark_weaver>nalaginrut: see module/language/tree-il/optimize.scm <mark_weaver>nalaginrut: also, I assume you know about the ",optimize" REPL command? <Chaos`Eternal>one question, in future, i mean when rtl/cps landed, will there be some simple way to serialize a continuation? <mark_weaver>Chaos`Eternal: sorry, that's probably further off, if ever. <nalaginrut>well, I think it's harder than rtl-VM ;-P but if we have it, we may exchange context between distributed machine which sounds like dreaming... <nalaginrut>mark_weaver: I guess it calls tree-il/optimize.scm <mark_weaver>Chaos`Eternal: continuations and procedures can encapsulate mutable state. so start with this: how do you serialize a mutable variable? <nalaginrut>sorry for the trash questions, but we don't have docs to show the big picture of Guile's current compiler-tower <mark_weaver>the only way to really do it properly is to put the variable on a globally-accessible server, and then serialize it as a URL. <mark_weaver>and then all future accesses will be done on that server. <mark_weaver>nalaginrut: well, there's the "guile implementation" chapter of the manual. but it's pretty basic. <mark_weaver>well, it's not bad, but there's certainly a lot more that could be written. <nalaginrut>it's too complicated when it's related to computation-architecture, and we just want to add a feature to compiler ;-P <nalaginrut>mark_weaver: I know, and I read that chapter several times, even for front-end developing I learn it by myself <nalaginrut>you know it's too simple to feed a hungry man ;-D <Chaos`Eternal>mark_weaver, i am not very familiar with this, but i know, there are efforts to serialize a linux process to disk and then restore them <mark_weaver>in general, when something is serialized, you must assume that it could then be copied <mark_weaver>I'm sorry, I don't have the cycles to explain this right now. maybe later. <mark_weaver>I'm a fool to have stayed awake all night (it's 6am here) and it's because I'm tempted by how close the RTL compiler is to being somewhat usable. <nalaginrut>well, don't think core-dump or similar things is the same with continuation, if you wish to have a whole Guile process dump as a serializable continuation, I think it's easy ;-) <wingo>mark_weaver: i was wondering whether you were coming at it from night or morning ;) <wingo>you already know it, but besides being a great help for guile, i really appreciate it too <wingo>time to sleep though, i imagine ;) <mark_weaver>I'm glad to help, I've been meaning to get more involved with the compiler for a while now :) <mark_weaver>but yeah, I was hoping to successfully run my implementation of strongly-connected-components on RTL before I slept, but maybe it won't happen tonight. <mark_weaver>I think these problems with 'seqs' are really all that remains. <wingo>mark_weaver: do you have a short test case? <wingo>currently refactoring some primitive-related stuff <wingo>prompts are going to be a mess, but that's another story ;) <mark_weaver>let me push the fixes I've already made before you start on it. <nalaginrut>mark_weaver: you should have rest now I think ;-) <mark_weaver>wingo: failing test case: (begin (newline) (newline)) <mark_weaver>sneek: later tell wingo I pushed my fixes to wip-cps-bis. failing test case: (begin (newline) (newline)). Don't forget to force-recompile things in language/cps for the improved 'match' error reporting. Happy hacking! <taylanub>Anyone ever heard of the "HnxGC" garbage collector ? Makes some big claims about fast, precise, deterministic GC (sounds way too good to be real). <add^_>taylanub: not me, couldn't really find anything fast on DDG <taylanub>Indeed, Googling reveals very little. :\\ Mainly "iGC", their for-iOS GC based on it, and some Chinese page, and some research PDF which I'll now look into but I think it isn't very relevant. <taylanub>They make some ridiculous claims for their iGC, so it drew my attention. *add^_ sadly can't read Chinise <taylanub>Well apparently it all comes down to restricting what kind of C you write. <amk9>talking about the browser, is Guile written in C or can it generate an interpreter written in C ? <wingo>that is a complicated question :) mostly guile is implemented in guile, but some parts are in C, like the VM <sneek>Welcome back wingo, you have 1 message. <sneek>wingo, mark_weaver says: I pushed my fixes to wip-cps-bis. failing test case: (begin (newline) (newline)). Don't forget to force-recompile things in language/cps for the improved 'match' error reporting. Happy hacking! <add^_>wingo: do you have some idea why (library ...) indents everything so much in emacs scheme-mode? I mean, it'd be enough with just 2 indents or something, but this is like alined with the argument after "library"... <add^_>I don't mean to disturb your work, maybe I should ask jao or someone else about that.. <wingo>(put 'library 'scheme-indent-function 1) <taylanub>add^_: Because it doesn't know that it's a macro .. <amk9>the idea behind Guile-C is to be able to compile it using emscripten, I probably look more into it later ;) <amk9>nalaginrut: hey, how do you plan to use a template engine in artanis ? <davexunit>amk9: scheme comes with templating via quasiquote :) <amk9>I have an issue regarding those, I use the simple quote ' to quote things like to create a symbol foo with 'foo, but then my program started to fail telling me that foo didn't exists, I had to use the english quote ` as in `foo <amk9>what is the problem here ? <amk9>there is difference between ' and ` ? <davexunit>yes, ' is quote. quasiquote allows you to use the unqoute operator , <amk9>yes I get that, but why my program started to fail ? is there something about using quote inside macros ? <davexunit>perhaps. I'm not totally sure what situation you got yourself into. <amk9>for instance I cannot quote the object quasiquote with quote procedure <amk9>I use a quasiquote to quote quasiquote... <amk9>anyway this might be a bit confusing, and my explanation are not helpful <amk9>templating via quasiquote seems nice, but I don't know how to actually achieve it <taylanub>amk9: Can you paste the exact code that gave the error ? Generally youd DON'T use symbols in macro-output though, you use "syntax objects". <amk9>espacially with external files <taylanub>In other Lisps, variables really are tied to symbols at run-time, in Scheme it's a bit more complicated .. <taylanub>(let ((foo <whatever>)) 'foo) -> The symbol `foo' that is returned from this piece of code has absolutely nothing to do with the variable `foo'. <taylanub>(Except that they just happen to have the same name, of course.) <amk9>as you can see in the first paste every symbol is defined as `name-of-symbol <amk9>I'll remove guile-reader and try again to see if it's not guile-reader that messing things <amk9>the program is somekind of s-expr template interpreter <amk9>don't mind this, it's related to guile-reader, I'll try to talk to civodul about that if it's still makes sens <taylanub>(define (file->sexpr file) (define reader (make-skribe-reader)) (reader (open-input-file file))) doesn't this throw a syntax error ? <amk9>with guile-reader and skribillo installed <amk9>I yes, I shouldn't use defined inside define ? <taylanub>Haven't written Scheme in a couple weeks and this is what happens ? ;_; <taylanub>amk9: As far as I see, any use of ` in your code can be replaced with ' (and should, for good style) <amk9>it I tried, it doesn't work <amk9>sorry my writring is horrible <taylanub>No problem. What error does it give ? "Doesn't work" is unclear. <amk9> ?: 0 [memoize-variable-access! #<memoized id> #<directory (sfx) 25a5480>] <amk9>ERROR: In procedure memoize-variable-access!: <amk9>ERROR: Unbound variable: id <taylanub>Sure that you used a normal ASCII apostrophe ? <taylanub>Can you paste the exact code that causes the error ? <amk9>I'm trying to reproduce it in a simple case <taylanub>BTW does any Scheme standard allow (cond (test-expression-only) (...)) ? I see in Guile it returns the test expression if not #f, as if one did (cond (test-expression => identity)), but the docs seem to be unclear on whether this is explicitly allowed, and I don't think it's standard .. just a nit-pick. <taylanub>s/if not #f/if not false/ (gotta remember #nil :)) <taylanub>amk9: Aaaaah, I see you re-define `quote' in your code! That will affect the behavior of ' <taylanub>The 'foo and `foo and ,foo in Scheme code are just braindead converted into (quote foo), (quasiquote foo), and (unquote foo) <taylanub>They're "unhygienic", one says in Scheme terms. <taylanub>No problem. First time I witness a clear damage resulting from the lack of "hygiene" :P <didi>Unhygienic makes a strong immune system. <amk9>my first program in scheme :') <taylanub>amk9: Random nitpicks: It would be best to change the name of consumer-set! to consumer-add! or so. More importantly, I think the usage of `procedure-name' and later (string->symbol (string-append "consumer-" ...)) is a bad practice, because it *implicitly* mandates all consumers to be called consumer-foo and will otherwise break in weird ways. Implicit limitations are very nasty for other users of the code, including possibly <taylanub>(Relocating my physical body, be back in an hour.) <amk9>I will consider that but I don't want to put too much time in this until I get a clear vision of what templating in scheme is or can be or should be <amk9>also there is skribillo which is powerful but diffirent from the templating systems I know of <nalaginrut_>evening! well, so evening that I have to sleep at once <mark_weaver>wingo: so, I found part of the bug with sequences in the RTL compiler. <mark_weaver>wingo: I see that in slot-allocation.scm, you use the same hash table to store both call-allocations and parallel-moves. <mark_weaver>wingo: well, there's a case where a parallel-move is put into the hash table, overwriting the call-allocation that was there. <mark_weaver>and then something looks for the call-allocation but it's gone. <wingo>call allocations happen in non-tail context, and parallel moves shouldn't get assigned then <mark_weaver>and fails because it finds a parallel-move when it's looking for a call allocatoin. <wingo>can you hold back from pushing for the next hour or so? i'd like to land a big patch <mark_weaver>well, that patch applies to 8240e5fd13b3288ff40c67f9b4f0f396678e18ec is the better way to say it :) <taylanub>amk9: I don't know much about templating systems in general, but do you know how quasiquoting works ? <mark_weaver>amk9: yeah, I really think you ought to at least learn the basics of using quasiquote combined with SXML before you write something new. <amk9>basically yes I know quasiquoting, let me try to explain it: evaluate the following as a list, each time you find a comma evaluate what follows <mark_weaver>which it not to say that you might not have a better idea, but it's often better to build on the last great idea than in ignorance of it. <mark_weaver>amk9: for starters, try this. type ",use (sxml simple)" at the REPL, and then: (define (make-test-page title strings) (sxml->xml `(html (head (title ,title)) (body ,@(map (lambda (str) `(p ,str)) strings))))) <mark_weaver>it also avoids all the usual "quoting" issues.. the idea is that you work with your XML or HTML using this hierarchical list data structure.. and then as a last step you serialize it to XML. <mark_weaver>while it's in the list data structure, you can conveniently build with quasiquote, pattern match with things like our (ice-9 match) module, and arbitrary strings can be used throughout. the quoting will happen in the SXML->XML conversion. <mark_weaver>well, it's not "our" match module.. but we include it in guile 2 anyway. <davexunit>take *that* every other templating system ever. *davexunit goes back to editing erb templates... <mark_weaver>and that's the one that's overwriting the needed call-allocation node. <wingo>so in the case of a trunc node to 0 values, there should be no parallel moves <wingo>that would be one quick fix to do <mark_weaver>(which is the one that wasn't stored because the trunc was to 0 values) <mark_weaver>ugh, I wonder if it might make more sense to store these in different tables, or something. <wingo>one is that $fun now has a list of $kentry <wingo>instead of $kentry chaining to alternates <mark_weaver>sounds good, I've long thought that would be better :) <wingo>and thus $kentry doesn't have an alternate field <wingo>the other thing is that i rewrote compile-cps.scm <wingo>to use some "builder" macros <wingo>it seems more readable and writable but we'll see <wingo>eventually we should consolidate a bit more <wingo>i will continue in that direction if i have any more energy today <mark_weaver>(one nice thing about the list of cases strategy is that empty case lambdas are representable without a special case) <mark_weaver>okay, I have to go afk for a bit. a little later I'll work on splitting the allocation table into two tables and continue to work to get sequences working. ***tolk``` is now known as tolk
<taylanub>davexunit: By the way what did you end up using for your cross-thread queue that needs to be dequeued efficiently ? <taylanub>My crack-pot idea of a lockless queue was fundamentally flawed so good that you didn't use that. :P (Apparently the basic flaw, as it was explianed to me, is that architectures nowadays don't make any guarantees about the atomicity of writing words NOR about the precise order in which the writes in a thread happen as observable by reads from another thread. One must use *some* synchronization primitives to get any sensible guarantees <davexunit>taylanub: there's no protection on the queue at all. I just used a global mutex that the REPL locks before eval'ing. <davexunit>the game loop currently unlocks the mutex before it sleeps between frames. <davexunit>but since mutex locking/unlocking has some overload, I want to do something different. <davexunit>like have a "repl-waiting" flag, and only when that flag is true will the game loop unlock the mutex. <davexunit>since 99.9% of game ticks will never need to unlock the mutex. <davexunit>the solution I'm working towards is to have the compiled thunks that the REPL generates scheduled for execution from the main thread. <davexunit>that's a less trivial problem, especially when you consider exception handling. <davexunit>there are a lot of things that can't be reasonably done from the REPL thread, like OpenGL calls. <davexunit>so getting the thunks into the main thread will complicate the REPL, but leave everything else (but the game loop) as it was. *wingo has factored the build-cps things into (language cps), will rebase and push shortly <mark_weaver>there are still some lingering issues that prevent my goal of running my strongly connected components code. <mark_weaver>wingo: is there a reason why the same constant, used in only one place, would cause two redundant 'load-constant' instructions to be emitted? <wingo>mark_weaver: is it shared somehow with other structure? <mark_weaver>in particular, compiling (display (set! foo 1)) causes the (void) from the 'set!' to be emitted twice. once with the destination register as #f (which I just fixed the handling of) <mark_weaver>of course, since one of them has a destination register of #f, it doesn't get emitted in the end (after my bug fix), but still I wonder why the emitter is even thinking about emitting it twice. <wingo>ok, pushed my little refactorings <wingo>at some point i would like to switch the order of the "k" and "src" fields in $cont <wingo>well, not tonight for me anyway, feel free to do what you like :) <mark_weaver>I think your refactoring efforts are very useful, and I'm glad you're doing it, but I'm most anxious to get some non-trivial code running :) <wingo>i just couldn't stand to write any more make-$foo calls ;) *wingo -> z; happy hacking :) <shanecelis>Hey guilers, Anyone know of anyone that uses macros to do one-time code refactoring? Basically, source-to-source macros? Just curious. <mark_weaver>well, the problem is that it will expand more than you want. <mark_weaver>e.g. things like 'case' and 'cond' statements will also be expanded. <mark_weaver>and there's really no way to avoid that. macro expanders have to work from the outside in. <shanecelis>It would also throw out all comments and formatting, right? <mark_weaver>there's no way to expand macros within code that hasn't yet been expanded.. at least not properly. <shanecelis>Bummer. It seems like it'd be a nice tool to have. <mark_weaver>basically, the macro expander has to expand the outer-most macros first, and keep doing that until it finds primitives that it understands. then it recurses into those primitives, taking note of the compile lexical environment as it goes deeper in. <mark_weaver>it can only recurse properly if it understands the constructs that it's traversing into. <mark_weaver>so there's no way to say "only expand this set of macros". <mark_weaver>shanecelis: there has been some work on transformation of source code from one scheme implementation to another, as a strategy for portability. <mark_weaver>I never looked carefully at it though. hmm, let's see if I can find a link. <mark_weaver>hmm, my web searches aren't succeeding. I don't know if anything much came out of the work, but I remember seeing an announcement of a little talk about this system a few years ago here in boston. <shanecelis>mark_weaver: Oh, I see. It seemed so tantalizingly feasible; now it seems pretty remote. <mark_weaver>if you can find a way to search there sanely, maybe you can find it. <mark_weaver>the author of that blog might remember the relevant talk. <mark_weaver>shanecelis: did you see the exchange between me and stamourv on #scheme? Yes, it was Dorai Sitaram who did the work.