<libfud>sorry, just wanted to see if I could poke the bot <libfud>neat bot, that's another project on my todolist <rgrmrts>I'm working through SICP right now and in the first chapter there's a part about re-implementing `if` using `cond`, it goes on to ask what happens to our square root implementation using this new-if and using guile it never terminates. I'm trying to understand why. gist with code: https://gist.github.com/rgrmrts/af34bc6e778176feb87c2cdca59fac3d, any clues? <rgrmrts>I realize this isn't related to guile specifically, sorry if this is a wrong channel <ft>You can't implement if as a function in languages that evaluate eagerly, like Scheme. The function only gets applied after *all* its operands have been evaluated. <libfud>the interpreter treats it differently than procedures <libfud>what's the motivation behind comma commands in guile? <ft>In the recursive case, your new-if gets its predicate, consequence and alternative arguments, and scheme evaluates all of them. The alternative has the recursive call, so it never can terminate, even if the predicate returns #t. <libfud>e.g. why ,apropos foo instead of (apropos foo)? <rgrmrts>was just typing up: so if this weren't a recursive function, the "new-if" would have probably been fine <ft>(apropos foo) would be subject to the namespace that's currently active. (I guess - I have no insight into the design decision) <rgrmrts>makes sense! I haven't quite processed _why_ the recursive call doesn't terminate but I can think on that. <libfud>it actually does matter regardless of it it's recursive or not <libfud>for example (if predicate (set! foo (+ foo 1))) <ft>Yeah, mutation can be a problem. I/O can. Lots of things can. <libfud>nothing recursive about that, but you only want to evaluate it on the predicate being true <ft>Also, vasted CPU cycles. :) <libfud>I think the purpose of the exercise is to introduce the idea of special forms behaving differently, and why it's desirable for them to behave as much <rgrmrts>word, I was curious about why special forms exist in some cases <libfud>to translate it in terms of assembly instructions, conditionals are branching instructions that operate on the program counter, "skipping" over instructions <ft>In the case of ‘if’, its purpose is to break the usual evaluation rules. :) <libfud>define and set! are also special forms <dsmith>libfud: The comma commands at the repl are convenient magic syntax because normally commas are only used in quasi-quote. <libfud>dsmith: so just a feature of convenience to save some keystrokes? <libfud>*me is not complaining, just curious <ft>If you're in a module that implements a function or macro called ‘apropos’, (apropos foo) won't work anymore. ",apropos foo" always can, because its a meta-command, independant of the currently active module. <dsmith>Not so much saving keystrokes. More like (ab)using invalid syntax to provide repl-specific commands. <ft>And dsmith is probably right about why the comma was chosen. <libfud>ft: so even if in the global environment I bind apropos to something else, it will still work? <libfud>or am I mistaken in calling the environment that you start out the REPL in the global environment? <ft>libfud: ,apropos probably calls out to the global definition, so that probably won't work. <ft>Yeah, (set! apropos identity) breaks it. <ft>I wonder if a local definition would shadow this. Hum. <libfud>it's fun to break things and play in the mud :) <ft>I tried. It calls out the the global one. <ft>And only if you override that one using set! things break, understandably. <ft>So it's more than just convenience. <libfud>hmmmm... since i'm going over SICP myself, could you implement if as a function with force and delay? <ft>If you force your users to obey that, yeah. <ft>That's why you can implement if as a function in lazy languages like Haskell. <libfud>ah, right, because you can't delay the input expressions in the body <libfud>is literally everything in haskell lazily evaluated? <ft>There are ways to force eager evaluation for selected expressions. <ft>But the default is lazy evaluation. <libfud>since I don't see this in SICP and it just says "cons-stream is a special form defined so that (cons-stream <a> <b>) is equivalent to (cons <a> (delay <b>))" <libfud>is the following a good way to express that? <libfud>(define-syntax cons-stream (syntax-rules () ((cons-stream a b) (cons a (delay b))))) <rekado>libfud: I don’t know if there’s anything else to it, but you can also use define-syntax-rules here <RhodiumToad>define-syntax-rule is a very useful shorthand for simple macros <rekado>(define-syntax-rule (cons-stream a b) (cons a (delay b))) <rekado>libfud: Guile has srfi-41 for streams, though, so you could use that instead :) ***daviid is now known as Guest14267
<leoprikler>Just a heads up, I think make-variable-transformer is not working correctly in the case of (set! (alias arg ...) value) <emys>how can I invoke guile for executing a compiled .go file directy (instead of refering to the source file?) <libfud>or is that the extension of compiled guile code? <justin_smith>libfud: it stands for "guile object" and predates the google funded programming language <ArneBab>libfud: my guess about the comma-commands is that a comma is always illegal in toplevel-scope, so it can be used to start arbitrary parsing without breaking anything in the very moldable scheme. <libfud>justin_smith: yeah I figured that out after looking at the documentation <emys>another question: can I somehow get the 'type' of an object / variable? <rekado>emys: guile -c '(load-compiled "foo.scm.go")' <rekado>emys: if you’re using GOOPS you can do <rekado>but that’s perhaps a little heavy <justin_smith>I've often wished the logic of "class-of" existed outside goops <emys>rekado, that will do for me, its just for debugging purposes <dsmith-work>emys: Outside of goops, you need explicitly check for the type. <emys>emys, full story is I did two mistakes, the first one led to the wrong behaviour, the second meant that (write x) debugging did show a different variable, so I didn't realize I was actually using the list/pair instead of the list-element in my code <emys>class-of gave me the info that I was dealing with a pair, then I realized I was writing out the wrong value and I was able to see what I did wrong <emys>dsmith-work, thats what I was using class-of for :-) and in this case goops was fine ***jonsger1 is now known as jonsger