From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Tomas Hlavaty Newsgroups: gmane.emacs.help Subject: RE: [External] : Re: Advantage using mapc over dolist Date: Mon, 02 Dec 2024 22:58:30 +0100 Message-ID: <8734j5lpbt.fsf@neko.mail-host-address-is-not-set> References: <87ed2qpo3o.fsf@gnu.org> <871pyqfl62.fsf@web.de> <87r06por3q.fsf@neko.mail-host-address-is-not-set> Mime-Version: 1.0 Content-Type: text/plain Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="11104"; mail-complaints-to="usenet@ciao.gmane.io" Cc: "help-gnu-emacs@gnu.org" To: Drew Adams , Heime , Michael Heerdegen Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane-mx.org@gnu.org Mon Dec 02 22:59:13 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 1tIERl-0002le-NH for geh-help-gnu-emacs@m.gmane-mx.org; Mon, 02 Dec 2024 22:59:13 +0100 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tIERC-0006XN-RZ; Mon, 02 Dec 2024 16:58:38 -0500 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 1tIERB-0006XF-12 for help-gnu-emacs@gnu.org; Mon, 02 Dec 2024 16:58:37 -0500 Original-Received: from logand.com ([37.48.87.44]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tIER7-0002lq-Ac for help-gnu-emacs@gnu.org; Mon, 02 Dec 2024 16:58:35 -0500 Original-Received: by logand.com (Postfix, from userid 1001) id 8A7FC1A0377; Mon, 2 Dec 2024 22:58:31 +0100 (CET) X-Mailer: emacs 29.4 (via feedmail 11-beta-1 I) In-Reply-To: Received-SPF: pass client-ip=37.48.87.44; envelope-from=tom@logand.com; helo=logand.com X-Spam_score_int: -18 X-Spam_score: -1.9 X-Spam_bar: - X-Spam_report: (-1.9 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, SPF_HELO_PASS=-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:148513 Archived-At: On Mon 02 Dec 2024 at 21:15, Drew Adams wrote: > OOTB Lisp isn't really made for such streaming-style programming. Lisp is great for streaming-style programming: ;; -*- lexical-binding: t -*- (defun stream (x) (cl-etypecase x (list (lambda () (pop x))) (array (let ((n (length x)) (i 0)) (lambda () (when (< i n) (prog1 (aref x i) (setq i (1+ i))))))))) (defun collect (stream) (cl-loop with x while (setq x (funcall stream)) collect x)) (collect (stream '(1 2 3 4)) (collect (stream [1 2 3 4])) (defun random-stream (&optional limit) (lambda () (random limit))) (defun head-stream (stream n) (lambda () (when (<= 0 (setq n (1- n))) (let ((z (funcall stream))) (unless z (setq n 0)) z)))) (collect (head-stream (stream '(1 2 3 4)) 3)) (collect (head-stream (stream '(1 2)) 3)) (collect (head-stream (random-stream 6) 10)) (defun map-stream (stream fn) (lambda () (let ((x (funcall stream))) (when x (funcall fn x))))) (collect (map-stream (head-stream (random-stream 6) 10) #'1+)) (defun message-stream (stream) (lambda () (let ((x (funcall stream))) (message "%s" (prin1-to-string x)) x))) (defun sleep-stream (stream seconds) (lambda () (let ((z (funcall stream))) (when z (sleep-for seconds) z)))) (collect (sleep-stream (message-stream (head-stream (random-stream 6) 10)) 1)) (defun fibonacci-stream () (let ((a 0) (b 1)) (lambda () (cl-shiftf a b (+ a b))))) (collect (head-stream (fibonacci-stream) 10)) Now lots of things can be such a stream. (defun deadline-stream (stream deadline) (lambda () ;; what is the Emacs replacement for get-universal-time? (if (< (get-universal-time) deadline) (funcall stream) (error "deadline ~s reached" deadline)))) Imagine a web application. It can be seen as such a stream where users funcall the stream with their clicks and keystrokes. A widget is also just another stream and can also contain other widgets which are also just another stream. The nice thing about these streams is how declaratively their definitions feel. Almost like a declarative reactive dataflow synchronous language.