[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Improve `replace-regexp-in-string' ergonomics?
From: |
Dmitry Gutov |
Subject: |
Re: Improve `replace-regexp-in-string' ergonomics? |
Date: |
Thu, 23 Sep 2021 01:23:07 +0300 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.13.0 |
On 22.09.2021 23:18, Lars Ingebrigtsen wrote:
But if we target thread-first instead and make the new function accept
STRING in the first position, all optional arguments would be still
available.
Yes, I've always found it weird that these functions have the object to
be worked upon as the last non-optional parameter. I had to look it up
for years when using `replace-regexp-in-string'. And it didn't help
that Emacs took this function from XEmacs, which had the string in a
different position... But I don't remember where...
*Lars says "apt install xemacs21"*
I misremembered:
`replace-in-string' is a compiled Lisp function
-- loaded from "/build/xemacs21-rcHAYB/xemacs21-21.4.24/lisp/subr.elc"
(replace-in-string STR REGEXP NEWTEXT &optional LITERAL)
So it has the placement of STRING that seems logical, I think.
On the other hand, changing the placement in a new function like this
will probably be even more confusing.
Adding a new function is the only time we *can* change the arguments
order. If we subsequently obsolete the current function, it could fly.
It's not the wildest among the alternatives anyway -- the idea about the
argument being a list takes the first place, I think. And either could
work, ultimately.
If we want to be able to use threading macros more consistently, it
seems functions should expect the "main" argument in either the first or
the last position, across the standard library. Or at least portions of it.
For example, in Clojure:
By convention, core functions that operate on sequences expect the
sequence as their last argument. Accordingly, pipelines containing
map, filter, remove, reduce, into, etc usually call for the ->> macro.
Core functions that operate on data structures, on the other hand,
expect the value they work on as their first argument. These include
assoc, update, dissoc, get and their -in variants. Pipelines that
transform maps using these functions often require the -> macro.
(https://clojure.org/guides/threading_macros)
It seems to me, with penchant for optional arguments, it's generally
harder to put the "main" argument into the last position in our case. I
could be wrong, though. But STRING being in neither first or last
position makes threading macro decidedly less useful.
(regexp-replace "'" "\""
",[[:space:]]" " "
"\\]" ")"
"\\[" "("
results)))
Or some variation thereupon with some more ()s to group pairs.
I'm not sure how to also make it accept "normal" convention, and we
probably don't want to always have to wrap the args in an alist, even
when only one replacement is needed.
No, that's the problem. We could hack it up by doing a &rest in
reality, and then checking if the first parameter is a list, but yuck.
Probably check that the number of &rest arguments divides by two as
well. Or three, or four? FIXEDCASE, LITERAL and SUBEXP could apply to a
single replacement. At best, it will create an ambiguity (do those args
apply to all steps, or do I need to repeat them?), but at worst it can
limit the applicability of the approach (when steps need different
values of these). Threading solves it.
(setq author (regexp-remove "[ \t]*[(<].*$" author))
(setq author (regexp-remove "\\`[ \t]+" author))
(setq author (regexp-remove "[ \t]+$" author))
(setq author (regexp-replace "[ \t]+" " " author))
IDK, if that leads to no increase in efficiency, then probably not?
Replacing with "" is an established pattern by now.
It helps with readability -- the function says what the intention is.
True. I'm not sold, though.
Re: Improve `replace-regexp-in-string' ergonomics?, Dmitry Gutov, 2021/09/22
Re: Improve `replace-regexp-in-string' ergonomics?, Stefan Monnier, 2021/09/22