[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
RE: [External] : Re: Advantage using mapc over dolist
From: |
Tomas Hlavaty |
Subject: |
RE: [External] : Re: Advantage using mapc over dolist |
Date: |
Mon, 02 Dec 2024 22:58:30 +0100 |
On Mon 02 Dec 2024 at 21:15, Drew Adams <drew.adams@oracle.com> 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.
- Re: Advantage using mapc over dolist, (continued)
- Re: Advantage using mapc over dolist, Tassilo Horn, 2024/12/02
- Re: Advantage using mapc over dolist, Michael Heerdegen, 2024/12/02
- Re: Advantage using mapc over dolist, Heime, 2024/12/02
- Re: Advantage using mapc over dolist, Tomas Hlavaty, 2024/12/02
- Re: Advantage using mapc over dolist, Heime, 2024/12/02
- Re: Advantage using mapc over dolist, Tomas Hlavaty, 2024/12/02
- Re: Advantage using mapc over dolist, Tomas Hlavaty, 2024/12/03
- RE: [External] : Re: Advantage using mapc over dolist, Drew Adams, 2024/12/02
- RE: [External] : Re: Advantage using mapc over dolist,
Tomas Hlavaty <=
- RE: [External] : Re: Advantage using mapc over dolist, Drew Adams, 2024/12/02
- RE: [External] : Re: Advantage using mapc over dolist, Tomas Hlavaty, 2024/12/03
- Lazy functional programming [was: Advantage using mapc over dolist], Drew Adams, 2024/12/03
- Re: Lazy functional programming [was: Advantage using mapc over dolist], Tomas Hlavaty, 2024/12/03
- Re: Advantage using mapc over dolist, Michael Heerdegen, 2024/12/03