From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Jakub Jankiewicz Newsgroups: gmane.emacs.help Subject: Re: Compiling a recursive macro Date: Sat, 13 Jun 2020 15:34:06 +0200 Message-ID: <20200613153406.135158eb@jcubic> References: <22b55d6d-f719-98d9-f8c8-e72e7fc43497@gmail.com> <87lfkt47bl.fsf@web.de> <87ftb1469o.fsf@web.de> <87h7vfi9cu.fsf@web.de> Mime-Version: 1.0 Content-Type: multipart/signed; boundary="Sig_/QKHQMTtm7tCnANsMfGl88RB"; protocol="application/pgp-signature"; micalg=pgp-sha256 Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="96806"; mail-complaints-to="usenet@ciao.gmane.io" Cc: help-gnu-emacs@gnu.org, Douglas Lewan To: Michael Heerdegen Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sat Jun 13 15:34:58 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 1jk6JG-000P2v-Ku for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 13 Jun 2020 15:34:58 +0200 Original-Received: from localhost ([::1]:53740 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jk6JF-000413-MB for geh-help-gnu-emacs@m.gmane-mx.org; Sat, 13 Jun 2020 09:34:57 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:60138) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jk6Ip-0003z0-Jz for help-gnu-emacs@gnu.org; Sat, 13 Jun 2020 09:34:32 -0400 Original-Received: from smtpo55.poczta.onet.pl ([213.180.142.186]:35766) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jk6Im-0000oe-Oj for help-gnu-emacs@gnu.org; Sat, 13 Jun 2020 09:34:30 -0400 Original-Received: from jcubic (unknown [185.129.113.167]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) (Authenticated sender: jcubic@onet.pl) by smtp.poczta.onet.pl (Onet) with ESMTPSA id 49kdqC5Dyvz1XQjvf; Sat, 13 Jun 2020 15:34:15 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=onet.pl; s=2011; t=1592055257; bh=q7v1I3ZS66E7wQyu4frVBFcDsiJ/uBQIMxQpvn4c2GE=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=hCowPsYNkjRfgKyxf5Agfcf/hOsunkrvVktMwJwBRCJO9SaNmcljc0a8TcZxCvbLo pzCfzta//nfohrMoy9KtO0zsRSVYoIS+GdbbTJtQ6kQdGNrCX4BGrl9VOyabcmaKoT Fzo0N6yqRkFOlQk7R9BH2CYH+zFL2HTnk8MalqIw= In-Reply-To: <87h7vfi9cu.fsf@web.de> X-Mailer: Claws Mail 3.17.3git196 (GTK+ 2.24.32; x86_64-pc-linux-gnu) X-ONET_PL-MDA-SEGREGATION: 0 Received-SPF: pass client-ip=213.180.142.186; envelope-from=jcubic@onet.pl; helo=smtpo55.poczta.onet.pl X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/13 09:34:23 X-ACL-Warn: Detected OS = Linux 3.11 and newer [fuzzy] X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.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_MSPIKE_H2=-1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN 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:123368 Archived-At: --Sig_/QKHQMTtm7tCnANsMfGl88RB Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: quoted-printable > BTW2, a small problem with your posted version is that it adds one `let' > binding per branch, but only the outermost is needed: Thanks I've fixed my macro now it looks like this: (define-macro (case val . list) "(case value (() result1) (() result2) [else result3]) Macro for switch case statement. It test if value is any of the item. If item match the value it will return coresponding result expression value. If no value match and there is else it will return that result." (let ((value (gensym))) `(let ((,value ,val)) ,(let iter ((list list)) (if (pair? list) (let* ((item (car list)) (first (car item)) (result (cadr item)) (rest (cdr list))) `(if (member ,value ',first) ,result ,(if (and (pair? rest) (eq? (caar rest) 'else)) (cadar rest) (if (not (null? rest)) (iter rest)))))))))) It's written in Scheme because that was my original implementation, I used named let in Emacs you probably will need flet or create helper function outside of macro. So I guess I will need to use that first implementation only as example of recursive macro. There is another example of recursive macros in book [Let Over Lambda][1] in printed version on page 135. And there is also chapter in [On Lips][2] on p= age 139 where there is one problem that you may find (probably issue OP had) if you expand with expansion that have `if` test inside, it will create infini= te loop, expansion need to be conditional so recursive check that stop the loop need to be called at macro level, it can't be present in expansion. This is example macro that will not work (defmacro nthb (n lst) `(if (=3D ,n 0) (car ,lst) (nthb (- ,n 1) (cdr ,lst)))) here recursive guard is present in expansion and it will not compile becuase it's infinite loop. [1]: https://letoverlambda.com/index.cl/guest/chap5.html#sec_5 [2]: http://www.paulgraham.com/onlisptext.html -- Jakub Jankiewicz, Web Developer https://jcubic.pl/me --Sig_/QKHQMTtm7tCnANsMfGl88RB Content-Type: application/pgp-signature Content-Description: Podpis cyfrowy OpenPGP -----BEGIN PGP SIGNATURE----- iQEzBAEBCAAdFiEEvGU/kjFLOYteHgvHpY7m8TH4MBMFAl7k1c8ACgkQpY7m8TH4 MBMFMQgArMUOiRf+SmTAQ+Mn4scMgAfEQf3EE4BIhXDOHtR6R6rJ6rnZKc2uCTyA HEUhQVFKtOMzCujWxXFv3c1xFhNo/PQO3rHqgY3WyuNBKvx3UvjPGzjlztVvjnbh sIRhGjs6JdAsokZ7Ym3o6mkCfeZjgIH+45XUuXsoJGavt91obFJHNRFo78uiiJBN vLdgKEZul1EvILAOuxLqaPlNtwWJ7/rZToAXWbM6hpsVjduMdicKl+4D3MUHyJXS KvURj57QPBX7nJlqPzplqruxRLR8ABEruI5CBBiossVc9bYenkHzKbyv2HKbyScd 1zx3DpVzq8s7PXsYIBM9bmXdpWvoyA== =TueN -----END PGP SIGNATURE----- --Sig_/QKHQMTtm7tCnANsMfGl88RB--