dash.el
dash.el copied to clipboard
Consider defining -last-item and -first-item as generalised variables
I'd like to be able to write:
(setf (-last-item some-list) new-value)
Rather than:
(setf (car (last some-list)) new-value)
Would you be open to a patch that did this?
This gives me an idea... maybe we could add this interface also for "predicates" like -last
or -first
and similar commands... that would enable us to "find the element and modify it" in a universal way (basically simulating functions like --replace-first
and similar).
Would such an API make sense?
I'm not sure what you're describing. Do you mean supporting something like this?
(setf (-first #'evenp some-list) 0)
Exactly. That's equivalent to a hypothetical api (-replace-first #'evenp some-list 0)
but with the advantage we don't have to add a version for each dash function which does something like this.
The disadvantage is that AFAIU setf
is side-effect and dash is trying to be pure. Can you make a pure version of setf
?
@Fuco1: cl-letf
is pure:
(setq lst '(1 2 3))
(cl-letf (((-first-item lst) 0))
(copy-list lst)) ;; => (0 2 3)
lst ;; => (1 2 3)
Without the copy-list
, you'd get (1 2 3)
back. You could put this into a macro:
(defmacro -replacef (lst place value)
`(letf ((,place ,value))
(copy-list lst)))
(-replacef lst (-first-item lst) 0) ;; => (0 2 3)
Of course, this is far from perfect, because you have to specify lst
as well as place
, meaning that the following won't work:
(-replacef '(1 2 3) (-first-item '(1 2 3)) 0) ;; => (1 2 3)
It's a start, anyhow.
You can make a slight improvement, if you let --replacef
be anaphoric.
(defmacro --replacef (lst place value)
`(letf* ((it ,lst)
(,place ,value))
(copy-list it)))
(--replacef '(1 2 3) (-first-item it) 0) ;; => (0 2 3)
I've looked through some of the gv
code, and I have a feeling that to make something like -replacef
that doesn't require (effectively) specifying the list twice will be fairly involved (but I'll give it a good shot).
This was partially implemented in #205