From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Thuna Newsgroups: gmane.emacs.help Subject: Re: `eval'ing form in the current lexical environment Date: Mon, 08 Jul 2024 04:07:31 +0200 Message-ID: <87y16c3acc.fsf@gmail.com> References: <87ikxh3uc0.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="23180"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) Cc: help-gnu-emacs@gnu.org To: Stefan Monnier Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Mon Jul 08 04:08:28 2024 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1sQdnm-0005lO-6o for geh-help-gnu-emacs@m.gmane-mx.org; Mon, 08 Jul 2024 04:08:26 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sQdn5-0000lu-8u; Sun, 07 Jul 2024 22:07:43 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sQdn4-0000li-0r for help-gnu-emacs@gnu.org; Sun, 07 Jul 2024 22:07:42 -0400 Original-Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1sQdmy-0008KW-7o for help-gnu-emacs@gnu.org; Sun, 07 Jul 2024 22:07:37 -0400 Original-Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-4266381bd23so6323715e9.2 for ; Sun, 07 Jul 2024 19:07:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1720404454; x=1721009254; darn=gnu.org; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:from:to:cc:subject:date:message-id:reply-to; bh=kBZeuwmFZ/v+Axd0kPA4yvwtPqd1rGVFg3cfnc2mpGc=; b=mH3laBT9O0dLzoQTQ8hrry8ibpPFqrn4iML4Ll3HdOjQ5GIBusnQD5ow3AwpPPNgXR nyyrPRlAaAnhUQYrFBff6kIu6dletrRjdW1AehL6NTiNpdOTMflbxAB7f7WHTt75Klns A9W3r4Su1rdMbSRA9O9dWMW9mDVOtNaLvvTnGcDFYX/04+kAIOLj13wkodMjrDXAhySx Es6+sRNmrQ+KoxXwkphChs1JmbfSbKxJIdxUervsrgmXL1mwqGmILDytRAtWcM/hwi8x 97PtYPM8sFsflgugR2Dd0HD0KgMu57qFtKbsh4F4XEEPeoKyk+ND/Qb9pTLMX4qJDc3s mMPQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1720404454; x=1721009254; h=mime-version:user-agent:message-id:date:references:in-reply-to :subject:cc:to:from:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=kBZeuwmFZ/v+Axd0kPA4yvwtPqd1rGVFg3cfnc2mpGc=; b=XBMLVw9ODGsRFOKghWplklUIJM3Ke41FN4tlV6Unk9wW6dvHq1YATQu9hAuKu013vv nLlp2ivVB7P3VWdXg69HchLaH8ae7bHUAqeqiuXrstxfP2YTeOgiKDcZDW+HUDmASjJD Haf7K3QE9NdFKNmJQxDkrhzTl1obhE2osdQ+LqpitZR8rqXWfb5wpekKivi7qYHgJo4F CyMdvbgNYGcms8FoKCQ2mhD6D7EfKR+9puWqBJgXMJSiG1eS9KDWxmO9ST1KnlNGlbaE ypJUf9sRgKYK1n8Fca9dfl9jzLsnPU0m6RGLyLz7HFMCVhiJ8gk/g+sdylSM7gGn+X2r W6kA== X-Gm-Message-State: AOJu0YzFbhkdRnrduXWNPo3Fx8u+vOah9GASNdhfp3cyuaVMowX6hHsP /e85pORNYk5DnKJ37T+DMKwkaIZXaWVhOUXH2lWAsZ9iqRrcDPgzu02c2w== X-Google-Smtp-Source: AGHT+IElFuqZF9Nj65sDoCbiwoZGdD2X+HXZP/DcbJfEsYoWUHhD7QcO+OOvLGIgdo4C2V3NGQLkFw== X-Received: by 2002:a05:600c:5788:b0:426:5cee:4abc with SMTP id 5b1f17b1804b1-4265cee4afamr37487715e9.20.1720404453413; Sun, 07 Jul 2024 19:07:33 -0700 (PDT) Original-Received: from thuna-lis3 ([85.106.105.81]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42663019ed2sm53457925e9.30.2024.07.07.19.07.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 07 Jul 2024 19:07:33 -0700 (PDT) In-Reply-To: (Stefan Monnier via Users list for the's message of "Sun, 07 Jul 2024 15:16:30 -0400") Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=thuna.cing@gmail.com; helo=mail-wm1-x332.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:147116 Archived-At: [ I appear to have forgotten to CC the list, sorry about that. Below's what I have previously sent. Please only reply to this mail. ] Hmm, I now realize that I misspoke in my original post. What is doing this is not a macro but a function, so that was why I went to `eval'. This form is being generated from within itself. Now, your suggestion did bring up an interesting point for me in that I could simply make a wrapper macro for this function and put that in, but there does appear to be a problem with this approach in this specific situation which... will be even more difficult to explain. Below are two versions of me trying to explain the problem, one with context and one with me attempting to reduce it down to the bare essentials. I'll leave the former in in case I leave out some important details in the latter, but I have to be honest: it is extremely convoluted. Please only read it if the first explanation doesn't make sense or if you wanted to take a look at the code and find yourself confused as to what's happening in it. --- Reduced down to essentials --- The function (which I accidentally called a macro) we are talking about is the itself, that is, it looks something like (defun (form) ;; `(,head ,@args) == form `(... (if (macrop #',head) (eval ( `(,head ,@args))) ... `(,head ,@argsyms)))) and there is a different macro which expands into the defun by doing (defmacro (name lambda-list &rest body) `(defun ,name ,lambda-list ,( `(progn ,@body)))) recursively expands and modifies FORM, and returns a version of it which is "processed", and then the definition of NAME is set to be that processed body. All macros are expanded and processed, thus `(,head ,@args) above is /necessarily/ a function call... that is, unless it is later redefined as a macro. The goal with (if (macrop #',head) ...) is to check for this exact case, an in case it DID happen, fix it by processing the form again, calling that processed version instead of what was supposed to happen. This however can only during the runtime of NAME, because that is when we are concerned with `head' being a macro, so the call to must happen within NAME and not within the top-level . Because we are calling during NAME, we obtain a form which needs to be evaluated. --- With context --- Let me provide you with the actual code we are discussing. I intend to bring this up in emacs-devel at some point anyways so hopefully it'll be worth the read: https://git.sr.ht/~thuna/tcl-values Quick rundown of what the code does: This is a library which simulates true Common Lisp style multiple values. The way this is achieved by having `cl-values' set a global variable which holds the values ONLY IF an "expecting multiple values" flag is set. Any function which supports multiple values must therefore ensure that this flag is suppressed (the term used in the library for this is "sanitization") everywhere in the code except for in the forms which are "returning" (in that, their values is what the function will/may return). While the function author can manually sanitize their function, this is a cumbursome and tedious process so the function `tcl-values--sanitize' is provided to sanitize any forms fed to it, which is called from `tcl-defun' before defining the function. This is the nebulous that we are talking about. The specific branch in which this eval exists is the basic call to (func arg1 arg2...). It's purpose is - in case `func' is later redefined as a macro - to preserve the sanitization of the function by going through the form and re-sanitize it. This needs to happen at runtime because that's when we are attempting to detect if `func' was redefined or not. Now, I looked into defining a macro which simply called `tcl-values--sanitize', but this led to two problems: 1. This resolution happens at macroexpansion time, due to it being `macroexpand-all'ed. 2. The branch which calls the macro is the same branch we feed into the macro, thus the expansion of the macro contains exactly the same macro, resulting in infinite recursion. There *might* be some trick I can use to get rid of the second problem, but I cannot think of one that would allow me to fix the first one, unless I can somehow prevent macroexpand-all from expanding the resulting macro.