2

Why does Elisp (member '3 '(1 2 3 4 5 6)) return (3 4 5 6) instead of t (true) or 3, or (3)?

I see the utility of a function to return the remainder/tail of an ordered list starting from, and including the delimiter element.

But why have it as a "side-effect" to the function for checking existence in a set?

Ever since I first read about member, I wondered about this, but quietly accepted. Now recently this topic came up, and I have a few ideas, like this being about keeping the number of C-primitives low by adding semantics to the non-false return values? Or is it a "hold-over" from the math paper(s) all of Lisp derived from? Or something else? Is there a (definitive) source out there?

4 Answers 4

6

This is a general Lisp question - a question about Lisp lists. It is not special to Emacs Lisp.

The answers you are getting are all correct, and they say the same thing, so far. You apparently don't want to hear the answer. ;-) And no, they are not just rephrasing your question.

The answer is, as others have said, that the return value is useful beyond its use as a Boolean indication of membership.

Consider, for example, that by returning that tail it tells you also how far from the end of the list the member is.

And it provides an actual tail of the list argument - same list, which is important when you are dealing with list structure (not copies of lists). For example

(setq foo  '(1 2 3 4 5 6))
(setcdr (member 3 foo) '(8 9 42))

Now foo is (1 2 3 8 9 42).

Remember too that what is returned is essentially a pointer - the cost is negligible.

6
  • This is information I was missing! The fact, that I get a pointer, and not a copy of the tail. Dec 17, 2016 at 23:02
  • This is typical. Documentation will usually make it clear if a list is being copied.
    – phils
    Dec 18, 2016 at 0:18
  • Lisp is neither call-by-value nor call-by-reference. It generally returns pointers to objects, and those pointers are implicit - dereferenced automatically. (Even speaking that way is not a good way to describe it.) Lisp is different.
    – Drew
    Dec 18, 2016 at 2:05
  • Sorry Drew, but Elisp is very much call-by-value and not call-by-reference. Structured values have a "reference" semantic, tho, indeed.
    – Stefan
    Dec 18, 2016 at 14:38
  • @Stefan: It depends what you mean by call-by-value. Lisp behavior is not what most people expect or are used to as call-by-value. Precisely because of that "'reference' semantic".
    – Drew
    Dec 18, 2016 at 17:19
3

I wasn't in their head when the original coders of those Lisp primitives made this choice, but my guess is that it seemed like the most useful non-nil value to return among those that were available without doing any extra work.

IOW somewhere along the lines of "keeping the number of C-primitives low by adding semantics to the non-false return values", except that it's not just the number of primitives but also the overall efficiency of the programs.

3
  • I thought something like that too, but then why not return position in the list? Dec 17, 2016 at 22:53
  • 2
    Because that would be slightly more work, and probably less useful?
    – phils
    Dec 18, 2016 at 0:32
  • 2
    Not to mention that member works on circular lists, where position isn't very useful (plus, you already have position function). I'd imagine Stefan's answer to be at least very close to the truth: it's unlikely there was a grand design for the return value. Just an implementation detail that became a tradition.
    – wvxvw
    Dec 18, 2016 at 7:23
2

It's not a side effect, it's the return value of the function.

Every function returns something. In elisp, every non-nil value (and (eq nil '()) returns t) is treated as a boolean true. So rather than suppress information by returning t, the function gives you the list from the matching element on, which you are free to use or discard as you see fit.

0
1

Every non-nil value in elisp is true, and it might be useful to just return the list starting at the matching value.

1
  • This answers just puts my question into different words. And member has to include the searched element in the result list, otherwise the return value would be ambiguous, if the search key were the last element in the list. Dec 17, 2016 at 21:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.