IRC channel logs
2023-03-09.log
back to list of logs
<Zelphir>Hi! Is (import ...) inside the body of (let ...) valid Guile? I seem to have hit a situation, in which imports in the body of the (let ...) do not work for the rest of the body of that (let ...). Not sure this is by design or a bug. Code example: http://0x0.st/Hiqq.scm Apparently, this is what Emacs org source blocks with :var variables are transformed into, according to people on the emacs-orgmode mailing list. <flatwhatson>Zelphir: it works, try the following in guile repl: (let ((ls '(1 2 3 4))) (import (srfi :1)) (values (take ls 2) (drop ls 2))) <Zelphir>How come, that the code I linked does not work? Is srfi-11 different? That code gives errors for me, when I run it. let-values not bound, subsequently `a` not bound and `b` not bound. (Guile 3.0.9) Calling it via `guile example.scm` or pasting it in the REPL. Both give errors. <flatwhatson>so it needs to be visible when the body of the let is expanded <Zelphir>Oh. I did not think of that difference. <flatwhatson>Zelphir: a fix would be to have org use (define x 1) (define y 2) instead of using let <Zelphir>Yes, that is what I am suggesting on the mailing list, but not sure there are any downsides. I mean, I guess one could claim, that :var variables should only be for the block that they are put on, but one could also claim the opposite, that every including source block should see them. <Zelphir>I will mention that about the let-values being a macro too. Thanks for that explanation. <Zelphir>But actually I have one question regarding that: <Zelphir>Why does it need to be available already, when the (let ...) block is expanded? Why is it not only needed to be available, when the (let-values ...) block is hit inside the (let ...)? <flatwhatson>because expressions are expanded and then executed, they're not expanded during execution <Zelphir>Ah and the import is in execution time, if inside the (let ...) body, right? <flatwhatson>i think import is syntax, but it expands to execution-time loads? <flatwhatson>but moving everything to the top-level is the solution here IMO <flatwhatson>either that or wrapping your source block in an eval <flatwhatson>that works, if you use (eval-when (expand) (import ...)) <flatwhatson>you mentioned about leaking :var between source blocks, but that import will leak because it modifies the current module <Zelphir>Hm yes. Will leak anyway and is even desired, I think. <flatwhatson>actually that eval-when doesn't work sorry, i didn't reset the repl when trying it <Zelphir>I want to try it on the (let-values ...) as well: ... (import ...) (eval-when (expand eval) (let-values ...)) <Zelphir>But for the import, should it not be: (eval-when (expand eval) (import ...)) ? <flatwhatson>i'm not sure what "should" work, except moving it to the top-level :) <Zelphir>Will include what I test in the e-mail to the orgmode mailing list. <flatwhatson>i've tested a few different eval-when variations, and can't find one that works <flatwhatson>but that will be guile-specific anyway. presumably that let-wrapping strategy is standard for scheme blocks? <Zelphir>A bit weird is still, that in org mode evaluation of source blocks, I do not get the error that let-values is undefined. I get an error, that the first binding of the matched multiple values is undefined. In the code example I linked, if I put that in a source block, I get an error about `a` not being defined. Nothing about `let-values` not being defined. -- Hm yes, maybe other Schemes do things differently. But not wrapping with (let ...) and using <Zelphir>(define ...) should work fine for all maybe. <Zelphir>Hm ok, good to know! Already 1 example for different behavior : ) <flatwhatson>it would certainly be nice if this "just worked" in guile, the fact that it doesn't is surprising <Zelphir>Just when I thought everything works perfectly in org mode, I hit this :D -- but at least I can fix it manually by moving imports to a source block that does not have any :var header arguments. <flatwhatson>oh hang on, it works in chez because chez has let-values ootb <flatwhatson>hmm. so, if you did (define a 1), you would expect that to be available in a following source block? <flatwhatson>i think that's a solid case for *not* let-wrapping. you expect your source block to be evaluated at the "top level", and let-wrapping breaks that <Zelphir>Personally, yes, I would. But not sure everyone would agree with me there. My previous mental model was, that when I include another block, it gets "pasted" where I reference it via the <<name>> syntax of org noweb. <Zelphir>Previously I did not use :var much, so I never hit that let-wrapping case before. <flatwhatson>but then if you don't use :var, it's not let-wrapped, so (define a 1) will leak <flatwhatson>and let-wrapping has other negative consequences on expansion as you've found <Zelphir>I recently discovered how I can use org-sbe to take values from a table and put them into source blocks to have calculations there and then put the result (output) back into the table. So that is why I am experimenting with it. And then this rabbithole :D <Zelphir>Yes, :var should probably not be "deciding" whether something leaks. <Zelphir>Maybe an additional header argument should be introduced, that decides whether to let-wrap or not. <Zelphir>Or not wrap at all, if no problems for other Schemes arise from that. <flatwhatson>the (define x '1) approach i suggested is completely portable <flatwhatson>and being able to define in one source block and use in another is generally desirable imo <Zelphir>I would guess so too. Seems so basic. Not sure why they bothered with let-wrapping. Lets see what people on the mailing list might write. I might need to make a bug report/issue on some repo or so. <flatwhatson>it might be worth comparing with how :var works in other more widely-used languages <flatwhatson>eg. how do python blocks work in org? i expect they "leak" too <Zelphir>Many do not have a let, so could not let-wrap at all. Say Python for example. <flatwhatson>right. probably let-wrapping was introduced without too much thought on consequences <Zelphir>Some might have "blocks". I think JS has? Simply {} around some code part? <Zelphir>*sigh* now I face the behavior of Python source blocks not outputting anything again and hints I find online don't work in making it show the outputs. I know I had this before at some point ... <Zelphir>Oh no -- I think I am finding more bugs now. ^^' <Zelphir>It seems that using any source block with :var header args via :noweb does not work, as it then behaves in the way, that it merely pasted the included source block, without first putting in the :var values into the variables and then I get errors about those :var variables being undefined. Of course, evaluating the block directly, that has the :var header args works, because then org sees the :var variables ... <Zelphir>Sent the e-mail to the org-mode mailing list. I hope I summarized the points well and will see what others think. : ) Thanks again for clearing things up! Need to leave now, good night/day! <cow_2001>hmmmmmmm... optparse-long's predicate attribute raises an exception which i have to catch. <mwette>you can try srfi-37 for arg parsing; that's used more often for guile now <jlicht>thanks again for haunt, and guile! It's been a while that I've been breaking things in joy instead of frustration ;) <abcdw>jlicht: tell us more about what you up to with huant! <mirai>how do I run a particular guile test under test-suite/tests/ ? <jlicht>abcdw: wiring up something with emacs, ox-haunt and haunt. My hacks make it creak and break, but I'm still having fun at least <abcdw>jlicht: If possible share you findings/experience with it, please, after you finish :) I also looking towards haunt. Thought about implementing guile-org on top of tree-sitter to use haunt with org. <civodul>wingo: i hear there's already exciting stuff in the wasm backend? <drakonis>"If given the opportunity and interest, they will bless an interested listener with a treasure trove of obscure Lisp history."