GNU bug report logs -
#73431
Add `setf` support for `stream.el` in ELPA
Previous Next
Reported by: Okamsn <okamsn <at> protonmail.com>
Date: Mon, 23 Sep 2024 01:35:01 UTC
Severity: wishlist
Done: Stefan Monnier <monnier <at> iro.umontreal.ca>
Bug is archived. No further changes may be made.
Full log
View this message in rfc822 format
Hi,
I agree to what Stefan is saying.
Philip Kaludercic <philipk <at> posteo.net> writes:
> Being able to modify the head of a buffer-stream using setf seems like
> something that could be useful, and certainly more efficient than what
> many people want to do with splitting the return value of
> (buffer-string).
AFAIK, what you normally do in this situation is creating a new stream
reusing the tail of the given one, like in this toy example:
#+begin_src emacs-lisp
(cl-labels ((integers (&optional from)
(let ((from (or from 1)))
(stream-cons from (integers (1+ from))))))
(let ((my-natural-numbers (integers 1))) ;a stream of the natural numbers: 1, 2, ...
(let ((my-natural-numbers-with-head-replaced ;let's "replace" the first element:
(stream-cons 'not-1 (stream-rest my-natural-numbers))))
;; Test: what are the first 10 elements of this second stream?
(seq-into
(seq-subseq my-natural-numbers-with-head-replaced 0 10)
'list))))
#+end_src
Modifying elements later in the stream conflicts a bit with the idea of
a delayed data structure. The above idea can be modified to work in
this case too, though. Creating a new stream even makes more
transparent what is going on... I don't want to tell anybody how to
work with these guys, but that's how I learned it at university.
In typical scenarios the elements before the one to change already have
been processed and been thrown away, and the element you
actually are interested in is the head element most of the time. Like
for a queue.
For buffer contents listing streams I could imagine that one could make
such a thing invalidate itself when the buffer has been modified;
like here [I only added few lines to the
(stream ((buffer buffer) &optional pos)) implementation]:
#+begin_src emacs-lisp
(cl-defmethod my-buffer-chars (buffer &optional pos)
(let ((mods (buffer-modified-tick))) ; added
(with-current-buffer buffer
(unless pos (setq pos (point-min)))
(if (>= pos (point-max))
(stream-empty))
(stream-cons
(with-current-buffer buffer
(save-excursion
(save-restriction
(widen)
(goto-char pos)
(char-after (point)))))
(if (not (eq mods (buffer-modified-tick))) ; added
(error "Buffer has been modified") ; added
(my-buffer-chars buffer (1+ pos)))))))
#+end_src
Already generated elements normally can't "invalidate themselves",
unless you make them functions. But a whole stream that regenerates or
recomputes itself doesn't seem natural to me. You would rather check
whether the stream is still valid _explicitly_ - and if not, just call
the function that returned that stream (most of the time a named
function, like above) again to create a new stream - in the above
example, possibly with an adopted POS argument.
My two cents.
Michael.
This bug report was last modified 264 days ago.
Previous Next
GNU bug tracking system
Copyright (C) 1999 Darren O. Benham,
1997,2003 nCipher Corporation Ltd,
1994-97 Ian Jackson.