[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: dolist considered harmful

From: Garreau\, Alexandre
Subject: Re: dolist considered harmful
Date: Wed, 31 Oct 2018 23:02:57 +0100
User-agent: Gnus (5.13), GNU Emacs 25.1.1 (i686-pc-linux-gnu, GTK+ Version 3.22.11) of 2017-09-15, modified by Debian

On 2018-10-30 at 14:39, Stefan Monnier wrote:
> All this pcase-dolist discussion made me take a second look at dolist
> and now I wondering whether we should keep it:

This is still extreme: I never saw anyone suggesting to remove anything
about pcase or its derivative… but I can get quite distracted sometimes
so maybe I missed it.  I think pattern-matching, though I’m not fond of
it, is sometimes necessary, and is a must-be in any high-level language,
and as pcase exists and is pretty used…

> Since it can only be used when we're 100% sure that LIST is a LIST,
> (and who can be sure of such a thing in a dynamic language like Emacs
> Lisp), I think we'd be better off deprecating it and changing all uses
> of dolist with a clear while+cdr loop that everyone can understand.

Before people spoke about sarcasm I really thought this all was serious
and first degree, about removing a such now idiomatic form from elisp,
that also exists in common lisp, to end suggesting such much lower level

Also I dislike `while': it looks pretty not lispy to me, very imperative
(but well all emacs and much lisp is imperative as well…)…  I’d rather
define `dolist' upon `mapc' than `while'.  And if something common and
simple as `dolist' was to be removed, I think I’d end up programming
like in scheme and use recursion everywhere (btw is emacs
tail-recursive?), so in the end that’d divide programming style between
`while' and recursion so all programs becomes half as readable as before
(except recursion-people are afaik more rare, so I’m going to be forced
in `while', and anyway it seems like in the end I made an argument in
favor of `pcase' and against `case' ><).

> - The docstring is incomprehensible:
>       Loop over a list.
>       Evaluate BODY with VAR bound to each car from LIST, in turn.
>       Then evaluate RESULT to get return value, default nil.
>   I don't know how to loop over a list.

I must say, that this seems true to me.  I regularely prefers recursion
or mapcar/mapc to dolist because they’re simpler and cleaner.  I recall
at a time, each time I realized I needed `dolist', I evaled a test using
it so to be sure I still knew how to properly use it.  Still today,
before writing it, it is unclear in my mind how I would use dolist to do
something (I have to say I find unnatural to repetedly use setq or use
side-effects (especially to set stuff) to achieve something).  Last time
I used `dolist', I first wanted to use recursion before someone noticed
me it was unnatural / strang / unidiomatic in elisp to do that, so I
needed dolist (or seq, which still seems more uncommon to me), while
what I wanted to do was simply to `reduce' composition (I got a list of
functions, I wanted to apply them all to a string, one upon the other:
so if there were a `compose' function, `reduce' it to a sequence of
functions upon a string).

>   Did they mean to set the cdr of the last element so it loops back to
>   the first element?

I have to say that, though it is closer to real, low-level, actual
meaning/behavior, and not difficult to grasp once you know what’s a
list, “to each element of LIST, in turn” would have been more simple to
read, parse (it is a syntactically simpler phrase), understand,
including for, but not limited to, newcomers.

>   "evaluate" is unclear (is it passed to `eval`?  Then why not say it?
>   What second arg is passed to `eval`?).  but why evaluate it several
>   times?  Also, in which order?  How does RESULT communicate the
>   return value?  Is it RESULT which defaults to nil or the return
>   value?  If the return value, then when does it default to nil?

Again I have to say “Then return RESULT evaluation, or nil if omitted.”
is simpler and more unambiguous.

> - The docstring says nothing of what happens when LIST is not a list,
>   yet a quick grep shows that most uses of dolist use for LIST a simple
>   variable rather than a list.  What gives?

a variable… returning a list, so being a list (the symbol is not a list,
but it doesn’t say it doesn’t evaluate the variable).

Again I have to say (this formulation is getting a little too much
redundant here and adding “again” is not hiding it well…) I find it is
true that `dolist' docstring is not explicit enough about what is
quoted, to quote, evaluated or not.  It no longer happens to me, but I
clearly recall having some pain about `dolist' in my first times I used
it, to understand what I needed to quote and what I needed to put as is…
and that required me several empirical tests to be sure: ideally a clear
docstring should spare you that.

Because there’s some inconstancy to explain there: VAR is not evaluated,
never, it *must* be a symbol as `read' would read it, not something
evaluating to a symbol, LIST is evaluated right away, and RESULT is too,
only once, and at the end.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]