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)))
<flatwhatson>take and drop aren't defined in guile's prelude
<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>ah, let-values is syntax, not a procedure
<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 ...)?
<Zelphir>*body of 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
<Zelphir>This eval https://www.gnu.org/software/guile/manual/html_node/Eval-When.html ?
<flatwhatson>that works, if you use (eval-when (expand) (import ...))
<Zelphir>Will try that, thanks!
<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>Ah that does not make sense, nvm.
<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 :)
<flatwhatson>you can test what does work in the repl.
<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?
<flatwhatson>so finding a guile-specific solution isn't useful
<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.
<flatwhatson>fwiw that let-wrapped import works in chez
<flatwhatson>i don't know enough to say what's correct behavior
<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
<Zelphir>oh aha!
<Zelphir>So many details to stumble over ^^'
<flatwhatson>hmm. so, if you did (define a 1), you would expect that to be available in a following source block?
<flatwhatson>because let-wrapping that, it won't.
<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>it should be one or the other
<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?
<flatwhatson>the answers will be found in the org implementation
<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.
<cow_2001>on failure of the attribute
<cow_2001>i have 6.11.8 Exceptions open in info.
<cow_2001>cosmic woman
<cow_2001>err oops
<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 ;)
<jlicht>s/that/since
<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.
<abcdw>your*
<wingo>meep
<civodul>oh! https://spritely.institute/news/robin-templeton-joins.html
<civodul>exciting news!!
<civodul>congrats, robin :-)
<civodul>wingo: i hear there's already exciting stuff in the wasm backend?
<robin>thanks civodul!
<civodul>pretty amazing team
<drakonis>nice!
<drakonis>"If given the opportunity and interest, they will bless an interested listener with a treasure trove of obscure Lisp history."
<drakonis>hmmm
<drakonis>i'll take this
<drakonis>this is a dream team in the making