Zelphir Kaltstahl <zelphirkaltst...@posteo.de> writes: > I am not sure (let ...) is a correct wrapper for noweb included source > blocks. > What, if I write a (define ...) in my source block and want to use that > source > block via noweb in another source block? Expected behavior I think would be > to > be able to access those variables in other source blocks, since they are > defined > on a top level in an earlier source block, but if they are wrapped in a (let > ...), that would make them only available in the (let ...)? It seems to me, > that > the simple wrapping with a (let ...) might not be the right thing to do. > Testing > that: > > ~~~~START~~~~ > #+name: scheme-defs > #+begin_src scheme :eval query-export :noweb strip-export :session myguile > :results output replace drawer :var x=1 :var y=2 > (define a x) > (define b y) > #+end_src > > #+name: scheme-time > #+begin_src scheme :eval query-export :noweb strip-export :session myguile > :results output replace drawer > <<scheme-defs>> > (simple-format #t "~a ~a\n" a b) > #+end_src > ~~~~~END~~~~~ > > Indeed, that also does not work.
I just checked ob-C, ob-shell, ob-emacs-lisp, and ob-clojure. Non-lisps appear to assign the values globally. In contrast, all the lisp babel backends are using let-bindings. Considering the existing inconsistency, and the raised bug I'd be in favor of making variable assignments global in all the lisp babel backends. The only possible exception is ob-emacs-lisp. Executing elisp code is done in current Elisp session and thus using global variable assignments may be tricky. Unless we juggle with multiple obarrays. > I guess I did never hit this problem earlier, because I "oursourced" my > imports > and in imports I do not need any :var header arguments. > > I've asked on the Guile IRC channel and something interesting is the case > here > (thanks for clearing it up flatwhatson!) and I understand it as follows: > > Imports inside (let ...) work. It is just that let-values is a macro and > macros > are expanded before execution time. However, Guile gets to the body of the > wrapping (let ...) at execution time. That means, that when Guile gets to > evaluate the body of the let, it does not expand the let-values, because it > is > already at execution time and no longer at macro expansion time. The import > might import the let-values form, or might not, but it is already too late to > expand the (let-values ...). So, apparently using `let' is not universally safe in Guile. > OK, the question is though, whether org should wrap anything in a (let ...) > at > all. During discussion on the Guile IRC, some points against let-wrapping > were > brought up: > > (1) The presence of a :var header argument currently determines, whether the > code in the source block is wrapped with a (let ...). One argument for that > was, > that this way the variables do not leak. But this also decides, whether other > things leak. For example (import ...) or (define ...). Should :var decide, > whether bindings created with (define ...) are visible in other source blocks > including the source block with the :var header arguments? It seems like a > responsibility :var should not have and definitely is unexpected for the user. This is something Guile-specific. In Elisp, let-binding still allows `defun' or `defvar'. -- Ihor Radchenko // yantar92, Org mode contributor, Learn more about Org mode at <https://orgmode.org/>. Support Org development at <https://liberapay.com/org-mode>, or support my work at <https://liberapay.com/yantar92>