From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: steve-humphreys@gmx.com Newsgroups: gmane.emacs.help Subject: Re: Understanding the "let" construct and the setting of variables Date: Thu, 17 Dec 2020 03:49:19 +0100 Message-ID: References: <87zh2d1byp.fsf@fastmail.fm> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31770"; mail-complaints-to="usenet@ciao.gmane.io" Cc: help-gnu-emacs@gnu.org To: Joost Kremers Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Thu Dec 17 03:50:23 2020 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 1kpjN1-0008A9-Cr for geh-help-gnu-emacs@m.gmane-mx.org; Thu, 17 Dec 2020 03:50:23 +0100 Original-Received: from localhost ([::1]:35358 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kpjN0-0000MZ-EO for geh-help-gnu-emacs@m.gmane-mx.org; Wed, 16 Dec 2020 21:50:22 -0500 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:37700) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kpjM7-0000MG-4S for help-gnu-emacs@gnu.org; Wed, 16 Dec 2020 21:49:27 -0500 Original-Received: from mout.gmx.net ([212.227.15.18]:60417) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kpjM4-0004lW-QK for help-gnu-emacs@gnu.org; Wed, 16 Dec 2020 21:49:26 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=gmx.net; s=badeba3b8450; t=1608173359; bh=K7o3rEaTvXo6WANXMngV/sUqNA7IXSdMFp/EONLGjWU=; h=X-UI-Sender-Class:From:To:Cc:Subject:Date:In-Reply-To:References; b=M3VSSOs51ecsMeis85GOGydzKxx45TXT2hwnaaj6vcPLPY1+ej0mjtkk2baP/bSKW qtBdOd/YnYpCBryYugeAuhoHRtT8w6yjHnOL2J7oi3/SLIRK4fmm7i6wGL1y8FEdmC QuSPKDobij7j29h5dups+Su/w8VtH2deF4M1Bll4= X-UI-Sender-Class: 01bb95c1-4bf8-414a-932a-4f6e2808ef9c Original-Received: from [213.165.168.94] ([213.165.168.94]) by web-mail.gmx.net (3c-app-mailcom-bs11.server.lan [172.19.170.179]) (via HTTP); Thu, 17 Dec 2020 03:49:19 +0100 Importance: normal Sensitivity: Normal In-Reply-To: <87zh2d1byp.fsf@fastmail.fm> X-UI-Message-Type: mail X-Priority: 3 X-Provags-ID: V03:K1:M4KUhnuTYuVNX+OMf38WkXb+ro81+BCDZAjC3u13IRIxVCBK/2pJyrZ+NA70+2efFZxS3 X5GlEIyPER5iKhIS/UHoCOCNwD7R333A6IhHJVWV+SHVdz/atztT+JMwCAODQls72KldgoLjLUzs 0rbbApyx9RN3RJpxAvyhx9AuyavVwfULK9yj0x4+6c95pjI0zv7PN8sxoLxu3dXYybgHaGQN/6qk 7/NWXKoTRQOiP08f5d4UOzr6BkHGbJHnDRT7K7VUL94r+t/QqmTF3G+aFKuc9UqJRkaHXspSq2Tp A4= X-UI-Out-Filterresults: notjunk:1;V03:K0:pkcPvKRO6V8=:gXCJNbQvYavtLm+xY9JS99 vNkaE0+OZsDq+otZF3PfAgixT9Fs6XOcEdF4AUDF8paXh/usmojCm1BA7R82LVKxrmSKzrtoL FXxnS1+33c/31TtNIIFbKTmgDyMjvyn5+FP90kIQEW/oPKeAO3zI2/Autu+uWC+yRzIEKthQy Jq6MbAGeI0UovRr9Hho6U3x805qQVnJRATYBOn6qh7asgcC3wMkWLtDNoNjtF0hafGndrbmtJ r9gxcJp6nV29/7XwBN9e1esXALN5ep98eM9fLlQhhWxD1ycMrXoSqcd4ivFWao7cS0tLgLu3I Cd+1xH0lhLp/VlWpU2fikhlbdccJN1ycA24SmWaA/OUb/m0ueAMacncEzjn190pSCOlK8VOzO huo+fpRGjD4G96uttgwJkVyg+uL1R7RFZ+FDuf/gzWVR/ALyCDm0NE8khWLUmcBIEyEu/F7SR wj3yH3RMUIX1NthdAoSb9CnZMW5bf6+LZyC596XS5NPxg1ylScN6c0bmpeImj8J1jm/mmyxBK IkkQOltTb57Qz0Janli17UBPZv+gImfcB2beLNzXKPanqg4TcbSq/mbHDTUCN8lkU7vsRJLIZ 6NbIiaavIAoXk= Received-SPF: pass client-ip=212.227.15.18; envelope-from=steve-humphreys@gmx.com; helo=mout.gmx.net X-Spam_score_int: -25 X-Spam_score: -2.6 X-Spam_bar: -- X-Spam_report: (-2.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H2=-0.001, 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.23 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" Xref: news.gmane.io gmane.emacs.help:126440 Archived-At: > Sent: Thursday, December 17, 2020 at 1:21 AM > From: "Joost Kremers" > To: steve-humphreys@gmx=2Ecom > Cc: help-gnu-emacs@gnu=2Eorg > Subject: Re: Understanding the "let" construct and the setting of variab= les > >=20 > On Thu, Dec 17 2020, steve-humphreys@gmx=2Ecom wrote: > > I have been writing some elisp to set the time grid in the agenda=2E > > The discussion progressed towards the use of the "let" construct=2E > > > > But, the discussion got too advanced for me to follow the different > > points of view and make a decision=2E > > > > This message is for showing some examples, of how to set and use varia= bles > > in a "let", because people criticise using "setq"=2E But discussion n= eeds > > simple examples that would not overwhelm a relative beginner=2E > > > > (defun timfutur () > > (interactive) > > (setq tim 845) > > (setq tsk 80) > > > > (setq thr (/ tim 100)) > > (setq tmn (- tim (* thr 100))) > > > > (setq tinc_mn (+ tmn tsk)) > > (setq tinc_hr (/ (+ tmn tsk) 60)) > > (setq tinc_mn (- tinc_mn (* tinc_hr 60)) ) > > > > (setq thr_futur (* (+ thr tinc_hr) 100) ) > > (setq tmn_futur tinc_mn) > > (setq tim_out (+ thr_futur tmn_futur)) >=20 > I'm not sure what exactly you're asking, (I'm wondering if your message = is > complete or was accidentally sent before you finished it), but to unders= tand the > problem with `setq`, evaluate your function above in the `*scratch*` buf= fer=2E > (Copy the function into the `*scratch*` buffer, put the cursor right aft= er it > and press `C-x C-e`; note that you need to add another closing parenthes= is on > the last line)=2E That will define your function and make it available t= o > Emacs=2E >=20 > Then open a Lisp interaction buffer with `M-x ielm RET`=2E You'll get a = buffer > called `*ielm*` with a prompt where you can type Elisp expressions that = get > executed right away=2E Type `tim` (without parentheses) and hit RET=2E Y= ou should > get a void variable error: >=20 > *** Eval error *** Symbol=E2=80=99s value as variable is void: tim" >=20 > Then type `(timfutur)` and hit RET=2E You'll get the return value 1005 (= displayed > also in octal and hexadecimal)=2E >=20 > Now type `tim` again at the prompt=2E This time, there won't be an error= anymore=2E > Instead you'll get the value 845=2E >=20 > Running your function has created a global variable `tim` (plus all the = other > variables you've setq'ed), and since there are no packages or namespaces= in > Elisp, your variable is now available to all of Emacs=2E I ran the following =20 ELISP> tima (lett 845 80) "tim_out: 1005" ELISP> tim *** Eval error *** Symbol=E2=80=99s value as variable is void: tim ELISP> (lett 845 90) "tim_out: 1015" ELISP> tim *** Eval error *** Symbol=E2=80=99s value as variable is void: tim So this is quite different from using "setq"=2E The variable "tim" is not available to all of emacs=2E ------- code ------ (defun lett (tim tsk) (let* ( (thr (/ tim 100)) (tmn (- tim (* thr 100))) (tinc_mn (+ tmn tsk)) (tinc_hr (/ (+ tmn tsk) 60)) (tinc_mn (- tinc_mn (* tinc_hr 60))) (thr_futur (* (+ thr tinc_hr) 100)) (tmn_futur tinc_mn) (tim_out (+ thr_futur tmn_futur)) ) ;; --- body of let ---- (message "tim_out: %d" tim_out) )) =20 > While I was writing this, your two questions arrived: >=20 > > 1=2E In what simple circumstances would one use a "setq" in the body o= f a let? >=20 > One common idiom would be to create or consume a list inside a loop, e= =2Eg=2E,=20 >=20 > ``` > (let ((lst (some-function-that-produces-a-list))) > (while (some-condition-on (car lst)) > (do-something-with (car lst)) > (setq lst (cdr lst)))) > ``` >=20 > Nowadays such an idiom would more often be handled with a higher-order f= unction > of the map/reduce/filter-family, but there may be situations in which th= at > doesn't work=2E >=20 > Another example would be the case where you want to modify a value based= on some > set of conditions, e=2Eg=2E,: >=20 > ``` > (let ((x (get-some-value)) > (y (get-some-other-value))) > (cond > ((some-condition-on y) > (setq x (do-something-with y))) > ((some-other-condition-on y) > (setq x (do-something-else-with x))) > (:otherwise > (setq y nil))) > (now-do-something-with x y)) > ``` >=20 > You could probably rewrite this without `setq` using `let*` and some > intermediate variables, but sometimes I find using `setq` to be clearer, > especially if you have multiple values that are interdependent in comple= x ways=2E >=20 > > 2=2E What simple option does one have that is more advantageous than u= sing a "setq"? >=20 > `let*` in the example function you gave above=2E For creating or consumi= ng a list, > there's the map/filter/reduce-family or cl-loop=2E >=20 > Not sure if that makes it any easier for a relative beginner :-/ but I h= ope it > helps a bit anyway=2E >=20 >=20 > --=20 > Joost Kremers > Life has its moments >=20 >