<calher>davexunit: I can't scp the generated site/ directory to a server and have it work, because the links it generates are not relative -- it assumes that the files are at /. <ijp>I'm pretty pleased with this bignum library I'm hacking <zv>i just got my mind blown by (let ((a 1)) (define (f x) (define b (+ a x)) (define a 5) (+ a b)) (f 10)) <zv>i've been programming for years and i would have never guessed... <ijp>that should be an error <zv>in racket its an error <ijp>I think it's an optimiser bug <zv>i mean, 16, 20 and "error" are all valid in some way -- wouldn't you say? <ijp>because I know how letrec* is defined <zv>"couldn't find source for letrec*" :( <ijp>it's handled in the macroexpander <ijp>anyway, the outer let is a red herring for this one <zv>shouldn't that bind the definition of let? <ijp>rename the outer a to c and you get the same result <ijp>I guess this falls in the category of wrong bug harmless <zv>whats going on there? <ijp>zv: if it didn't, you wouldn't be able to have recursive inner defines <zv>inner defines meaning... letrec? <ijp>I say harmless because if you replace the value of a with (launch-the-missiles 5) you get the right answer <zv>i mean, i dont really see <zv>but thats interesting at least <zv>compiling guile to see if i can get emacs to source the letrec* definition in guile so i can see what you are talking about <ijp>that isn't going to help you very much <ijp>geiser won't find the definition because it's part of the expander <ijp>and the expander isn't very clear to begin with <zv>so what is a at the top of the body of "f" <zv>is it "undefined"? is it "null" <ijp>wait, sorry, wrong 'a' <zv>although that sounded cool <zv>"wrong, it is *IRRELEVANT*" <ijp>it is undefined, although strictlyf speaking guile should probably error when it is accessed <zv>anyway, i see what you mean, changing the varname of `a' to anything else preserves the structure of the code <zv>clearly the "define" is being moved to the beginning of the stack frame <zv>rather, the value is. <ijp>probably during the "fixing letrec" pass <ijp>ACTION whistles innocently <lloda>meep seems to be one of the big Guile users, but we don't see them around too much. I got into Guile through libctl and one day I just had to remove the whole thing. Ah those evil define-macros... ***cluck` is now known as cluck
***cluck`` is now known as cluck
<zv>is there any way to have a function run at the end of compilation/interpretation without actually having a function at the end of the file? <mark_weaver>zv: it doesn't matter where the procedure definition is, but if you want to run it at the end, then you need to *call* that procedure at the end of the module. <zv>maybe you could answer one more question <zv>why does this print 20? (let ((a 1)) (define (f x) (define b (+ a x)) (define a 5) (+ a b)) (f 10)) <zv>ijp tried to answer it but he just said there was some macroing going on <zv>i tried to look into it and it's above my pay grade to be honest <mark_weaver>at the expression (+ a x), the 'a' that is in scope there is the inner 'a', which is defined to be 5. <mark_weaver>the outer 'a' is not actually referenced from anywhere in that case. <zv>by a has not yet been defined? <mark_weaver>well, they are two different variables, despite having the same name. <mark_weaver>now, technically you have violated a restriction of letrec there, by referencing 'a' before it is initialized. <zv>but then isn't the (+ a b) referencing an a that doesn't exist? <mark_weaver>the inner binding of 'a' that it references does exist, but according to the semantics of letrec*, it has not yet been initialized. <mark_weaver>now, our optimizer clearly did some rearranging there, to perform the initialization of 'a' before the initialization of 'b'. <mark_weaver>it would have been better to detect and raise an error here, but that's not required. <mark_weaver>if you want to reference the outer 'a', then you should use 'let' instead of inner defines. <mark_weaver>because a block containing internal 'defines' is equivalent to a 'letrec*', where all the inner definitions are in scope in all of the right-hand-side initializers. <mark_weaver>however, you are not allowed to forward reference variables in those right-hand-side initializers. <mark_weaver>what you *are* allowed to do is to forward reference variables from within *procedures* that are not called immediately, and that's the typical use: to define a set of mutually recursive procedures. <mark_weaver>e.g. (let ((a 1)) (define (f x) (define (b) (+ a x)) <mark_weaver>actually, it turns out that our optimizer simply evaluates that entire piece of code into a constant, 20. <mark_weaver>as shown by: ,optimize (let ((a 1)) (define (f x) (define b (+ a x)) (define a 5) (+ a b)) (f 10)) <zv>are there any tools that show the steps and logic of the optimizer? <mark_weaver>well, the REPL has commands for viewing the output of macro expansion (,expand) and partial evaluation (,optimize) <mark_weaver>but we don't have anything that shows the individual steps and explains them. <mark_weaver>but most of the optimizers are in module/language/tree-il/*.scm <mark_weaver>and wingolog.org has quite a few blog posts about aspects of guile's compiler and optimizers. <mark_weaver>in the master branch (2.1+) much of the newer optimizations are in module/language/cps/*.scm