From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Emanuel Berg Newsgroups: gmane.emacs.help Subject: Re: [External] : Re: Testing whether a list contains at least one non-nil element Date: Sun, 30 Oct 2022 13:48:34 +0100 Message-ID: <87ilk15vfh.fsf@dataswamp.org> References: <87r0yw85la.fsf@dataswamp.org> <87lep031vm.fsf@web.de> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="33925"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Gnus/5.13 (Gnus v5.13) To: help-gnu-emacs@gnu.org Cancel-Lock: sha1:1NNrSNhsh+VxjGDNkZE/k4UKfRc= Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Sun Oct 30 14:06:41 2022 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 1op81Q-0008XT-R0 for geh-help-gnu-emacs@m.gmane-mx.org; Sun, 30 Oct 2022 14:06:40 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1op81K-0005e6-3x; Sun, 30 Oct 2022 09:06:34 -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 1op7k6-0000Mi-Ch for help-gnu-emacs@gnu.org; Sun, 30 Oct 2022 08:48:46 -0400 Original-Received: from ciao.gmane.io ([116.202.254.214]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1op7k4-0005qK-AZ for help-gnu-emacs@gnu.org; Sun, 30 Oct 2022 08:48:45 -0400 Original-Received: from list by ciao.gmane.io with local (Exim 4.92) (envelope-from ) id 1op7k2-00013Q-4a for help-gnu-emacs@gnu.org; Sun, 30 Oct 2022 13:48:42 +0100 X-Injected-Via-Gmane: http://gmane.org/ Mail-Followup-To: help-gnu-emacs@gnu.org Mail-Copies-To: never Received-SPF: pass client-ip=116.202.254.214; envelope-from=geh-help-gnu-emacs@m.gmane-mx.org; helo=ciao.gmane.io X-Spam_score_int: -16 X-Spam_score: -1.7 X-Spam_bar: - X-Spam_report: (-1.7 / 5.0 requ) BAYES_00=-1.9, HEADER_FROM_DIFFERENT_DOMAINS=0.248, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sun, 30 Oct 2022 09:06:33 -0400 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: , Original-Sender: "help-gnu-emacs" Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.emacs.help:140512 Archived-At: Stefan Monnier via Users list for the GNU Emacs text editor wrote: >> You don't want to implement such functions in Emacs with >> recursion because you'll easily hit `max-lisp-eval-depth' >> when they are called. > > Indeed (and it's significantly slower than the corresponding > loop without function calls). Recursion is slower because of the continual function calls and those will also blow the stack eventually ... >> Sorry to tell you, but a loop is the preferable way >> in Elisp. > > Luckily, since Emacs-28 you can have your cake and eat it too: > > (defun has-non-nil (lst) > (named-let loop ((lst lst)) > (cond > ((null lst) nil) > ((consp lst) (or (not (null (car lst))) (loop (cdr lst)))) > (t (error "Not a proper list! You cheater!"))))) `named-let' is from a "[l]ooping construct taken from Scheme." I love it that Elisp is like a "Lisp dump" area where everything from the Lisp world worth having seems to end up eventually ... > Admittedly, here the `named-let` construct gives you only > the elimination of tail-recursion, but in many other > circumstances it also leads to quite elegant code. Here tail refers to not the `cdr' of the list but the tail of the function, "a tail call is a subroutine call performed as the final action of a procedure. If the target of a tail is the same subroutine, the subroutine is said to be tail recursive, which is a special case of direct recursion" [1] I don't know why that is such an important distinction, I also remember recursion over trees that recursed both ways from the top and middle nodes if it/they had several child nodes, so I guess that recursion was both tail and direct LOL. Elisp direct recursion example anyone? And what was this continuation-passing style? CPS 1975 continuation-passing style, coined in "AI Memo 349" I used it once, but don't remember what file that was ... > (defalias 'has-non-nil > #'(lambda (lst) [...] TIL: In Scheme-inspired Elisp, quoting lambdas is OK ... [1] https://en.wikipedia.org/wiki/Tail_call -- underground experts united https://dataswamp.org/~incal