emacs-orgmode@gnu.org archives
 help / color / mirror / code / Atom feed
From: Zelphir Kaltstahl <zelphirkaltstahl@posteo.de>
To: Ihor Radchenko <yantar92@posteo.net>
Cc: Bruno Barbier <brubar.cs@gmail.com>,
	emacs-orgmode@gnu.org, Bastien <bzg@gnu.org>
Subject: Re: [BUG] Inconsistent global/local :var assignments in ob-* for lisps and non-lisps (was: org-babel guile source block bug in handling multiple values)
Date: Fri, 10 Mar 2023 10:39:45 +0000	[thread overview]
Message-ID: <21ea836d-8bdf-2d0d-8515-283209f2eb1f@posteo.de> (raw)
In-Reply-To: <87v8jaoz3u.fsf@localhost>

On 3/9/23 14:04, Ihor Radchenko wrote:
> Zelphir Kaltstahl <zelphirkaltstahl@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.
Is it safe in any Scheme? I think that depends on expansion and evaluation 
phases of the Scheme standards (see below).
>> 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'.

The issue is not with defining via (define ...) inside a (let ...) in Guile. It 
is about importing macros at the time, when the body of the (let ...) is already 
evaluated, which is at a later phase than macro expansion. By wrapping inside a 
(let ...) org has moved the import to a later phase, which causes the macro 
(let-values ...) to not be expanded.

As far as I know, (defun ...) and (defvar ...) are merely defining functions and 
variables, not macros.

My point is, that imports are usually global for sessions. But :var decided for 
let-wrapping, moving them to a different place. Just like imports are usually 
global, I would expect (define ...)s to be global in the session, unless I put 
them inside a narrowed scope like a (let ...) myself. The org generated (let 
...) is invisible to the user and thus confusing, at least for GNU Guile.

For other Schemes it probably all depends on how their phases of expansion and 
evaluation work. I don't know enough about the Scheme standards, to tell, 
whether Guile has the correct behavior here or whether there is a correct 
behavior defined in the Scheme standards. Maybe someone more knowledgeable can 
chime in to comment on that.

repositories: https://notabug.org/ZelphirKaltstahl

  reply	other threads:[~2023-03-10 10:40 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-07 11:27 org-babel guile source block bug in handling multiple values Zelphir Kaltstahl
2023-03-07 14:36 ` Ihor Radchenko
2023-03-07 15:18   ` Zelphir Kaltstahl
2023-03-07 19:52     ` Bruno Barbier
2023-03-08  0:55       ` Zelphir Kaltstahl
2023-03-08 19:38         ` Bruno Barbier
2023-03-09  0:44           ` Zelphir Kaltstahl
2023-03-09 13:04             ` [BUG] Inconsistent global/local :var assignments in ob-* for lisps and non-lisps (was: org-babel guile source block bug in handling multiple values) Ihor Radchenko
2023-03-10 10:39               ` Zelphir Kaltstahl [this message]
2023-03-11  9:58                 ` Ihor Radchenko
2023-03-11 18:30                   ` Zelphir Kaltstahl
2023-03-12 11:33                     ` Ihor Radchenko
2023-03-19 13:50                   ` [PATCH] lisp/ob-scheme.el Zelphir Kaltstahl
2023-03-22 10:43                     ` Ihor Radchenko
2023-03-25 14:34                       ` Zelphir Kaltstahl
2023-03-26  9:32                         ` Ihor Radchenko
2023-04-25 12:28                         ` Ihor Radchenko
2023-04-29 11:08                           ` Zelphir Kaltstahl
2023-03-09 13:10             ` org-babel guile source block bug in handling multiple values Ihor Radchenko
2023-03-10 10:42               ` Zelphir Kaltstahl
2023-03-11 10:18                 ` Ihor Radchenko
2023-06-02 13:11                   ` Ihor Radchenko
2023-03-09 13:11             ` Ihor Radchenko
2023-03-09 14:21               ` Daniel Kraus
2023-03-10 11:57                 ` Ihor Radchenko
2023-03-10 10:45               ` Zelphir Kaltstahl
2023-03-08  1:13       ` Zelphir Kaltstahl
2023-03-08  8:55         ` Ihor Radchenko
2023-03-07 15:44 ` Max Nikulin
2023-03-07 21:41 ` Rudolf Adamkovič

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:

  List information: https://www.orgmode.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=21ea836d-8bdf-2d0d-8515-283209f2eb1f@posteo.de \
    --to=zelphirkaltstahl@posteo.de \
    --cc=brubar.cs@gmail.com \
    --cc=bzg@gnu.org \
    --cc=emacs-orgmode@gnu.org \
    --cc=yantar92@posteo.net \


* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).