From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Michael Heerdegen Newsgroups: gmane.emacs.devel Subject: Re: `thunk-let'? Date: Mon, 09 Oct 2017 16:07:33 +0200 Message-ID: <87mv50e7oa.fsf@web.de> References: <87infp9z6j.fsf@web.de> <87zi90eehg.fsf@web.de> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain X-Trace: blaine.gmane.org 1507558079 3983 195.159.176.226 (9 Oct 2017 14:07:59 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Mon, 9 Oct 2017 14:07:59 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.0.60 (gnu/linux) Cc: Nicolas Petton , Emacs Development To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Oct 09 16:07:51 2017 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1e1Yij-0008Ji-Bb for ged-emacs-devel@m.gmane.org; Mon, 09 Oct 2017 16:07:49 +0200 Original-Received: from localhost ([::1]:58100 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1Yiq-00045P-RK for ged-emacs-devel@m.gmane.org; Mon, 09 Oct 2017 10:07:56 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:50572) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1e1Yik-00045F-3U for emacs-devel@gnu.org; Mon, 09 Oct 2017 10:07:51 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1e1Yif-00061r-8V for emacs-devel@gnu.org; Mon, 09 Oct 2017 10:07:50 -0400 Original-Received: from mout.web.de ([212.227.17.12]:61829) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1e1Yie-00061a-TH for emacs-devel@gnu.org; Mon, 09 Oct 2017 10:07:45 -0400 Original-Received: from drachen.dragon ([88.67.74.137]) by smtp.web.de (mrweb101 [213.165.67.124]) with ESMTPSA (Nemesis) id 0Meje0-1ddSIQ1POi-00OFld; Mon, 09 Oct 2017 16:07:34 +0200 In-Reply-To: <87zi90eehg.fsf@web.de> (Michael Heerdegen's message of "Mon, 09 Oct 2017 13:40:27 +0200") X-Provags-ID: V03:K0:Cj6aR5BpEQoiCrA9PvFPMfZzig+/1fCeFAIZnRrMBvvN7F5belj 6uP97ClkdtQnQowTLHBRDY5+skEAZLRm6dnBO7eMC5QyguhxFBwyORNWO5qS+6cKMkaU/JW GSYGD2AOKcBjZ7hmHoFp+BdOiyRaNCoDGgBITSp5DVkDDxmbWE/EdLeLrQW6RK/BYdW5Or5 uE3gpcGKSoBgoNAoJVR5Q== X-UI-Out-Filterresults: notjunk:1;V01:K0:zjfsIOlLAlo=:M8CrqmqBcePCm1uEai7qLN atY+/JgWKb59VhQ0Mb+zB2h/yxFksP+fJ0KOuJi2LGULdbRmNMO8MF4ZoZPryOLp4lZtl1pkE tQOosaijsIS+JLrrlacMx+QD7lUxiCnxQRdyPJnpcnEogsUJjXE3+OZKnNWe1nFzxXMzblult /bhlqpUYLG78tc53FGyvIgoEmN3vHUgUycPAso11gea0TBwd1McQtUk2B53H42UG7YgYzWKUF a+WF4Auws5z1oS+IJEPBqfG1VUCkpCMySI3Xuc5vV9h1KWaSy9rDuALd2CzGdZHaxOyr6C9OQ oBsVAUFO+JbC0gEyuHlmGjtZg8Luousuj6SKp3a/I3VC9qUulG3Lgs/cqjhhs3bGMJVTxjz0o a3xx0fPjJEyEY6BIuanRR8qkmQy8SLtp5wU8AZBHV1oy/ma1VfiU6iu/vKqias793VMPCvui5 jP7hho8ARUrwxNuz9TK0+gZ6zkBvyJx7kCfvylKK0+KDkP5rU7nB7EpGOCXcBUNg5Dej0eja1 XNHCpTzVGjtc/94YlVyufd2vTsudQkqw2XWIqq6zhCxAUPTf9Fr130vpPBNMKyln08MY3yB42 CuaP86C/DEIPUOvlDBrSyU4qMLQ8+KVSj6mjOJ5qQF2BRbB5kSyb4bWmy7BZrhph9N33lksfc W/XwBRjQXrHXUmH0vYDTLMQA91/f09dbrh3+VNd1YAEXy4Np9tbeDECNaG+IDkLOhH2d6gn+z s21NC7l1QRQf6a6+qrQFGdXTBVrRcogtNXwuF4MPuxuPJcAxyifRAlUPtGxvoqiG77S3XR12 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 212.227.17.12 X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: "Emacs-devel" Xref: news.gmane.org gmane.emacs.devel:219301 Archived-At: Michael Heerdegen writes: > The second case should be trivial, that's what we get with > `cl-symbol-macrolet' out of the box. I tried the first way: I implemented a place `lazy-let--thunk-value' that is only used internally, and went with `cl-symbol-macrolet'. Now doing the e.g. the following works (lexical-binding needed!): #+begin_src emacs-lisp (lazy-let ((a (+ 1 2)) (x (error "This evaluation would raise an error!")) (b (* 10 3)) (c (* 10 10 10))) (setq a (+ b a)) ; 33 (cl-incf b) ; 31 (+ a b c)) ==> 1064 #+end_src Here is the implementation: #+begin_src emacs-lisp ;; -*- lexical-binding: t -*- (eval-when-compile (require 'cl-lib)) (defun lazy-let--thunk-value (thunk) (funcall thunk)) (defun lazy-let--set-thunk-value (thunk value) (funcall thunk value)) (gv-define-simple-setter lazy-let--thunk-value lazy-let--set-thunk-value) (defmacro lazy-let--make-thunk (expr) (let ((forced (make-symbol "forced")) (val (make-symbol "val")) (args (make-symbol "args"))) `(let (,forced ,val) (lambda (&rest ,args) (if ,args (prog1 (setf ,val (car ,args)) (setq ,forced t)) (unless ,forced (setf ,val ,expr) (setf ,forced t)) ,val))))) (defmacro lazy-let (bindings &rest body) "Like `let' but make delayed bindings. This is like `let' but all binding expressions are not calculated before they are used." (declare (indent 1)) (setq bindings (mapcar (pcase-lambda (`(,var ,binding)) (list (make-symbol (concat (symbol-name var) "_thunk")) var binding)) bindings)) `(let ,(mapcar (pcase-lambda (`(,thunk-var ,_var ,binding)) `(,thunk-var (lazy-let--make-thunk ,binding))) bindings) (cl-symbol-macrolet ,(mapcar (pcase-lambda (`(,thunk-var ,var ,_binding)) `(,var (lazy-let--thunk-value ,thunk-var))) bindings) ,@body))) (defmacro lazy-let* (bindings &rest body) "Like `let*' but make delayed bindings. This is like `let*' but all binding expressions are not calculated before they are used." (declare (indent 1)) (if (> (length bindings) 1) `(lazy-let (,(car bindings)) (lazy-let ,(cdr bindings) ,@body)) `(lazy-let ,bindings ,@body))) #+end_src Regards, Michael.