unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* Add seq-random-elt
@ 2016-10-21  6:05 Damien Cassou
  2016-10-21  8:08 ` Nicolas Petton
                   ` (5 more replies)
  0 siblings, 6 replies; 19+ messages in thread
From: Damien Cassou @ 2016-10-21  6:05 UTC (permalink / raw)
  To: emacs-devel; +Cc: Nicolas Petton

[-- Attachment #1: Type: text/plain, Size: 255 bytes --]

Hi,

attached patch adds seq-random-elt to seq.el and its unit test to
seq-tests.el.

Best

-- 
Damien Cassou
http://damiencassou.seasidehosting.st

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-seq-random-elt-to-seq.el.patch --]
[-- Type: text/x-patch, Size: 2232 bytes --]

From 87396cb588e7faa6ee64f692290d53aeb9553f1b Mon Sep 17 00:00:00 2001
From: Damien Cassou <damien@cassou.me>
Date: Fri, 21 Oct 2016 07:53:08 +0200
Subject: [PATCH] Add seq-random-elt to seq.el

* lisp/emacs-lisp/seq.el (seq-random-elt): Add function to return a
  random element from it's sequence parameter.

* test/lisp/emacs-lisp/seq-tests.el (test-seq-random-elt-take-all): Test
  the new function
---
 lisp/emacs-lisp/seq.el            |  6 +++++-
 test/lisp/emacs-lisp/seq-tests.el | 12 ++++++++++++
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 9859f28..6ef5b08 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: sequences
-;; Version: 2.18
+;; Version: 2.19
 ;; Package: seq
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -476,6 +476,10 @@ SEQUENCE must be a sequence of numbers or markers."
   "Return element of SEQUENCE at the index N.
 If no element is found, return nil."
   (ignore-errors (seq-elt sequence n)))
+
+(cl-defgeneric seq-random-elt (sequence)
+  "Return a random element from SEQUENCE."
+  (seq-elt sequence (random (seq-length sequence))))
 \f
 
 ;;; Optimized implementations for lists
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index c2065c6..7c1b5e7 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -28,6 +28,7 @@
 
 (require 'ert)
 (require 'seq)
+(require 'map)
 
 (defmacro with-test-sequences (spec &rest body)
   "Successively bind VAR to a list, vector, and string built from SEQ.
@@ -371,5 +372,16 @@ Evaluate BODY for each created sequence.
     (should (equal (seq-sort-by #'seq-length #'> seq)
                    ["xxx" "xx" "x"]))))
 
+(ert-deftest test-seq-random-elt-take-all ()
+  (let ((seq '(a b c d e))
+        (count '()))
+    (should (= 0 (map-length count)))
+    (dotimes (_ 1000)
+      (let ((random-elt (seq-random-elt seq)))
+        (map-put count
+                 random-elt
+                 (map-elt count random-elt 0))))
+    (should (= 5 (map-length count)))))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
@ 2016-10-21  8:08 ` Nicolas Petton
  2016-10-21  9:06 ` Nicolas Petton
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Nicolas Petton @ 2016-10-21  8:08 UTC (permalink / raw)
  To: Damien Cassou, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 251 bytes --]

Damien Cassou <damien@cassou.me> writes:

> Hi,

Hi Damien,

> attached patch adds seq-random-elt to seq.el and its unit test to
> seq-tests.el.

Thanks, it looks good to me.  Could you also add documentation in the
sequences.texi file?

Thanks,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
  2016-10-21  8:08 ` Nicolas Petton
@ 2016-10-21  9:06 ` Nicolas Petton
  2016-10-21 18:57 ` Stefan Monnier
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 19+ messages in thread
From: Nicolas Petton @ 2016-10-21  9:06 UTC (permalink / raw)
  To: Damien Cassou, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 251 bytes --]

Damien Cassou <damien@cassou.me> writes:

> Hi,

Hi Damien,

> attached patch adds seq-random-elt to seq.el and its unit test to
> seq-tests.el.

Thanks, it looks good to me.  Could you also add documentation in the
sequences.texi file?

Cheers,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
  2016-10-21  8:08 ` Nicolas Petton
  2016-10-21  9:06 ` Nicolas Petton
@ 2016-10-21 18:57 ` Stefan Monnier
  2016-10-21 20:52   ` Nicolas Petton
  2016-10-22 14:54 ` Clément Pit--Claudel
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 19+ messages in thread
From: Stefan Monnier @ 2016-10-21 18:57 UTC (permalink / raw)
  To: emacs-devel

> +(cl-defgeneric seq-random-elt (sequence)
> +  "Return a random element from SEQUENCE."
> +  (seq-elt sequence (random (seq-length sequence))))

Hmm... do we really need that?  What's the benefit?

I have a hard time imagining that it's so commonly needed that it
deserves to be in seq.el to avoid everyone redefining its own.

Is there maybe a sequence which will provide another implementation?
If not, I'd vote to keep this out of seq.el.


        Stefan




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21 18:57 ` Stefan Monnier
@ 2016-10-21 20:52   ` Nicolas Petton
  2016-10-21 21:30     ` Stefan Monnier
  0 siblings, 1 reply; 19+ messages in thread
From: Nicolas Petton @ 2016-10-21 20:52 UTC (permalink / raw)
  To: Stefan Monnier, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 568 bytes --]

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Hmm... do we really need that?  What's the benefit?

I think it's convenient.  Accessing random elements of sequences is not
uncommon.

Smalltalk has `Collection >> atRandom', Clojure has `rand-nth', etc.  I
agree it's probably not something you use daily, but it's convenient to
have it when you need it.

> Is there maybe a sequence which will provide another implementation?
> If not, I'd vote to keep this out of seq.el.

I'd go for including it, but I don't have a super strong opinion about
it.

Cheers,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21 20:52   ` Nicolas Petton
@ 2016-10-21 21:30     ` Stefan Monnier
  2016-10-22  8:13       ` Michael Heerdegen
                         ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Stefan Monnier @ 2016-10-21 21:30 UTC (permalink / raw)
  To: emacs-devel

>> Hmm... do we really need that?  What's the benefit?
> I think it's convenient.  Accessing random elements of sequences is not
> uncommon.

Right, but

    (seq-elt L (random (seq-length L)))

it pretty convenient to write and pretty clear as well, so the benefit
seems slim.


        Stefan




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21 21:30     ` Stefan Monnier
@ 2016-10-22  8:13       ` Michael Heerdegen
  2016-10-22 12:42       ` Ted Zlatanov
  2016-10-22 14:53       ` Clément Pit--Claudel
  2 siblings, 0 replies; 19+ messages in thread
From: Michael Heerdegen @ 2016-10-22  8:13 UTC (permalink / raw)
  To: emacs-devel

Stefan Monnier <monnier@iro.umontreal.ca> writes:

> Right, but
>
>     (seq-elt L (random (seq-length L)))
>
> it pretty convenient to write and pretty clear as well, so the benefit
> seems slim.

FWIW I second that.


Michael.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21 21:30     ` Stefan Monnier
  2016-10-22  8:13       ` Michael Heerdegen
@ 2016-10-22 12:42       ` Ted Zlatanov
  2016-10-22 14:53       ` Clément Pit--Claudel
  2 siblings, 0 replies; 19+ messages in thread
From: Ted Zlatanov @ 2016-10-22 12:42 UTC (permalink / raw)
  To: emacs-devel

On Fri, 21 Oct 2016 17:30:02 -0400 Stefan Monnier <monnier@iro.umontreal.ca> wrote: 

>>> Hmm... do we really need that?  What's the benefit?
>> I think it's convenient.  Accessing random elements of sequences is not
>> uncommon.

SM>     (seq-elt L (random (seq-length L)))

SM> it pretty convenient to write and pretty clear as well, so the benefit
SM> seems slim.

I don't like to name variables twice. I've sometimes forgotten to change
the second place when I copy and paste, creating very annoying bugs.

I also think this would be helpful to beginners who may not intuit the
right approach so easily.

Ted




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21 21:30     ` Stefan Monnier
  2016-10-22  8:13       ` Michael Heerdegen
  2016-10-22 12:42       ` Ted Zlatanov
@ 2016-10-22 14:53       ` Clément Pit--Claudel
  2 siblings, 0 replies; 19+ messages in thread
From: Clément Pit--Claudel @ 2016-10-22 14:53 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 717 bytes --]

On 2016-10-21 17:30, Stefan Monnier wrote:
>>> Hmm... do we really need that?  What's the benefit?
>> I think it's convenient.  Accessing random elements of sequences is not
>> uncommon.
> 
> Right, but
> 
>     (seq-elt L (random (seq-length L)))
> 
> it pretty convenient to write and pretty clear as well, so the benefit
> seems slim.

Indeed, but it's arguably wrong: if L is nil, random will ignore limit and possibly return a negative number.  seq-elt is unspecified for negative indices AFAICT (though it seems to return nil ATM).
So maybe we could/should have a seq-random-element, and it should check for nil.  If it did, then it would be a useful addition, I think.

Cheers,
Clément.




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
                   ` (2 preceding siblings ...)
  2016-10-21 18:57 ` Stefan Monnier
@ 2016-10-22 14:54 ` Clément Pit--Claudel
  2016-10-23 17:06 ` Damien Cassou
  2016-10-25  6:52 ` Damien Cassou
  5 siblings, 0 replies; 19+ messages in thread
From: Clément Pit--Claudel @ 2016-10-22 14:54 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 299 bytes --]

On 2016-10-21 02:05, Damien Cassou wrote:
> * lisp/emacs-lisp/seq.el (seq-random-elt): Add function to return a
>   random element from it's sequence parameter.

Typo: it's → its
Also: I think adding error checking (for `nil' lists) would make this function much more useful.

Clément.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
                   ` (3 preceding siblings ...)
  2016-10-22 14:54 ` Clément Pit--Claudel
@ 2016-10-23 17:06 ` Damien Cassou
  2016-10-24 11:03   ` Nicolas Petton
  2016-10-24 16:24   ` Davis Herring
  2016-10-25  6:52 ` Damien Cassou
  5 siblings, 2 replies; 19+ messages in thread
From: Damien Cassou @ 2016-10-23 17:06 UTC (permalink / raw)
  To: emacs-devel; +Cc: Nicolas Petton

[-- Attachment #1: Type: text/plain, Size: 341 bytes --]

Hi,

here is a new patch which both:

* adds documentation to sequences.texi as Nicolas requested, and

* checks for null parameter as Clément requested

Best,

-- 
Damien Cassou
http://damiencassou.seasidehosting.st

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-seq-random-elt-to-seq.el.patch --]
[-- Type: text/x-patch, Size: 3215 bytes --]

From 77984f5705f478275b865e7c3105ceca9380007e Mon Sep 17 00:00:00 2001
From: Damien Cassou <damien@cassou.me>
Date: Fri, 21 Oct 2016 07:53:08 +0200
Subject: [PATCH] Add seq-random-elt to seq.el

* lisp/emacs-lisp/seq.el (seq-random-elt): Add function to return a
  random element from it's sequence parameter.

* test/lisp/emacs-lisp/seq-tests.el (test-seq-random-elt-take-all
  test-seq-random-elt-return-nil): Test the new function

* doc/lispref/sequences.texi: Document the new function
---
 doc/lispref/sequences.texi        | 20 ++++++++++++++++++++
 lisp/emacs-lisp/seq.el            |  8 +++++++-
 test/lisp/emacs-lisp/seq-tests.el | 15 +++++++++++++++
 3 files changed, 42 insertions(+), 1 deletion(-)

diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 08e5e3a..f06a615 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1037,6 +1037,26 @@ Sequence Functions
 @end example
 @end defmac
 
+@defun seq-random-elt sequence
+  This function returns an element of @var{sequence} taken at random. If @var{sequence} is nil, the function returns nil.
+
+@example
+@group
+(seq-random-elt [1 2 3 4])
+@result{} 3
+(seq-random-elt [1 2 3 4])
+@result{} 2
+(seq-random-elt [1 2 3 4])
+@result{} 4
+(seq-random-elt [1 2 3 4])
+@result{} 2
+(seq-random-elt [1 2 3 4])
+@result{} 1
+@end group
+@end example
+
+  If @var{sequence} is nil, the function returns nil.
+@end defun
 
 @node Arrays
 @section Arrays
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 9859f28..9ece928 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: sequences
-;; Version: 2.18
+;; Version: 2.19
 ;; Package: seq
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -476,6 +476,12 @@ seq--elt-safe
   "Return element of SEQUENCE at the index N.
 If no element is found, return nil."
   (ignore-errors (seq-elt sequence n)))
+
+(cl-defgeneric seq-random-elt (sequence)
+  "Return a random element from SEQUENCE.
+Return nil if SEQUENCE is nil."
+  (when sequence
+    (seq-elt sequence (random (seq-length sequence)))))
 \f
 
 ;;; Optimized implementations for lists
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index c2065c6..a6f26be 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -28,6 +28,7 @@
 
 (require 'ert)
 (require 'seq)
+(require 'map)
 
 (defmacro with-test-sequences (spec &rest body)
   "Successively bind VAR to a list, vector, and string built from SEQ.
@@ -371,5 +372,19 @@ test-sequences-oddp
     (should (equal (seq-sort-by #'seq-length #'> seq)
                    ["xxx" "xx" "x"]))))
 
+(ert-deftest test-seq-random-elt-take-all ()
+  (let ((seq '(a b c d e))
+        (count '()))
+    (should (= 0 (map-length count)))
+    (dotimes (_ 1000)
+      (let ((random-elt (seq-random-elt seq)))
+        (map-put count
+                 random-elt
+                 (map-elt count random-elt 0))))
+    (should (= 5 (map-length count)))))
+
+(ert-deftest test-seq-random-elt-return-nil ()
+  (should (null (seq-random-elt nil))))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-23 17:06 ` Damien Cassou
@ 2016-10-24 11:03   ` Nicolas Petton
  2016-10-24 13:07     ` Stefan Monnier
  2016-10-24 16:24   ` Davis Herring
  1 sibling, 1 reply; 19+ messages in thread
From: Nicolas Petton @ 2016-10-24 11:03 UTC (permalink / raw)
  To: Damien Cassou, emacs-devel, Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 187 bytes --]

Damien Cassou <damien@cassou.me> writes:

> here is a new patch which both:

Thanks, I think it is useful enough as it is to be included.
Stefan, is it ok with you as well?

Cheers,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-24 11:03   ` Nicolas Petton
@ 2016-10-24 13:07     ` Stefan Monnier
  0 siblings, 0 replies; 19+ messages in thread
From: Stefan Monnier @ 2016-10-24 13:07 UTC (permalink / raw)
  To: Nicolas Petton; +Cc: Damien Cassou, emacs-devel

>> here is a new patch which both:
> Thanks, I think it is useful enough as it is to be included.
> Stefan, is it ok with you as well?

I'm not in favor of introducing such a function, but since other people
like it, feel free to go ahead,


        Stefan



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-23 17:06 ` Damien Cassou
  2016-10-24 11:03   ` Nicolas Petton
@ 2016-10-24 16:24   ` Davis Herring
  2016-10-24 16:54     ` Clément Pit--Claudel
  1 sibling, 1 reply; 19+ messages in thread
From: Davis Herring @ 2016-10-24 16:24 UTC (permalink / raw)
  To: Damien Cassou; +Cc: Nicolas Petton, emacs-devel

> * checks for null parameter as Clément requested

The check should signal an error, though: it's meaningless to ask for a 
random choice from an empty set, and nil is a legitimate return value 
otherwise (if the sequence contains it).

Davis

-- 
This product is sold by volume, not by mass.  If it appears too dense or 
too sparse, it is because mass-energy conversion has occurred during 
shipping.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-24 16:24   ` Davis Herring
@ 2016-10-24 16:54     ` Clément Pit--Claudel
  0 siblings, 0 replies; 19+ messages in thread
From: Clément Pit--Claudel @ 2016-10-24 16:54 UTC (permalink / raw)
  To: emacs-devel


[-- Attachment #1.1: Type: text/plain, Size: 327 bytes --]

On 2016-10-24 12:24, Davis Herring wrote:
>> * checks for null parameter as Clément requested
> 
> The check should signal an error, though: it's meaningless to ask for a random choice from an empty set, and nil is a legitimate return value otherwise (if the sequence contains it).

Indeed, I think I agree with this.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 819 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-21  6:05 Add seq-random-elt Damien Cassou
                   ` (4 preceding siblings ...)
  2016-10-23 17:06 ` Damien Cassou
@ 2016-10-25  6:52 ` Damien Cassou
  2016-10-25 10:33   ` Nicolas Petton
  5 siblings, 1 reply; 19+ messages in thread
From: Damien Cassou @ 2016-10-25  6:52 UTC (permalink / raw)
  To: emacs-devel; +Cc: Nicolas Petton

[-- Attachment #1: Type: text/plain, Size: 442 bytes --]

 Hi,

 here is v3 which:

  * signals an error on empty parameter as Davis Herring requested.


 Compared to v1, this patch also:

 * adds documentation to sequences.texi as Nicolas requested, and

 * checks for null parameter as Clément requested

 Best,

-- 
Damien Cassou
http://damiencassou.seasidehosting.st

"Success is the ability to go from one failure to another without
losing enthusiasm." --Winston Churchill

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-seq-random-elt-to-seq.el.patch --]
[-- Type: text/x-patch, Size: 3359 bytes --]

From 54e3074cfee6a4aafaf009ac58548005419db3c5 Mon Sep 17 00:00:00 2001
From: Damien Cassou <damien@cassou.me>
Date: Fri, 21 Oct 2016 07:53:08 +0200
Subject: [PATCH] Add seq-random-elt to seq.el

* lisp/emacs-lisp/seq.el (seq-random-elt): Add function to return a
  random element from it's sequence parameter.

* test/lisp/emacs-lisp/seq-tests.el (test-seq-random-elt-take-all
  test-seq-random-elt-return-nil): Test the new function

* doc/lispref/sequences.texi: Document the new function
---
 doc/lispref/sequences.texi        | 20 ++++++++++++++++++++
 lisp/emacs-lisp/seq.el            |  9 ++++++++-
 test/lisp/emacs-lisp/seq-tests.el | 17 +++++++++++++++++
 3 files changed, 45 insertions(+), 1 deletion(-)

diff --git a/doc/lispref/sequences.texi b/doc/lispref/sequences.texi
index 08e5e3a..b6874bf 100644
--- a/doc/lispref/sequences.texi
+++ b/doc/lispref/sequences.texi
@@ -1037,6 +1037,26 @@ Sequence Functions
 @end example
 @end defmac
 
+@defun seq-random-elt sequence
+  This function returns an element of @var{sequence} taken at random. If @var{sequence} is nil, the function returns nil.
+
+@example
+@group
+(seq-random-elt [1 2 3 4])
+@result{} 3
+(seq-random-elt [1 2 3 4])
+@result{} 2
+(seq-random-elt [1 2 3 4])
+@result{} 4
+(seq-random-elt [1 2 3 4])
+@result{} 2
+(seq-random-elt [1 2 3 4])
+@result{} 1
+@end group
+@end example
+
+  If @var{sequence} is empty, the function signals an error.
+@end defun
 
 @node Arrays
 @section Arrays
diff --git a/lisp/emacs-lisp/seq.el b/lisp/emacs-lisp/seq.el
index 9859f28..133dbd4 100644
--- a/lisp/emacs-lisp/seq.el
+++ b/lisp/emacs-lisp/seq.el
@@ -4,7 +4,7 @@
 
 ;; Author: Nicolas Petton <nicolas@petton.fr>
 ;; Keywords: sequences
-;; Version: 2.18
+;; Version: 2.19
 ;; Package: seq
 
 ;; Maintainer: emacs-devel@gnu.org
@@ -476,6 +476,13 @@ seq--elt-safe
   "Return element of SEQUENCE at the index N.
 If no element is found, return nil."
   (ignore-errors (seq-elt sequence n)))
+
+(cl-defgeneric seq-random-elt (sequence)
+  "Return a random element from SEQUENCE.
+Return nil if SEQUENCE is nil."
+  (if (seq-empty-p sequence)
+      (error "Sequence cannot be empty")
+    (seq-elt sequence (random (seq-length sequence)))))
 \f
 
 ;;; Optimized implementations for lists
diff --git a/test/lisp/emacs-lisp/seq-tests.el b/test/lisp/emacs-lisp/seq-tests.el
index c2065c6..6d17b7c 100644
--- a/test/lisp/emacs-lisp/seq-tests.el
+++ b/test/lisp/emacs-lisp/seq-tests.el
@@ -28,6 +28,7 @@
 
 (require 'ert)
 (require 'seq)
+(require 'map)
 
 (defmacro with-test-sequences (spec &rest body)
   "Successively bind VAR to a list, vector, and string built from SEQ.
@@ -371,5 +372,21 @@ test-sequences-oddp
     (should (equal (seq-sort-by #'seq-length #'> seq)
                    ["xxx" "xx" "x"]))))
 
+(ert-deftest test-seq-random-elt-take-all ()
+  (let ((seq '(a b c d e))
+        (count '()))
+    (should (= 0 (map-length count)))
+    (dotimes (_ 1000)
+      (let ((random-elt (seq-random-elt seq)))
+        (map-put count
+                 random-elt
+                 (map-elt count random-elt 0))))
+    (should (= 5 (map-length count)))))
+
+(ert-deftest test-seq-random-elt-signal-on-empty ()
+  (should-error (seq-random-elt nil))
+  (should-error (seq-random-elt []))
+  (should-error (seq-random-elt "")))
+
 (provide 'seq-tests)
 ;;; seq-tests.el ends here
-- 
2.10.0


^ permalink raw reply related	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-25  6:52 ` Damien Cassou
@ 2016-10-25 10:33   ` Nicolas Petton
  2016-10-25 18:58     ` Eli Zaretskii
  0 siblings, 1 reply; 19+ messages in thread
From: Nicolas Petton @ 2016-10-25 10:33 UTC (permalink / raw)
  To: Damien Cassou, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 381 bytes --]

Damien Cassou <damien@cassou.me> writes:

>  here is v3 which:
>
>   * signals an error on empty parameter as Davis Herring requested.
>
>
>  Compared to v1, this patch also:
>
>  * adds documentation to sequences.texi as Nicolas requested, and
>
>  * checks for null parameter as Clément requested

Thanks Damien, I installed your patch in master.

Cheers,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-25 10:33   ` Nicolas Petton
@ 2016-10-25 18:58     ` Eli Zaretskii
  2016-10-25 19:32       ` Nicolas Petton
  0 siblings, 1 reply; 19+ messages in thread
From: Eli Zaretskii @ 2016-10-25 18:58 UTC (permalink / raw)
  To: Nicolas Petton; +Cc: damien, emacs-devel

> From: Nicolas Petton <nicolas@petton.fr>
> Date: Tue, 25 Oct 2016 12:33:29 +0200
> 
> >  Compared to v1, this patch also:
> >
> >  * adds documentation to sequences.texi as Nicolas requested, and
> >
> >  * checks for null parameter as Clément requested
> 
> Thanks Damien, I installed your patch in master.

I fixed a couple of minor issues with the text in sequences.texi,
please take a look for the future.

Thanks.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Add seq-random-elt
  2016-10-25 18:58     ` Eli Zaretskii
@ 2016-10-25 19:32       ` Nicolas Petton
  0 siblings, 0 replies; 19+ messages in thread
From: Nicolas Petton @ 2016-10-25 19:32 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: damien, emacs-devel

[-- Attachment #1: Type: text/plain, Size: 215 bytes --]

Eli Zaretskii <eliz@gnu.org> writes:

Hi Eli,

> I fixed a couple of minor issues with the text in sequences.texi,
> please take a look for the future.

The second sentence was false, so I removed it.

Cheers,
Nico

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 512 bytes --]

^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2016-10-25 19:32 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-10-21  6:05 Add seq-random-elt Damien Cassou
2016-10-21  8:08 ` Nicolas Petton
2016-10-21  9:06 ` Nicolas Petton
2016-10-21 18:57 ` Stefan Monnier
2016-10-21 20:52   ` Nicolas Petton
2016-10-21 21:30     ` Stefan Monnier
2016-10-22  8:13       ` Michael Heerdegen
2016-10-22 12:42       ` Ted Zlatanov
2016-10-22 14:53       ` Clément Pit--Claudel
2016-10-22 14:54 ` Clément Pit--Claudel
2016-10-23 17:06 ` Damien Cassou
2016-10-24 11:03   ` Nicolas Petton
2016-10-24 13:07     ` Stefan Monnier
2016-10-24 16:24   ` Davis Herring
2016-10-24 16:54     ` Clément Pit--Claudel
2016-10-25  6:52 ` Damien Cassou
2016-10-25 10:33   ` Nicolas Petton
2016-10-25 18:58     ` Eli Zaretskii
2016-10-25 19:32       ` Nicolas Petton

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).