* Re: seq-some-p and nil
2015-09-07 15:19 ` Stefan Monnier
@ 2015-09-07 15:23 ` Mark Oteiza
2015-09-07 17:08 ` Drew Adams
` (2 subsequent siblings)
3 siblings, 0 replies; 54+ messages in thread
From: Mark Oteiza @ 2015-09-07 15:23 UTC (permalink / raw)
To: emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> If the function is not supposed to return non-nil if an element is
>>> matched but the element itself, then would it be ok? OTOH there would be
>>> again no way to differentiate between no element found and nil being
>>> found in the sequence.
>
> Returning what FUN returned seems like a better choice.
>
> If you need the element matched, then you can simply arrange for FUN
> to return the element.
Or have a function which returns the matching ELT and have seq-some and
friends use said function and apply PRED to its return value.
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-07 15:19 ` Stefan Monnier
2015-09-07 15:23 ` Mark Oteiza
@ 2015-09-07 17:08 ` Drew Adams
2015-09-07 20:44 ` Nicolas Petton
2015-09-07 20:45 ` Nicolas Petton
3 siblings, 0 replies; 54+ messages in thread
From: Drew Adams @ 2015-09-07 17:08 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, emacs-devel
> >> If the function is not supposed to return non-nil if an element is
> >> matched but the element itself, then would it be ok? OTOH there would be
> >> again no way to differentiate between no element found and nil being
> >> found in the sequence.
>
> Returning what FUN returned seems like a better choice.
> If you need the element matched, then you can simply arrange for FUN
> to return the element.
Sure, and that is the choice that Common Lisp made:
CL `some' looks only for non-nil sequence elements. However:
1. It is common to have existing predicates that you can reuse,
and that design makes you wrap them with a lambda, if you want
to return the element: (lambda (x) (and (arrayp x) x) versus
just arrayp. (A minor point, admittedly.)
And IF we want to let `seq-some' also find a nil sequence element:
2. If you "arrange for FUN to return the element", and if the
element found is nil (the problem you raised), the calling code
still cannot tell whether or not predicate FUN has been satisfied
by that element. You would need to then retest the return value
using the bare, underlying predicate that FUN wraps.
IOW, such a design is OK if all you ever care about is finding
a non-nil match, but not if you want to be sure there are no
matches (including no matches of nil).
3. The name of the function suggests that it returns an element
of the sequence: some element that satisfies the predicate.
Nothing in the name suggests that it returns what the function
returns. (Another point that is minor.)
4. This is another reason that `member' & compagnie return a
cons and not just the element that is a member: distinguish
a find of nil from no find.
It means that `member' can be used as a general "presence"
predicate, whereas, say, `get' cannot (as it does not
distinguish the presence of a nil property value from the
absence of the property).
The typical way to distinguish nil as the thing found from
not finding anything is to wrap the thing found in a cons.
And if it is sometimes useful to get the value that FUN
returns then both that value and the element that satisfies
FUN can be returned in a cons: (ELEMENT . VALUE).
The first question to ask here is the one suggested in the
Subject line: Do we want `seq-some' to find a nil sequence
element?
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-07 15:19 ` Stefan Monnier
2015-09-07 15:23 ` Mark Oteiza
2015-09-07 17:08 ` Drew Adams
@ 2015-09-07 20:44 ` Nicolas Petton
2015-09-07 22:27 ` Stefan Monnier
2015-09-07 20:45 ` Nicolas Petton
3 siblings, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-07 20:44 UTC (permalink / raw)
To: Stefan Monnier, Drew Adams; +Cc: Mark Oteiza, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1153 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> If the function is not supposed to return non-nil if an element is
>>> matched but the element itself, then would it be ok? OTOH there would be
>>> again no way to differentiate between no element found and nil being
>>> found in the sequence.
>
> Returning what FUN returned seems like a better choice.
>
> If you need the element matched, then you can simply arrange for FUN
> to return the element.
There is a misunderstanding here I think.
The way I see it, they are two different functions: the (new) seq-some,
and this other function that is now missing in seq, with the new
implementation of `seq-some'.
This new function would be used to find an element in a seq using a
predicate. CL has `find-if,' Scheme has `find', Clojure has `some',
Smalltalk has `detect:', etc.
Also, both the CL and scheme versions have the nil value ambiguity, but
since these functions are not supposed to return the logical truth on a
match, it is in my opinion fine.
I think I could name this function `seq-find'.
Cheers,
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-07 20:44 ` Nicolas Petton
@ 2015-09-07 22:27 ` Stefan Monnier
2015-09-08 7:09 ` Nicolas Petton
0 siblings, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-07 22:27 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Mark Oteiza, Drew Adams, emacs-devel
>> Returning what FUN returned seems like a better choice.
>> If you need the element matched, then you can simply arrange for FUN
>> to return the element.
> There is a misunderstanding here I think.
> The way I see it, they are two different functions: the (new) seq-some,
> and this other function that is now missing in seq, with the new
> implementation of `seq-some'.
I don't think so. Both functions can be one and the same.
If you really want seq-find, you can define it as
(defun seq-find (pred seq)
(seq-some (lambda (x) (and (funcall pred x) x)) seq))
But I'm far from convinced it's worth having them both,
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-07 22:27 ` Stefan Monnier
@ 2015-09-08 7:09 ` Nicolas Petton
2015-09-08 12:36 ` Stefan Monnier
0 siblings, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-08 7:09 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Drew Adams, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> Returning what FUN returned seems like a better choice.
>>> If you need the element matched, then you can simply arrange for FUN
>>> to return the element.
>> There is a misunderstanding here I think.
>> The way I see it, they are two different functions: the (new) seq-some,
>> and this other function that is now missing in seq, with the new
>> implementation of `seq-some'.
>
> I don't think so. Both functions can be one and the same.
> If you really want seq-find, you can define it as
>
> (defun seq-find (pred seq)
> (seq-some (lambda (x) (and (funcall pred x) x)) seq))
>
> But I'm far from convinced it's worth having them both,
Can you elaborate on why you think it's not worth it?
IMO, finding an element in a sequence is a very common operation, and to
do that now with `seq-some' one would have to add extra code to the
lambda each time, which I find cumbersome, but more importantly is not
very good in terms of code reuse.
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 7:09 ` Nicolas Petton
@ 2015-09-08 12:36 ` Stefan Monnier
2015-09-08 13:07 ` Nicolas Petton
2015-09-08 13:21 ` Nicolas Petton
0 siblings, 2 replies; 54+ messages in thread
From: Stefan Monnier @ 2015-09-08 12:36 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Mark Oteiza, Drew Adams, emacs-devel
> Can you elaborate on why you think it's not worth it?
> IMO, finding an element in a sequence is a very common operation,
Conceptually, yes, but if you take into account the details of how you
specify which element you want, as well as what you want to do with it,
then in most cases, I think the code ends up just as simple with
seq-some as with seq-find.
And using seq-some doesn't have the weird nil corner case.
And defining seq-find as I did means it's always less efficient.
And defining seq-find more efficiently means code duplication.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 12:36 ` Stefan Monnier
@ 2015-09-08 13:07 ` Nicolas Petton
2015-09-08 16:49 ` Stefan Monnier
2015-09-08 13:21 ` Nicolas Petton
1 sibling, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-08 13:07 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Drew Adams, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 996 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>> Can you elaborate on why you think it's not worth it?
>
>> IMO, finding an element in a sequence is a very common operation,
>
> Conceptually, yes, but if you take into account the details of how you
> specify which element you want, as well as what you want to do with it,
> then in most cases, I think the code ends up just as simple with
> seq-some as with seq-find.
I don't follow. How can the code end up just as simple when finding an
element matching a predicate?
To make things easier to understand, I'm taking the example of finding
the first odd number in a seq:
(seq-some (lambda (elt) (and (oddp elt) elt))
'(0 1 2 3))
(seq-find #'oddp '(0 1 2 3))
The first version is not only much harder to read, it also IMO shows
that the lambda mostly re-implement what a `seq-find' function should
provide by default in the library.
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 13:07 ` Nicolas Petton
@ 2015-09-08 16:49 ` Stefan Monnier
2015-09-08 17:01 ` David Kastrup
2015-09-08 18:59 ` Nicolas Petton
0 siblings, 2 replies; 54+ messages in thread
From: Stefan Monnier @ 2015-09-08 16:49 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Mark Oteiza, Drew Adams, emacs-devel
>> then in most cases, I think the code ends up just as simple with
>> seq-some as with seq-find.
[...]
> To make things easier to understand, I'm taking the example of finding
> the first odd number in a seq:
I've never needed to do that.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 16:49 ` Stefan Monnier
@ 2015-09-08 17:01 ` David Kastrup
2015-09-08 17:08 ` Drew Adams
2015-09-08 18:43 ` Stefan Monnier
2015-09-08 18:59 ` Nicolas Petton
1 sibling, 2 replies; 54+ messages in thread
From: David Kastrup @ 2015-09-08 17:01 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, Drew Adams, emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> then in most cases, I think the code ends up just as simple with
>>> seq-some as with seq-find.
> [...]
>> To make things easier to understand, I'm taking the example of finding
>> the first odd number in a seq:
>
> I've never needed to do that.
Marvelous.
--
David Kastrup
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-08 17:01 ` David Kastrup
@ 2015-09-08 17:08 ` Drew Adams
2015-09-08 19:02 ` Nicolas Petton
2015-09-08 18:43 ` Stefan Monnier
1 sibling, 1 reply; 54+ messages in thread
From: Drew Adams @ 2015-09-08 17:08 UTC (permalink / raw)
To: David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, emacs-devel
> >> To make things easier to understand, I'm taking the example of finding
> >> the first odd number in a seq:
> >
> > I've never needed to do that.
>
> Marvelous.
;-)
Was there something wrong with the suggestion to return,
as the non-nil value, a cons (ELEMENT . VALUE)?
(Where ELEMENT is the sequence element that satisfies the
predicate, and VALUE is the return value of the predicate
for that element.)
That gives you "some" element that satisfies the predicate
(the first such). And it gives you the result of the test.
Each of these can be useful, depending on the context.
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-08 17:08 ` Drew Adams
@ 2015-09-08 19:02 ` Nicolas Petton
2015-09-08 19:48 ` Drew Adams
0 siblings, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-08 19:02 UTC (permalink / raw)
To: Drew Adams, David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 917 bytes --]
Drew Adams <drew.adams@oracle.com> writes:
>> >> To make things easier to understand, I'm taking the example of finding
>> >> the first odd number in a seq:
>> >
>> > I've never needed to do that.
>>
>> Marvelous.
>
> ;-)
>
> Was there something wrong with the suggestion to return,
> as the non-nil value, a cons (ELEMENT . VALUE)?
>
> (Where ELEMENT is the sequence element that satisfies the
> predicate, and VALUE is the return value of the predicate
> for that element.)
>
> That gives you "some" element that satisfies the predicate
> (the first such). And it gives you the result of the test.
> Each of these can be useful, depending on the context.
It would work, and I believe Scheme has a similar function, but I don't
want seq-some to have this extra complexity. It could be another
function though, just like in Scheme.
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-08 19:02 ` Nicolas Petton
@ 2015-09-08 19:48 ` Drew Adams
2015-09-09 7:56 ` Nicolas Petton
0 siblings, 1 reply; 54+ messages in thread
From: Drew Adams @ 2015-09-08 19:48 UTC (permalink / raw)
To: Nicolas Petton, David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, emacs-devel
> > Was there something wrong with the suggestion to return,
> > as the non-nil value, a cons (ELEMENT . VALUE)?
> >
> > (Where ELEMENT is the sequence element that satisfies the
> > predicate, and VALUE is the return value of the predicate
> > for that element.)
> >
> > That gives you "some" element that satisfies the predicate
> > (the first such). And it gives you the result of the test.
> > Each of these can be useful, depending on the context.
>
> It would work, and I believe Scheme has a similar function, but I don't
> want seq-some to have this extra complexity. It could be another
> function though, just like in Scheme.
What extra complexity? It creates one cons cell which has as its
car and cdr things that presumably already exist.
I realize you are dealing with general sequences, and that the
sequence code can be complex, but the cons part of it, as the return
value, should be simple, no? Isn't it true for all sequence types
supported, that the car and cdr will exist after the predicate is
called, and so they can just be pointed to by the cons?
For lists only, this is what I use, FWIW:
(defun zz-some (predicate list)
"Return non-nil if PREDICATE applied to some element of LIST is true.
The value returned is a cons, (ELEMENT . VALUE), where ELEMENT is the
first list element that satisfies PREDICATE and VALUE is the value of
PREDICATE applied to ELEMENT."
(let (elt val)
(catch 'zz-some
(while list
(when (setq val (funcall predicate (setq elt (pop list))))
(throw 'zz-some (cons elt val))))
nil)))
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-08 19:48 ` Drew Adams
@ 2015-09-09 7:56 ` Nicolas Petton
2015-09-09 13:26 ` Drew Adams
0 siblings, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-09 7:56 UTC (permalink / raw)
To: Drew Adams, David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1079 bytes --]
Drew Adams <drew.adams@oracle.com> writes:
>> > Was there something wrong with the suggestion to return,
>> > as the non-nil value, a cons (ELEMENT . VALUE)?
>> >
>> > (Where ELEMENT is the sequence element that satisfies the
>> > predicate, and VALUE is the return value of the predicate
>> > for that element.)
>> >
>> > That gives you "some" element that satisfies the predicate
>> > (the first such). And it gives you the result of the test.
>> > Each of these can be useful, depending on the context.
>>
>> It would work, and I believe Scheme has a similar function, but I don't
>> want seq-some to have this extra complexity. It could be another
>> function though, just like in Scheme.
>
> What extra complexity? It creates one cons cell which has as its
> car and cdr things that presumably already exist.
I meant extra complexity for the user. If seq-some was returning a
value, I wouldn't expect it to be a cons cell, I'd almost always want
the element of the sequence straight away.
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-09 7:56 ` Nicolas Petton
@ 2015-09-09 13:26 ` Drew Adams
2015-09-09 17:45 ` Stefan Monnier
2015-09-09 21:44 ` Nicolas Petton
0 siblings, 2 replies; 54+ messages in thread
From: Drew Adams @ 2015-09-09 13:26 UTC (permalink / raw)
To: Nicolas Petton, David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, emacs-devel
> I meant extra complexity for the user. If seq-some was returning a
> value, I wouldn't expect it to be a cons cell, I'd almost always want
> the element of the sequence straight away.
Well, yes. But what if the user wants the value returned by the
function? And what if the element is nil?
1. You need a way to always return non-nil when an element is found.
This includes the case where the element is nil - you cannot
just return nil as the element.
2. You (I) want to be able to use the the `some' function to
either get the element or get the return value of the predicate,
which can be an arbitrary function that could return a rich value.
Or both: get and use both the element and the value.
Conclusion: return both the element and the predicate value, as
a non-nil Lisp value. (ELEMENT . VALUE) is one such simple value.
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-09 13:26 ` Drew Adams
@ 2015-09-09 17:45 ` Stefan Monnier
2015-09-09 17:53 ` Drew Adams
2015-09-09 21:44 ` Nicolas Petton
1 sibling, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-09 17:45 UTC (permalink / raw)
To: Drew Adams; +Cc: Mark Oteiza, Nicolas Petton, David Kastrup, emacs-devel
seq-some already solves those problems. The user can provide a FUN that
returns a cons if she so wishes. It's simple and general.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-09 17:45 ` Stefan Monnier
@ 2015-09-09 17:53 ` Drew Adams
2015-09-09 20:24 ` Stefan Monnier
0 siblings, 1 reply; 54+ messages in thread
From: Drew Adams @ 2015-09-09 17:53 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, David Kastrup, emacs-devel
> seq-some already solves those problems. The user can provide a FUN that
> returns a cons if she so wishes. It's simple and general.
So is assembly language simple and general. Why make callers of
`seq-some' deal with the nil-value-vs-not-found issue and wrap
existing predicates they want to reuse with cruft, just to get
the desired effect? Why not just have `seq-some' DTRT, always?
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-09 17:53 ` Drew Adams
@ 2015-09-09 20:24 ` Stefan Monnier
2015-09-09 20:46 ` Drew Adams
0 siblings, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-09 20:24 UTC (permalink / raw)
To: Drew Adams; +Cc: Mark Oteiza, Nicolas Petton, David Kastrup, emacs-devel
> So is assembly language simple and general. Why make callers of
> `seq-some' deal with the nil-value-vs-not-found issue
There's no such issue with seq-some. It only affects seq-find.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-09 20:24 ` Stefan Monnier
@ 2015-09-09 20:46 ` Drew Adams
0 siblings, 0 replies; 54+ messages in thread
From: Drew Adams @ 2015-09-09 20:46 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, David Kastrup, emacs-devel
> > Why make callers of `seq-some' deal with the nil-value-vs-not-found
> > issue and...
>
> There's no such issue with seq-some. It only affects seq-find.
Oh, right, because you have not done what Nico proposed wrt returning
the element. Fair enough.
The second part of what I wrote, which you elided, still applies:
Why make callers of `seq-some' ... wrap existing predicates they want
to reuse with cruft, just to get the desired effect? Why not just
have `seq-some' DTRT, always?
^ permalink raw reply [flat|nested] 54+ messages in thread
* RE: seq-some-p and nil
2015-09-09 13:26 ` Drew Adams
2015-09-09 17:45 ` Stefan Monnier
@ 2015-09-09 21:44 ` Nicolas Petton
1 sibling, 0 replies; 54+ messages in thread
From: Nicolas Petton @ 2015-09-09 21:44 UTC (permalink / raw)
To: Drew Adams, David Kastrup, Stefan Monnier; +Cc: Mark Oteiza, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1016 bytes --]
Drew Adams <drew.adams@oracle.com> writes:
>> I meant extra complexity for the user. If seq-some was returning a
>> value, I wouldn't expect it to be a cons cell, I'd almost always want
>> the element of the sequence straight away.
>
> Well, yes. But what if the user wants the value returned by the
> function?
`seq-some', as it is now defined, is the right function to use.
> And what if the element is nil?
Then maybe seq-find is not the right function to use. Or seq-find
could, as Stephen suggested, take an optional sentinel argument for
these very rare cases.
I know that your suggestion also fixes the semantic issue, but I don't
like the cost it adds. 99% of the times, you will want the element you
searched for in the seq. I think using seq-find should remain simple
and straightforward, just like `find-if' in CL. I also had another look
at the Clojure and Scheme equivalents, and they both have a similar
corner case, though in the case of Clojure, `true' is returned instead
of `nil'.
Nico
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 17:01 ` David Kastrup
2015-09-08 17:08 ` Drew Adams
@ 2015-09-08 18:43 ` Stefan Monnier
2015-09-08 19:03 ` David Kastrup
1 sibling, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-08 18:43 UTC (permalink / raw)
To: David Kastrup; +Cc: Mark Oteiza, Nicolas Petton, Drew Adams, emacs-devel
>>>> then in most cases, I think the code ends up just as simple with
>>>> seq-some as with seq-find.
>> [...]
>>> To make things easier to understand, I'm taking the example of finding
>>> the first odd number in a seq:
>> I've never needed to do that.
> Marvelous.
You did notice the "most" qualifier, right?
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 18:43 ` Stefan Monnier
@ 2015-09-08 19:03 ` David Kastrup
0 siblings, 0 replies; 54+ messages in thread
From: David Kastrup @ 2015-09-08 19:03 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Nicolas Petton, Drew Adams, emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>>>> then in most cases, I think the code ends up just as simple with
>>>>> seq-some as with seq-find.
>>> [...]
>>>> To make things easier to understand, I'm taking the example of finding
>>>> the first odd number in a seq:
>>> I've never needed to do that.
>> Marvelous.
>
> You did notice the "most" qualifier, right?
Oh, that changes _everything_, _everything_ I am sure.
When at that time in my life when I had been attending lectures some
professor would have stated
"As an example, let's see how to take the inverse of the matrix
( 1 2 )
( 2 1 )"
I would never felt the urge to tell the professor that this is a
particular matrix I never actually needed to invert. I'm pretty sure
that the entire lecture room would have bursted into laughter at me
volunteering this particular bit of information and considering it
important enough to ask for everybody's attention.
It is an example. Nobody expects life-shattering relevance of that
example for any purpose but being an example.
--
David Kastrup
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 16:49 ` Stefan Monnier
2015-09-08 17:01 ` David Kastrup
@ 2015-09-08 18:59 ` Nicolas Petton
2015-09-08 19:06 ` David Kastrup
2015-09-08 20:33 ` Stefan Monnier
1 sibling, 2 replies; 54+ messages in thread
From: Nicolas Petton @ 2015-09-08 18:59 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Drew Adams, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 449 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> then in most cases, I think the code ends up just as simple with
>>> seq-some as with seq-find.
> [...]
>> To make things easier to understand, I'm taking the example of finding
>> the first odd number in a seq:
>
> I've never needed to do that.
That was just an example. You never needed to find an element from
a sequence?
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 18:59 ` Nicolas Petton
@ 2015-09-08 19:06 ` David Kastrup
2015-09-08 20:33 ` Stefan Monnier
1 sibling, 0 replies; 54+ messages in thread
From: David Kastrup @ 2015-09-08 19:06 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Mark Oteiza, Stefan Monnier, Drew Adams, emacs-devel
Nicolas Petton <nicolas@petton.fr> writes:
> Stefan Monnier <monnier@iro.umontreal.ca> writes:
>
>>>> then in most cases, I think the code ends up just as simple with
>>>> seq-some as with seq-find.
>> [...]
>>> To make things easier to understand, I'm taking the example of finding
>>> the first odd number in a seq:
>>
>> I've never needed to do that.
>
> That was just an example.
<URL:http://www.smbc-comics.com/index.php?id=3855>
--
David Kastrup
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 18:59 ` Nicolas Petton
2015-09-08 19:06 ` David Kastrup
@ 2015-09-08 20:33 ` Stefan Monnier
2015-09-09 7:57 ` Nicolas Petton
1 sibling, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-08 20:33 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Mark Oteiza, Drew Adams, emacs-devel
>>>> then in most cases, I think the code ends up just as simple with
>>>> seq-some as with seq-find.
>> [...]
>>> To make things easier to understand, I'm taking the example of finding
>>> the first odd number in a seq:
>> I've never needed to do that.
> That was just an example. You never needed to find an element from
> a sequence?
On its own, no; only to do something with it. So I think in many cases
you can cheaply move the equivalent of (and <pred> x) into the seq-some
search, in many other cases you can instead cheaply move the processing
of the result into the seq-some search.
Of course, there are still remaining cases where you'll end up needing
(lambda (x) (if (my-pred x) x)), but in my experience, it's not frequent
enough to make a seq-find useful.
This said, we have lots of such functions I find useless, so don't let
that prevent you from adding it to seq.el. Just don't forget to warn
about its little semantic problem with nil in the docstring.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 12:36 ` Stefan Monnier
2015-09-08 13:07 ` Nicolas Petton
@ 2015-09-08 13:21 ` Nicolas Petton
2015-09-08 13:37 ` Mark Oteiza
1 sibling, 1 reply; 54+ messages in thread
From: Nicolas Petton @ 2015-09-08 13:21 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Mark Oteiza, Drew Adams, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 569 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> And using seq-some doesn't have the weird nil corner case.
Just like CL's `find-if' and Scheme's `find', if one is looking for nil,
and if `seq-find' is not supposed to return a boolean, then it's fine
with me. You'd always have `seq-some' if it's an issue in a specific
scenario anyway.
> And defining seq-find as I did means it's always less efficient.
It's ok, I think, for `seq-find' to reuse `seq-some'. You can't both
want to remove code duplication and be as efficient as the code you are
reusing.
Nico
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 13:21 ` Nicolas Petton
@ 2015-09-08 13:37 ` Mark Oteiza
2015-09-08 17:50 ` Stefan Monnier
0 siblings, 1 reply; 54+ messages in thread
From: Mark Oteiza @ 2015-09-08 13:37 UTC (permalink / raw)
To: Nicolas Petton; +Cc: Stefan Monnier, Drew Adams, emacs-devel
On 08/09/15 at 03:21pm, Nicolas Petton wrote:
> > And defining seq-find as I did means it's always less efficient.
>
> It's ok, I think, for `seq-find' to reuse `seq-some'. You can't both
> want to remove code duplication and be as efficient as the code you are
> reusing.
Why not reuse seq-find in seq-some? It at least looks (to me) a little
cleaner than the other way around
(defun seq-some (pred seq)
(funcall pred (seq-find (pred seq)))
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 13:37 ` Mark Oteiza
@ 2015-09-08 17:50 ` Stefan Monnier
2015-09-09 2:19 ` Mark Oteiza
0 siblings, 1 reply; 54+ messages in thread
From: Stefan Monnier @ 2015-09-08 17:50 UTC (permalink / raw)
To: Mark Oteiza; +Cc: Nicolas Petton, Drew Adams, emacs-devel
> (defun seq-some (pred seq)
> (funcall pred (seq-find (pred seq)))
But that fails for the case where the element found is nil.
Stefan
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-08 17:50 ` Stefan Monnier
@ 2015-09-09 2:19 ` Mark Oteiza
2015-09-09 4:28 ` Stephen J. Turnbull
0 siblings, 1 reply; 54+ messages in thread
From: Mark Oteiza @ 2015-09-09 2:19 UTC (permalink / raw)
To: Stefan Monnier; +Cc: Nicolas Petton, Drew Adams, emacs-devel
On 08/09/15 at 01:50pm, Stefan Monnier wrote:
> > (defun seq-some (pred seq)
> > (funcall pred (seq-find (pred seq)))
>
> But that fails for the case where the element found is nil.
Works as expected
(cl-defgeneric seq-find (pred seq)
(catch 'seq--break
(seq-doseq (elt seq)
(when (funcall pred elt)
(throw 'seq--break elt)))
nil))
(cl-defgeneric seq-some (pred seq)
(funcall pred (seq-find pred seq)))
(seq-find 'null [1 2 nil])
;; => nil
(seq-some 'null [1 2 nil])
;; => t
It's not a "semantic problem" or a "corner case", if one is really
curious if their sequence has a nil value, seq-find isn't the way to
find out.
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-09 2:19 ` Mark Oteiza
@ 2015-09-09 4:28 ` Stephen J. Turnbull
2015-09-09 4:57 ` Mark Oteiza
0 siblings, 1 reply; 54+ messages in thread
From: Stephen J. Turnbull @ 2015-09-09 4:28 UTC (permalink / raw)
To: Mark Oteiza; +Cc: Nicolas Petton, Stefan Monnier, Drew Adams, emacs-devel
Mark Oteiza writes:
> On 08/09/15 at 01:50pm, Stefan Monnier wrote:
> > > (defun seq-some (pred seq)
> > > (funcall pred (seq-find (pred seq)))
> >
> > But that fails for the case where the element found is nil.
>
> Works as expected
[...]
> (seq-find 'null [1 2 nil])
> ;; => nil
>
> (seq-some 'null [1 2 nil])
> ;; => t
>
> It's not a "semantic problem" or a "corner case", if one is really
> curious if their sequence has a nil value, seq-find isn't the way to
> find out.
You have a test coverage problem.
(seq-find 'null [1 2])
;; => nil
(seq-some 'null [1 2])
;; => t
I suppose this is the corner case Stefan meant, in the sense that when
seq-find "finds" (ie, "returns") nil it's impossible to distinguish
finding nil from not finding nil.
There are many ways to implement the distinction. One is to create an
uninterned symbol and return that from seq-find-internal, then define
seq-find and seq-some in terms of seq-find-internal. I suppose it's
more elegant to use a multiple-value technique (ie, return a cons
since Emacs doesn't have Common Lisp-style multiple values). This
could be done in the -internal function or in the exported API as Drew
(IIRC) suggested. You could use the get/find convention used
occasionally in Emacs, where the get-foo version signals an error and
find-foo returns nil. Then find can be defined in terms of get with
an error handler for the not-found error. (This is mostly used in
cases where the object is typically a blocker if not found though --
condition-case is relatively expensive.) The find version can also
take an optional sentinel argument which is an object to return in the
not found case.
There are so many ways to get this right. Please don't get it wrong.
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-09 4:28 ` Stephen J. Turnbull
@ 2015-09-09 4:57 ` Mark Oteiza
0 siblings, 0 replies; 54+ messages in thread
From: Mark Oteiza @ 2015-09-09 4:57 UTC (permalink / raw)
To: emacs-devel; +Cc: Nicolas Petton, Stefan Monnier, Drew Adams
On 09/09/15 at 01:28pm, Stephen J. Turnbull wrote:
> Mark Oteiza writes:
> > On 08/09/15 at 01:50pm, Stefan Monnier wrote:
> > > > (defun seq-some (pred seq)
> > > > (funcall pred (seq-find (pred seq)))
> > >
> > > But that fails for the case where the element found is nil.
> >
> > Works as expected
>
> [...]
> > (seq-find 'null [1 2 nil])
> > ;; => nil
> >
> > (seq-some 'null [1 2 nil])
> > ;; => t
>
> You have a test coverage problem.
>
> (seq-find 'null [1 2])
> ;; => nil
>
> (seq-some 'null [1 2])
> ;; => t
>
> I suppose this is the corner case Stefan meant, in the sense that when
> seq-find "finds" (ie, "returns") nil it's impossible to distinguish
> finding nil from not finding nil.
Thanks, that makes sense. I misunderstood
^ permalink raw reply [flat|nested] 54+ messages in thread
* Re: seq-some-p and nil
2015-09-07 15:19 ` Stefan Monnier
` (2 preceding siblings ...)
2015-09-07 20:44 ` Nicolas Petton
@ 2015-09-07 20:45 ` Nicolas Petton
3 siblings, 0 replies; 54+ messages in thread
From: Nicolas Petton @ 2015-09-07 20:45 UTC (permalink / raw)
To: Stefan Monnier, Drew Adams; +Cc: Mark Oteiza, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 211 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> Returning what FUN returned seems like a better choice.
It's already what the new seq-some does.
Nico
--
Nicolas Petton
http://nicolas-petton.fr
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]
^ permalink raw reply [flat|nested] 54+ messages in thread