* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
@ 2013-08-17 15:59 Drew Adams
2014-02-08 5:08 ` Lars Ingebrigtsen
0 siblings, 1 reply; 27+ messages in thread
From: Drew Adams @ 2013-08-17 15:59 UTC (permalink / raw)
To: 15117
These are motion functions, just like `goto-char' and
`skip-chars-forward'. Their doc should specify the return value
(regardless of whether it is a position, a Boolean, always nil, or
anything else).
If, for some special (good) reason, code should not rely on the return
value of some function then this fact should be stated explicitly in
the doc: "This function is used only for its side effects; the return
value is undefined." This is Lisp, not C - return values are the norm,
not the exception.
The doc of `(forward|backward)-(word|line)' already correctly specifies
the return value. Not so for other `(forward|backward)-*' functions,
such as `(forward|backward)-sexp'.
In GNU Emacs 24.3.50.1 (i686-pc-mingw32)
of 2013-08-07 on ODIEONE
Bzr revision: 113750 lekktu@gmail.com-20130808011911-0jzpc9xuncegg6x9
Windowing system distributor `Microsoft Corp.', version 6.1.7601
Configured using:
`configure --prefix=/c/Devel/emacs/binary --enable-checking=yes,glyphs
CFLAGS=-O0 -g3 LDFLAGS=-Lc:/Devel/emacs/lib
CPPFLAGS=-Ic:/Devel/emacs/include'
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2013-08-17 15:59 Drew Adams
@ 2014-02-08 5:08 ` Lars Ingebrigtsen
2014-02-10 0:12 ` Drew Adams
0 siblings, 1 reply; 27+ messages in thread
From: Lars Ingebrigtsen @ 2014-02-08 5:08 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117
Drew Adams <drew.adams@oracle.com> writes:
> These are motion functions, just like `goto-char' and
> `skip-chars-forward'. Their doc should specify the return value
> (regardless of whether it is a position, a Boolean, always nil, or
> anything else).
>
> If, for some special (good) reason, code should not rely on the return
> value of some function then this fact should be stated explicitly in
> the doc: "This function is used only for its side effects; the return
> value is undefined." This is Lisp, not C - return values are the norm,
> not the exception.
No, in Emacs we seldom say that. Functions used for side effect are
quite normal.
> The doc of `(forward|backward)-(word|line)' already correctly specifies
> the return value. Not so for other `(forward|backward)-*' functions,
> such as `(forward|backward)-sexp'.
They don't seem to return anything useful. Closing.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog http://lars.ingebrigtsen.no/
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-08 5:08 ` Lars Ingebrigtsen
@ 2014-02-10 0:12 ` Drew Adams
2014-02-10 2:39 ` Lars Ingebrigtsen
2014-02-10 16:27 ` Stefan Monnier
0 siblings, 2 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-10 0:12 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 15117
> > These are motion functions, just like `goto-char' and
> > `skip-chars-forward'. Their doc should specify the return value
> > (regardless of whether it is a position, a Boolean, always nil, or
> > anything else).
> >
> > If, for some special (good) reason,
What is that special, good reason?
> > code should not rely on the return value of some function then
> > this fact should be stated explicitly in the doc: "This function
> > is used only for its side effects; the return value is undefined."
> > This is Lisp, not C - return values are the norm,
> > not the exception.
>
> No, in Emacs we seldom say that. Functions used for side effect are
> quite normal.
Please _read_. No one said that side-effect functions are abnormal.
These are NOT side-effect functions. They modify nothing except
the cursor position. These are normal, ordinary, run-of-the-mill
motion functions. Their return values should be specified. We
do not proscribe users from using the return value of motion
functions, in general - quite the contrary.
> > The doc of `(forward|backward)-(word|line)' already correctly
> > specifies the return value. Not so for other
> > `(forward|backward)-*' functions, such as `(forward|backward)-sexp'.
>
> They don't seem to return anything useful. Closing.
Where do you get off saying that? Of course it is useful to
use the return value of a motion function. It saves a call to
`point', which can simplify the code. (Yes, simple and beautiful
is in the eye of the reader. But the point is that it is normal
for users to make use of the return value of a motion function
that is side-effect free. Reopening.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 0:12 ` Drew Adams
@ 2014-02-10 2:39 ` Lars Ingebrigtsen
2014-02-10 2:45 ` Drew Adams
2014-02-10 16:27 ` Stefan Monnier
1 sibling, 1 reply; 27+ messages in thread
From: Lars Ingebrigtsen @ 2014-02-10 2:39 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117
Drew Adams <drew.adams@oracle.com> writes:
>> They don't seem to return anything useful. Closing.
>
> Where do you get off saying that? Of course it is useful to
> use the return value of a motion function. It saves a call to
> `point', which can simplify the code. (Yes, simple and beautiful
> is in the eye of the reader. But the point is that it is normal
> for users to make use of the return value of a motion function
> that is side-effect free. Reopening.
If other developers disagree with my closing the bug, they can reopen.
Reclosing.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog http://lars.ingebrigtsen.no/
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 2:39 ` Lars Ingebrigtsen
@ 2014-02-10 2:45 ` Drew Adams
0 siblings, 0 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-10 2:45 UTC (permalink / raw)
To: Lars Ingebrigtsen; +Cc: 15117
> >> They don't seem to return anything useful. Closing.
> >
> > Where do you get off saying that? Of course it is useful to
> > use the return value of a motion function. It saves a call to
> > `point', which can simplify the code. (Yes, simple and beautiful
> > is in the eye of the reader. But the point is that it is normal
> > for users to make use of the return value of a motion function
> > that is side-effect free. Reopening.
>
> If other developers disagree with my closing the bug, they can
> reopen.
>
> Reclosing.
I already did disagree. This is quite ludicrous. Just how
do you think you are improving things by doing this?
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 0:12 ` Drew Adams
2014-02-10 2:39 ` Lars Ingebrigtsen
@ 2014-02-10 16:27 ` Stefan Monnier
2014-02-10 21:16 ` Drew Adams
1 sibling, 1 reply; 27+ messages in thread
From: Stefan Monnier @ 2014-02-10 16:27 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, Lars Ingebrigtsen
> These are NOT side-effect functions. They modify nothing except
> the cursor position.
How is that not a side-effect?
Stefan
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 16:27 ` Stefan Monnier
@ 2014-02-10 21:16 ` Drew Adams
2014-02-11 1:07 ` Dmitry Gutov
` (3 more replies)
0 siblings, 4 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-10 21:16 UTC (permalink / raw)
To: Stefan Monnier; +Cc: 15117, Lars Ingebrigtsen
> > These are NOT side-effect functions. They modify nothing except
> > the cursor position.
>
> How is that not a side-effect?
You are clearly arguing for the sake of arguing, now.
Everything in the universe has side effects. Ohhmmmm. It's true.
Motion functions are not what is typically meant by a side-effect
function. They do not change the contents of the buffer, for
example, in the sense of `buffer-modified-p'.
These functions are like `goto-char' and `skip-chars-forward', as
mentioned in the bug report. They are also like `forward-line',
another motion function whose return value we document. And
`beginning-of-defun' - another.
By your (newfound) logic, you will presumably remove mention of
the return value from the doc for those functions. The same
logic behind documenting their return value applies to these
other motion functions.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 21:16 ` Drew Adams
@ 2014-02-11 1:07 ` Dmitry Gutov
2014-02-11 6:40 ` Drew Adams
2014-02-11 1:28 ` Juanma Barranquero
` (2 subsequent siblings)
3 siblings, 1 reply; 27+ messages in thread
From: Dmitry Gutov @ 2014-02-11 1:07 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, Lars Ingebrigtsen
Drew Adams <drew.adams@oracle.com> writes:
> Everything in the universe has side effects. Ohhmmmm. It's true.
You should look up "referential transparency".
> Motion functions are not what is typically meant by a side-effect
> function. They do not change the contents of the buffer, for
> example, in the sense of `buffer-modified-p'.
Please read http://en.wikipedia.org/wiki/Side_effect_(computer_science)
"function with side effects" is a pretty well-defined term. A function
does not necessarily have to modify an Emacs buffer to be termed as
such.
> By your (newfound) logic, you will presumably remove mention of
> the return value from the doc for those functions. The same
> logic behind documenting their return value applies to these
> other motion functions.
The logic is simple: if the return value is documented, the caller
should be able to depend on it, and "undocumenting" it retroactively
isn't an option. As long as the return value is undocumented, but the
function can still be useful without it, it can stay that way
indefinitely.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 21:16 ` Drew Adams
2014-02-11 1:07 ` Dmitry Gutov
@ 2014-02-11 1:28 ` Juanma Barranquero
2014-02-11 6:43 ` Drew Adams
2014-02-11 2:52 ` Glenn Morris
2014-02-11 4:01 ` Stefan Monnier
3 siblings, 1 reply; 27+ messages in thread
From: Juanma Barranquero @ 2014-02-11 1:28 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, Lars Ingebrigtsen
On Mon, Feb 10, 2014 at 10:16 PM, Drew Adams <drew.adams@oracle.com> wrote:
> Motion functions are not what is typically meant by a side-effect
> function.
Why not? Functions intended to move the point are as prototypically
side-effect functions as you can get. That goto-char returns POSITION
is a moderately useful, but not-at-all necessary commodity. goto-char
moving the point as a side effect is its whole raison d'être.
> They do not change the contents of the buffer, for
> example, in the sense of `buffer-modified-p'.
Why would you restrict the definition of "side effects" to changing
the buffer? `recenter' has no documented return value, and does not
modify the buffer. Would you deny that it exists to recenter as a side
effect?
J
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 21:16 ` Drew Adams
2014-02-11 1:07 ` Dmitry Gutov
2014-02-11 1:28 ` Juanma Barranquero
@ 2014-02-11 2:52 ` Glenn Morris
2014-02-11 4:01 ` Stefan Monnier
3 siblings, 0 replies; 27+ messages in thread
From: Glenn Morris @ 2014-02-11 2:52 UTC (permalink / raw)
To: 15117
Drew Adams wrote:
> You are clearly arguing for the sake of arguing, now.
Oh, the irony.
>> If other developers disagree with my closing the bug, they can reopen.
> I already did disagree.
You are not an Emacs developer.
To those are who are, I would like to say this:
There are more open Emacs issues than we can ever hope to fix.
So I suggest being selective about which ones you try to deal with.
Getting sucked into long debates about trivia is not a productive use of
time.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-10 21:16 ` Drew Adams
` (2 preceding siblings ...)
2014-02-11 2:52 ` Glenn Morris
@ 2014-02-11 4:01 ` Stefan Monnier
2014-02-11 10:52 ` Andreas Röhler
3 siblings, 1 reply; 27+ messages in thread
From: Stefan Monnier @ 2014-02-11 4:01 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, Lars Ingebrigtsen
>> > These are NOT side-effect functions. They modify nothing except
>> > the cursor position.
>> How is that not a side-effect?
> You are clearly arguing for the sake of arguing, now.
Not at all.
> Motion functions are not what is typically meant by a side-effect
> function.
Says you. For me (and most definitions of side-effects I've ever seen),
a side-effecting function is something like a function where the calls
can't simply be replaced by their return value.
Stefan
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 1:07 ` Dmitry Gutov
@ 2014-02-11 6:40 ` Drew Adams
0 siblings, 0 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-11 6:40 UTC (permalink / raw)
To: Dmitry Gutov; +Cc: 15117, Lars Ingebrigtsen
> > Everything in the universe has side effects. Ohhmmmm. It's true.
>
> You should look up "referential transparency".
Perhaps you should give me the benefit of the doubt. I'm actually
well aware of referential transparency. That might even have been
the case before you uttered your first side-effect cry. ;-)
> Please read
> http://en.wikipedia.org/wiki/Side_effect_(computer_science)
Please spare me the comp-sci lesson. FYI, I was at the Santa Fe
graph-reduction workshop in 1986, discussing what would ultimately
become Haskell with John Hughes, Phil Wadler, Paul Hudak, and Simon
Peyton-Jones. That's only to assure you that I am somewhat at home
in this forest.
I've been a proponent of purely functional and logic programming
for over 30 years. And yet I have also enjoyed programming in
nasty old Lisp for the same period. ;-) Go figure.
> "function with side effects" is a pretty well-defined term. A
> function does not necessarily have to modify an Emacs buffer to
> be termed as such.
Cough, gag. Yes, indeed. I really did not mean to suggest
otherwise.
> > By your (newfound) logic, you will presumably remove mention of
> > the return value from the doc for those functions. The same
> > logic behind documenting their return value applies to these
> > other motion functions.
>
> The logic is simple:
So are you arguing that we should not document the return value
of those functions either? Meme combat.
> if the return value is documented, the caller should be able to
> depend on it,
Yes, that's the idea.
> and "undocumenting" it retroactively isn't an option. As long as
> the return value is undocumented, but the function can still be
> useful without it, it can stay that way indefinitely.
When have you ever seen Emacs Dev worry a lot about changing
something, let alone undocumenting a return value retroactively?
Let's not exaggerate.
Yes, the return value for these simple motion functions should be
documented, and thus users should be able to depend on it.
That is no more of a constraint on Emacs-Lisp implementors than
is letting users depend on the value of `point' when the function
is finished.
We are not designing a language standard that will be implemented
here and there around the world using different teams and different
technologies for different purposes for the next 100 years.
This is Emacs Lisp, not Common Lisp. Let's not get carried away.
And even Common Lisp defines return values for the vast majority
of its functions, whether or not they perform side effects.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 1:28 ` Juanma Barranquero
@ 2014-02-11 6:43 ` Drew Adams
2014-02-11 16:31 ` Eli Zaretskii
2014-02-11 17:36 ` Juanma Barranquero
0 siblings, 2 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-11 6:43 UTC (permalink / raw)
To: Juanma Barranquero; +Cc: 15117, Lars Ingebrigtsen
> > Motion functions are not what is typically meant by a
> > side-effect function.
In Emacs, in the sense of modifying buffer contents. That was
what I meant. No, I was not clear enough. But it doesn't really
matter. That is anyway *not* a criterion I use for whether a Lisp
function should have a defined and documented return value.
My criterion for that is just whether such a value is useful and
can be counted on. If so, then I say we should let users know that
they can count on it. Simple as that.
> Why not? Functions intended to move the point are as prototypically
> side-effect functions as you can get. That goto-char returns
> POSITION is a moderately useful, but not-at-all necessary commodity.
> goto-char moving the point as a side effect is its whole raison d'être.
Agreed; it is. And the resulting position is thus an important part
of its effect. And it is handy to use that value directly. It always
has been. There is nothing special about this. And nothing special
about `goto-char' or `skip-chars-forward' vs `forward-char'. That's
the point.
Are you arguing not to document `goto-char's return value, as well?
And so to discourage its use? After all, one doesn't need to depend
on it - it's certainly enough to depend on the side effect and then
call `point' to get the new position.
If so, go for it. Then what have you gained? Greater liberty
for the implementation to change? Bof. More readable code? Bof.
Code that is more functional or side-effect free? Certainly not.
> > They do not change the contents of the buffer, for
> > example, in the sense of `buffer-modified-p'.
>
> Why would you restrict the definition of "side effects" to
> changing the buffer?
I don't, actually. Whether something constitutes a "side effect"
is relative.
This is what I wrote, which engendered the current excitement:
If, for some special (good) reason, code should not rely on the
return value of some function, then this fact should be stated
explicitly in the doc: "This function is used only for its side
effects; the return value is undefined." This is Lisp, not C -
return values are the norm, not the exception.
I was suggesting boilerplate text similar to what we often write
for functions, such as `mapc', where we point out that the return
value is not to be relied on.
We mention side effects here because if the return value is not
to be depended on then what else is there, besides the side effect?
Nada. We let users know that side effects are (necessarily) the
"whole raison d'être" in that case.
That is precisely what the Common Lisp doc does, for example:
call attention to the relatively *few* cases where the return
value is *not* to be counted on. Lisps have always tended to
provide reasonable return values as a general rule. Regardless,
BTW, of whether a given function happens to perform side effects.
It is not because a function performs side effects that its
return value should not be counted on (and so documented).
It is because the return value of a given function should not
be counted on that it should not be documented (actually, it
should be documented that the return value cannot be counted
on). And such functions are therefore used for side effect only.
There are certain Common Lisp "functions" for which no return
value is documented, and which are _called out as such_,
explicitly. (And the doc typically says something like what
I said above: Use this for its side effects only; do not count
on its return value being anything in particular (it can vary
among implementations etc.)
Such functions are the exception to the rule - in spite of the
fact that most Common Lisp "functions" can have side effects.
And such an exception is often for reasons of implementation -
in particular, to allow different implementors more freedom of
implementation. (Common Lisp, unlike GNU Emacs, is intended
to have multiple implementations, including for unforeseen
situations and uses.)
So really the question has nothing particularly to do with side
effects, beyond the concerns just mentioned. I should not have
mentioned not-even-modifying-buffer-contents in this context.
It's all about what we want for programmers. Should they get
a useful return value for the given function or not? That's
the only question.
Consider `when', for instance. I, for one, adopt the convention
often used with Common Lisp of NOT using the return value. Why?
To signal the programmer intention that what is happening is for
the side effects and not for the return value - i.e., that in
that particular context, the return value is not important. IOW,
this is to help readers of the code; nothing more.
That convention makes sense for `when' and `unless' especially
because there are alternatives to signal just the opposite
programmer intention: I use `if', `and', or `or' when the
return value is significant, precisely to show that, for
readability.
If you were to argue that we should not document the return
value of `when' or `unless' you would get no argument from
me. (Well, actually, I would again suggest saying explicitly
that one should not count on the return value.)
This, in spite of the fact that `if', `and', and `or' can,
just like `when' and `unless', be used in code that produces
side effects. It's really not about side effects at all.
(I find it ironic that some of those who've jumped on this
to scream that programmers should not be able to count on
the return value of `forward-sexp' nevertheless count on
the return value of `when' in the code they write, something
I won't do.)
So I am not against documenting return values for some, even
most, functions that perform side effects, including effects
that might modify the buffer, if it can be shown that:
(a) there is no special benefit (e.g. wrt implementation or
for users) to *not* guaranteeing a known return value for
users or (b) there is no particularly useful value to return.
In the case of the motion functions, there is a useful value
to return: the destination position. And my question about
that is "Why not?". I've seen no response to that question,
so far. Why not?
> `recenter' has no documented return value, and does not
> modify the buffer. Would you deny that it exists to recenter
> as a side effect?
No more than I would deny that `goto-char' or `skip-chars-forward'
exists to move point. I don't see why that prohibits providing
the new `point' (or perhaps even the starting position) as a
useful return value, however.
I'm not sure the resulting position is particularly useful in
the case of `recenter', but if you proposed returning it and
documenting that, I might not object. Why not? I don't have
a great reason why not for `recenter' - do you?
Let's be clear. No one is proposing that additional side
effects be introduced anywhere here! This is not
pure-function-vs-procedure. These are all procedures.
They move point. The position attained is in most cases
a reasonable return value, and costs little or nothing to
return. So why not? That's all.
It is natural to return a value readily available from the
implementation. I would not propose that a definition go
out of its way to obtain a useful value to return in such
cases. But it seems obvious to me that there is no a priori
reason for a simple motion function *not* to return a known
value such as the position moved to.
I gave several examples of motion functions where we already
do that. Why do we? Why shouldn't we?
Look at those functions. See if you would really argue that
we should not document their return values and let users
depend on them. See if you want to shout "side effects!"
or some other battle cry as a reason for making such a change.
Then tell me what we would gain by that. Just what do we
gain by not returning the new position or not telling users
that we return it?
That's really the only question here. And I haven't heard a
single argument about that yet. Forget about whether this or
that function performs side effects. Please answer the
question of why we should not let users write code that
counts on the moved-to position as a return value.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 4:01 ` Stefan Monnier
@ 2014-02-11 10:52 ` Andreas Röhler
2014-02-11 11:16 ` Nicolas Richard
0 siblings, 1 reply; 27+ messages in thread
From: Andreas Röhler @ 2014-02-11 10:52 UTC (permalink / raw)
To: 15117
Am 11.02.2014 05:01, schrieb Stefan Monnier:
>>>> These are NOT side-effect functions. They modify nothing except
>>>> the cursor position.
>>> How is that not a side-effect?
>> You are clearly arguing for the sake of arguing, now.
>
> Not at all.
>
>> Motion functions are not what is typically meant by a side-effect
>> function.
>
> Says you. For me (and most definitions of side-effects I've ever seen),
> a side-effecting function is something like a function where the calls
> can't simply be replaced by their return value.
>
>
Can't see a logic link between a possible return value and the notion of side-effect.
It all depends from the purpose of the function.
Avoiding side-effects as a goal tries to avoid complexity.
While asking for (documented) return-values some times ago, being well aware these might constitute side-effects - but must not.
I.e. if a move-function reaches position, the buffer state is changed, but that's not a side effect, as it's the purpose.
If this function returns position for possibly receiving functions, would consider it a side-effect.
So if avoiding complexity is a goal, delivering a smart language is another one.
Not all side-effects are of same severity or same urgence to avoid.
Remains to decide. In case of move-functions, being in favor of returning position reached.
Documenting return-values is another --quite useful-- thing.
Cheers,
Andreas
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 10:52 ` Andreas Röhler
@ 2014-02-11 11:16 ` Nicolas Richard
2014-02-11 12:10 ` Andreas Röhler
0 siblings, 1 reply; 27+ messages in thread
From: Nicolas Richard @ 2014-02-11 11:16 UTC (permalink / raw)
To: Andreas Röhler; +Cc: 15117
Andreas Röhler <andreas.roehler@easy-emacs.de> writes:
> Am 11.02.2014 05:01, schrieb Stefan Monnier:
>> Says you. For me (and most definitions of side-effects I've ever seen),
>> a side-effecting function is something like a function where the calls
>> can't simply be replaced by their return value.
> Can't see a logic link between a possible return value and the notion of side-effect.
> It all depends from the purpose of the function.
I guess this is a slight misunderstanding. The notion of side-effect is
well defined in CS: « a function or expression is said to have a side
effect if, in addition to returning a value, it also modifies some state
or has an observable interaction with calling functions or the outside
world. »
(http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29)
The notions of "mostly-unintended effect" (like so: (defun
my-point-at-eol (progn (end-of-line) (point)))) or "multi-purpose
functions by means of global variables" (e.g. the use of 'org-ts-what in
org-at-timestamp-p -- which is kind of scary if I may say) are only
special cases of side effects.
--
Nico.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 11:16 ` Nicolas Richard
@ 2014-02-11 12:10 ` Andreas Röhler
0 siblings, 0 replies; 27+ messages in thread
From: Andreas Röhler @ 2014-02-11 12:10 UTC (permalink / raw)
To: Nicolas Richard; +Cc: 15117
Am 11.02.2014 12:16, schrieb Nicolas Richard:
> Andreas Röhler <andreas.roehler@easy-emacs.de> writes:
>> Am 11.02.2014 05:01, schrieb Stefan Monnier:
>>> Says you. For me (and most definitions of side-effects I've ever seen),
>>> a side-effecting function is something like a function where the calls
>>> can't simply be replaced by their return value.
>
>> Can't see a logic link between a possible return value and the notion of side-effect.
>> It all depends from the purpose of the function.
>
> I guess this is a slight misunderstanding. The notion of side-effect is
> well defined in CS: « a function or expression is said to have a side
> effect if, in addition to returning a value, it also modifies some state
> or has an observable interaction with calling functions or the outside
> world. »
> (http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29)
>
WP is often good, sometimes bad, sometimes just an agent of CIA, NSA and their satellites.
Saying in WP is no proof at all.
If you read "in addition to returning a value": functions must not return a value, but might have side-effects
> The notions of "mostly-unintended effect" (like so: (defun
> my-point-at-eol (progn (end-of-line) (point)))) or "multi-purpose
> functions by means of global variables" (e.g. the use of 'org-ts-what in
> org-at-timestamp-p -- which is kind of scary if I may say) are only
> special cases of side effects.
>
It's also not about unintended side-effect, also also about intended.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 6:43 ` Drew Adams
@ 2014-02-11 16:31 ` Eli Zaretskii
2014-02-11 17:29 ` Drew Adams
2014-02-11 17:36 ` Juanma Barranquero
1 sibling, 1 reply; 27+ messages in thread
From: Eli Zaretskii @ 2014-02-11 16:31 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, lekktu, larsi
> Date: Mon, 10 Feb 2014 22:43:08 -0800 (PST)
> From: Drew Adams <drew.adams@oracle.com>
> Cc: 15117@debbugs.gnu.org, Lars Ingebrigtsen <larsi@gnus.org>
>
> > > Motion functions are not what is typically meant by a
> > > side-effect function.
>
> In Emacs, in the sense of modifying buffer contents. That was
> what I meant. No, I was not clear enough. But it doesn't really
> matter. That is anyway *not* a criterion I use for whether a Lisp
> function should have a defined and documented return value.
>
> My criterion for that is just whether such a value is useful and
> can be counted on. If so, then I say we should let users know that
> they can count on it. Simple as that.
>
> > Why not? Functions intended to move the point are as prototypically
> > side-effect functions as you can get. That goto-char returns
> > POSITION is a moderately useful, but not-at-all necessary commodity.
> > goto-char moving the point as a side effect is its whole raison d'être.
>
> Agreed; it is. And the resulting position is thus an important part
> of its effect. And it is handy to use that value directly. It always
> has been. There is nothing special about this. And nothing special
> about `goto-char' or `skip-chars-forward' vs `forward-char'. That's
> the point.
With all due respect to the philosophical argument raging through this
thread, it has nothing at all to do with the original bug report.
If you (Drew) want that something productive comes out of this, please
point out specific forward/backward-* functions that return
non-trivial values, and those values are not documented. The only 2
functions mentioned since the beginning of this discussion are
forward/backward-sexp, which always return nil, a.k.a. "nothing". I
also tried a couple of other random functions, and they seem all to be
of this "nothing" kind. So I wonder whether we have any real problem
here.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 16:31 ` Eli Zaretskii
@ 2014-02-11 17:29 ` Drew Adams
2014-02-11 18:05 ` Eli Zaretskii
2014-02-11 18:42 ` Andreas Röhler
0 siblings, 2 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-11 17:29 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 15117, lekktu, larsi
> If you (Drew) want that something productive comes out of this,
> please point out specific forward/backward-* functions that return
> non-trivial values, and those values are not documented. The only 2
> functions mentioned since the beginning of this discussion are
> forward/backward-sexp, which always return nil, a.k.a. "nothing". I
> also tried a couple of other random functions, and they seem all to
> be of this "nothing" kind. So I wonder whether we have any real
> problem here.
I would like to see functions that are purely motion functions
return `point', the destination position, unless there is a more
useful return value (as is already the case for a function such as
`forward-comment' or `forward-button').
IOW, some useful value is better than none. Note: I have nothing
against picking a _more_ useful value than `point'. Point is just
a default suggestion. For an example of a more useful value, see
`forward-comment': it sets `point' but returns t or nil.
And document that return value. Here are some candidates, for a
start (likewise, their backward relatives, and other relatives,
such as `up-list', `down-list', `backward-up-list'...).
forward-char
forward-list ; already returns `point'
forward-page ; returns count
forward-same-syntax
forward-sentence
forward-sexp
forward-symbol
forward-thing
forward-to-indentation
forward-visible-line
forward-whitespace
forward-word
We can look for other motion functions to treat similarly after
this start. Assuming there is any will to do this.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 6:43 ` Drew Adams
2014-02-11 16:31 ` Eli Zaretskii
@ 2014-02-11 17:36 ` Juanma Barranquero
1 sibling, 0 replies; 27+ messages in thread
From: Juanma Barranquero @ 2014-02-11 17:36 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, Lars Ingebrigtsen
On Tue, Feb 11, 2014 at 7:43 AM, Drew Adams <drew.adams@oracle.com> wrote:
> That is anyway *not* a criterion I use for whether a Lisp
> function should have a defined and documented return value.
The only criteria that make sense IMHO about whether a function should
have a defined and documented return value are:
- That the return value is useful and non-trivial.
- That it is somewhat related to the function's purpose.
As an example, goto-char has a documented return value, POSITION,
identical to its only argument. I suppose it is so for historical
reasons and I'm not proposing to undocument it, but if goto-char were
introduced now, I would, because the only thing you gain from it is
saving a `let' binding every now and then (perhaps 100 times out of
~12,000 calls to goto-char in the sources).
> Agreed; it is. And the resulting position is thus an important part
> of its effect. And it is handy to use that value directly.
The result of goto-char is NOT "the resulting position". Try
(with-temp-buffer (goto-char 1000)) => 1000
or
(let ((p (point-marker))) (eq p (goto-char p))) => t
The result of goto-char is *its argument*, even if it does not make sense.
> Are you arguing not to document `goto-char's return value, as well?
> And so to discourage its use? After all, one doesn't need to depend
> on it - it's certainly enough to depend on the side effect and then
> call `point' to get the new position.
As said above, I would, if it were a new function, yes.
> If so, go for it. Then what have you gained? Greater liberty
> for the implementation to change? Bof. More readable code? Bof.
Your "bof" is my "hell, yeah".
> Code that is more functional or side-effect free? Certainly not.
I wouldn't presume to make a side-effect function side-effect free.
That'd be weird ;-)
> Whether something constitutes a "side effect"
> is relative.
I don't think so.
> If, for some special (good) reason, code should not rely on the
> return value of some function, then this fact should be stated
> explicitly in the doc: "This function is used only for its side
> effects; the return value is undefined." This is Lisp, not C -
> return values are the norm, not the exception.
Not documenting a return value is, in fact, a way of saying "this
function is used only for its side effects; the return value is
undefined". It's just that it is a way of saying it that you dislike,
but it has a long history.
> It is not because a function performs side effects that its
> return value should not be counted on (and so documented).
No, it is because it is trivial, or irrelevant, or an accident of
implementation.
> It's all about what we want for programmers. Should they get
> a useful return value for the given function or not? That's
> the only question.
The answer to that question is already there: some do (return a useful
value), some don't. What you're saying instead is that, in your
opinion, *most* functions should have its return value documented,
because that's more "lispy". But Elisp is not just a lisp, it's the
high-level implementation language of a text editor, and as such,
there are many functions intended to produce side effects in the text;
that they return a value is a consequence of these functions being
implemented in lisp, which does not have a concept of not returning
anything at all.
> Consider `when', for instance. I, for one, adopt the convention
> often used with Common Lisp of NOT using the return value. Why?
> To signal the programmer intention that what is happening is for
> the side effects and not for the return value - i.e., that in
> that particular context, the return value is not important. IOW,
> this is to help readers of the code; nothing more.
I do, too. But in fact, I think that function is an argument for my
position, not yours, exactly because of this:
> If you were to argue that we should not document the return
> value of `when' or `unless' you would get no argument from
> me. (Well, actually, I would again suggest saying explicitly
> that one should not count on the return value.)
Exactly. I would prefer that `when' and `unless' had their return
values undefined, and people had to use (if X Y nil) or (if X nil Y).
> In the case of the motion functions, there is a useful value
> to return: the destination position. And my question about
> that is "Why not?". I've seen no response to that question,
> so far. Why not?
See above. If the function is moving the point in a non trivial way,
it makes sense to return the new position. If not, not. There's
nothing special about motion functions.
> I'm not sure the resulting position is particularly useful in
> the case of `recenter', but if you proposed returning it and
> documenting that, I might not object. Why not? I don't have
> a great reason why not for `recenter' - do you?
recenter does not move the point. It could return `point', but, what for?
> Look at those functions. See if you would really argue that
> we should not document their return values and let users
> depend on them. See if you want to shout "side effects!"
> or some other battle cry as a reason for making such a change.
Drew, I didn't enter the discussion to defend function purity, just to
try to understand why did you define obvious side-effects as "no side
effects". That said, I do think that in many cases documenting the
return value has as a net negative effect in that it does not add
value and limits implementation. But there's nothing new there, we've
had this discussion before.
> Please answer the
> question of why we should not let users write code that
> counts on the moved-to position as a return value.
I think it is a good idea to encourage the users to use functions that
return the position as their *main* effect.
J
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 17:29 ` Drew Adams
@ 2014-02-11 18:05 ` Eli Zaretskii
2014-02-11 18:42 ` Andreas Röhler
1 sibling, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2014-02-11 18:05 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, lekktu, larsi
> Date: Tue, 11 Feb 2014 09:29:24 -0800 (PST)
> From: Drew Adams <drew.adams@oracle.com>
> Cc: lekktu@gmail.com, 15117@debbugs.gnu.org, larsi@gnus.org
>
> I would like to see functions that are purely motion functions
> return `point', the destination position, unless there is a more
> useful return value (as is already the case for a function such as
> `forward-comment' or `forward-button').
That's a different issue: you are asking to change the functions
rather than to document what they currently do. Let's stay with the
latter.
> And document that return value. Here are some candidates, for a
> start (likewise, their backward relatives, and other relatives,
> such as `up-list', `down-list', `backward-up-list'...).
>
> forward-char
Returns nil, so I don't see what is there to document.
> forward-list ; already returns `point'
> forward-page ; returns count
Returns nil, not count.
> forward-same-syntax
Returns nil.
> forward-sentence
> forward-sexp
Returns nil.
> forward-symbol
> forward-thing
Always returns t, so not interesting.
> forward-to-indentation
The value is random, so not interesting
> forward-visible-line
Always nil.
> forward-whitespace
> forward-word
Value is documented.
Looks like only 4 functions of the list return something non-trivial.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
[not found] ` <<8338jpttic.fsf@gnu.org>
@ 2014-02-11 18:14 ` Drew Adams
2014-02-11 18:17 ` Eli Zaretskii
[not found] ` <<5889df4e-4343-4136-ae49-4062659da625@default>
1 sibling, 1 reply; 27+ messages in thread
From: Drew Adams @ 2014-02-11 18:14 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 15117, lekktu, larsi
> Looks like only 4 functions of the list return something non-
> trivial.
1. So fix those four functions, as a start. Plus their backward
etc. relatives - that brings it to 8 + 3 = 11 functions (including
*-list).
And if you look, you will find others. `forward-*' are not the
only motion functions.
2. I guess you want a separate bug report for fixing the other
functions themselves, so they return something useful.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 18:14 ` bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value Drew Adams
@ 2014-02-11 18:17 ` Eli Zaretskii
0 siblings, 0 replies; 27+ messages in thread
From: Eli Zaretskii @ 2014-02-11 18:17 UTC (permalink / raw)
To: Drew Adams; +Cc: 15117, lekktu, larsi
> Date: Tue, 11 Feb 2014 10:14:26 -0800 (PST)
> From: Drew Adams <drew.adams@oracle.com>
> Cc: lekktu@gmail.com, 15117@debbugs.gnu.org, larsi@gnus.org
>
> 2. I guess you want a separate bug report for fixing the other
> functions themselves, so they return something useful.
It deserves a separate discussion, but I'm not sure their current
non-values constitute a bug. There's nothing wrong in returning nil.
In any case, each function should be discussed separately, because the
fact that the name starts with "forward-" says nothing about possible
useful values it could return.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
[not found] ` <<831tz9tsy2.fsf@gnu.org>
@ 2014-02-11 18:26 ` Drew Adams
0 siblings, 0 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-11 18:26 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 15117, lekktu, larsi
> > 2. I guess you want a separate bug report for fixing the other
> > functions themselves, so they return something useful.
>
> It deserves a separate discussion, but I'm not sure their current
> non-values constitute a bug. There's nothing wrong in returning
> nil.
It's an enhancement request - or it will be: Return a useful value
when possible, for motion functions.
> In any case, each function should be discussed separately, because
> the fact that the name starts with "forward-" says nothing about
> possible useful values it could return.
The set of candidate functions for enhancement are motion functions.
Yes, each needs to be checked in detail. That should not mean that
a separate enhancement request is needed for each function.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 17:29 ` Drew Adams
2014-02-11 18:05 ` Eli Zaretskii
@ 2014-02-11 18:42 ` Andreas Röhler
2014-02-11 18:58 ` Eli Zaretskii
1 sibling, 1 reply; 27+ messages in thread
From: Andreas Röhler @ 2014-02-11 18:42 UTC (permalink / raw)
To: 15117
Am 11.02.2014 18:29, schrieb Drew Adams:
>> If you (Drew) want that something productive comes out of this,
>> please point out specific forward/backward-* functions that return
>> non-trivial values, and those values are not documented. The only 2
>> functions mentioned since the beginning of this discussion are
>> forward/backward-sexp, which always return nil, a.k.a. "nothing". I
>> also tried a couple of other random functions, and they seem all to
>> be of this "nothing" kind. So I wonder whether we have any real
>> problem here.
>
> I would like to see functions that are purely motion functions
> return `point', the destination position, unless there is a more
> useful return value (as is already the case for a function such as
> `forward-comment' or `forward-button').
>
> IOW, some useful value is better than none. Note: I have nothing
> against picking a _more_ useful value than `point'. Point is just
> a default suggestion. For an example of a more useful value, see
> `forward-comment': it sets `point' but returns t or nil.
IMO these functions should return point if successful, i.e. if point was moved, but nil otherwise, for example at EOB.
As point --a number-- evals to `t', a respective check might be set upon from receiving function.
>
> And document that return value. Here are some candidates, for a
> start (likewise, their backward relatives, and other relatives,
> such as `up-list', `down-list', `backward-up-list'...).
>
> forward-char
> forward-list ; already returns `point'
> forward-page ; returns count
> forward-same-syntax
> forward-sentence
> forward-sexp
> forward-symbol
> forward-thing
> forward-to-indentation
> forward-visible-line
> forward-whitespace
> forward-word
>
> We can look for other motion functions to treat similarly after
> this start. Assuming there is any will to do this.
>
>
>
>
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 18:42 ` Andreas Röhler
@ 2014-02-11 18:58 ` Eli Zaretskii
2014-02-11 19:13 ` Drew Adams
2014-02-11 19:26 ` Andreas Röhler
0 siblings, 2 replies; 27+ messages in thread
From: Eli Zaretskii @ 2014-02-11 18:58 UTC (permalink / raw)
To: Andreas Röhler; +Cc: 15117
> Date: Tue, 11 Feb 2014 19:42:52 +0100
> From: Andreas Röhler <andreas.roehler@easy-emacs.de>
>
> IMO these functions should return point if successful, i.e. if point was moved, but nil otherwise, for example at EOB.
Why point? E.g., forward-to-indentation could returns the column
where it ended up, forward-same-syntax could return the syntax class,
forward-visible-line could return the number of screen lines
traversed, etc.
Once again, the potentially useful value might well be different for
each function, and needs to be considered separately for each.
There's no "one fits all" here.
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 18:58 ` Eli Zaretskii
@ 2014-02-11 19:13 ` Drew Adams
2014-02-11 19:26 ` Andreas Röhler
1 sibling, 0 replies; 27+ messages in thread
From: Drew Adams @ 2014-02-11 19:13 UTC (permalink / raw)
To: Eli Zaretskii, Andreas Röhler; +Cc: 15117
> > IMO these functions should return point if successful, i.e. if
> > point was moved, but nil otherwise, for example at EOB.
>
> Why point? E.g., forward-to-indentation could returns the column
> where it ended up, forward-same-syntax could return the syntax
> class, forward-visible-line could return the number of screen lines
> traversed, etc.
>
> Once again, the potentially useful value might well be different for
> each function, and needs to be considered separately for each.
> There's no "one fits all" here.
I agree 100%, and said the same thing earlier. Point is likely a
reasonable value for some functions, for which there is no more
useful value. But we should think carefully about each function,
especially in terms of its common use case(s).
^ permalink raw reply [flat|nested] 27+ messages in thread
* bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value
2014-02-11 18:58 ` Eli Zaretskii
2014-02-11 19:13 ` Drew Adams
@ 2014-02-11 19:26 ` Andreas Röhler
1 sibling, 0 replies; 27+ messages in thread
From: Andreas Röhler @ 2014-02-11 19:26 UTC (permalink / raw)
To: Eli Zaretskii; +Cc: 15117
Am 11.02.2014 19:58, schrieb Eli Zaretskii:
>> Date: Tue, 11 Feb 2014 19:42:52 +0100
>> From: Andreas Röhler <andreas.roehler@easy-emacs.de>
>>
>> IMO these functions should return point if successful, i.e. if point was moved, but nil otherwise, for example at EOB.
>
> Why point? E.g., forward-to-indentation could returns the column
> where it ended up, forward-same-syntax could return the syntax class,
> forward-visible-line could return the number of screen lines
> traversed, etc.
>
> Once again, the potentially useful value might well be different for
> each function, and needs to be considered separately for each.
> There's no "one fits all" here.
>
>
Agreed. Saying "these" was a way too general.
^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2014-02-11 19:26 UTC | newest]
Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <<1dc76f7a-5481-41df-b976-ec22229d7283@default>
[not found] ` <<874n4a42f0.fsf@building.gnus.org>
[not found] ` <<1281d0fd-77cb-45e2-b99d-f4ad24b0fc4e@default>
[not found] ` <<jwvr47b3pcw.fsf-monnier+emacsbugs@gnu.org>
[not found] ` <<2fefcbaf-9417-4f57-93af-490ea73aea98@default>
[not found] ` <<CAAeL0SRYdnYryaVzADc5L61vgM0EPQeBzG2h327YynitS18tXA@mail.gmail.com>
[not found] ` <<68a64949-d801-4d09-8dc8-4b6ae0824855@default>
[not found] ` <<8361oltxu1.fsf@gnu.org>
[not found] ` <<67b917ca-8b69-49fd-9e12-68da310f7567@default>
[not found] ` <<8338jpttic.fsf@gnu.org>
2014-02-11 18:14 ` bug#15117: 24.3.50; doc of `(forward|backward)-*': state return value Drew Adams
2014-02-11 18:17 ` Eli Zaretskii
[not found] ` <<5889df4e-4343-4136-ae49-4062659da625@default>
[not found] ` <<831tz9tsy2.fsf@gnu.org>
2014-02-11 18:26 ` Drew Adams
2013-08-17 15:59 Drew Adams
2014-02-08 5:08 ` Lars Ingebrigtsen
2014-02-10 0:12 ` Drew Adams
2014-02-10 2:39 ` Lars Ingebrigtsen
2014-02-10 2:45 ` Drew Adams
2014-02-10 16:27 ` Stefan Monnier
2014-02-10 21:16 ` Drew Adams
2014-02-11 1:07 ` Dmitry Gutov
2014-02-11 6:40 ` Drew Adams
2014-02-11 1:28 ` Juanma Barranquero
2014-02-11 6:43 ` Drew Adams
2014-02-11 16:31 ` Eli Zaretskii
2014-02-11 17:29 ` Drew Adams
2014-02-11 18:05 ` Eli Zaretskii
2014-02-11 18:42 ` Andreas Röhler
2014-02-11 18:58 ` Eli Zaretskii
2014-02-11 19:13 ` Drew Adams
2014-02-11 19:26 ` Andreas Röhler
2014-02-11 17:36 ` Juanma Barranquero
2014-02-11 2:52 ` Glenn Morris
2014-02-11 4:01 ` Stefan Monnier
2014-02-11 10:52 ` Andreas Röhler
2014-02-11 11:16 ` Nicolas Richard
2014-02-11 12:10 ` Andreas Röhler
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).