New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add -to-head
and -shuffle
#404
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -294,6 +294,8 @@ Other list functions not fit to be classified elsewhere. | |
* [`-last-item`](#-last-item-list) `(list)` | ||
* [`-butlast`](#-butlast-list) `(list)` | ||
* [`-sort`](#-sort-comparator-list) `(comparator list)` | ||
* [`-to-head`](#-to-head-n-list) `(n list)` | ||
* [`-shuffle`](#-shuffle-list) `(list)` | ||
* [`-list`](#-list-arg) `(arg)` | ||
* [`-fix`](#-fix-fn-list) `(fn list)` | ||
|
||
|
@@ -2317,6 +2319,29 @@ if the first element should sort before the second. | |
(--sort (< it other) '(3 1 2)) ;; => (1 2 3) | ||
``` | ||
|
||
#### -to-head `(n list)` | ||
|
||
Return a new list that move the element at `n`th to the head of old `list`. | ||
|
||
```el | ||
(-to-head 3 '(1 2 3 4 5)) ;; => (4 1 2 3 5) | ||
(-to-head 5 '(1 2 3 4 5)) ;; peculiar error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. BTW, |
||
(let ((l '(1 2 3 4 5))) (list (-to-head 2 l) l)) ;; => ((3 1 2 4 5) (1 2 3 4 5)) | ||
``` | ||
|
||
#### -shuffle `(list)` | ||
|
||
Return a new shuffled `list`. | ||
|
||
The returned list is shuffled by using Fisher-Yates' Algorithm. See | ||
https://en.wikipedia.org/wiki/Fisher-Yates_shuffle for more details. | ||
|
||
```el | ||
(progn (random "dash1") (-shuffle '(1 2 3 4 5 6 7))) ;; => (2 7 6 4 5 1 3) | ||
(progn (random "dash2") (-shuffle '(1 2 3 4 5 6 7))) ;; => (1 5 2 4 3 7 6) | ||
(let ((l '(1 2 3 4 5 6 7))) (random "dash3") (list (-shuffle '(1 2 3 4 5 6 7)) l)) ;; => ((3 4 1 5 7 6 2) (1 2 3 4 5 6 7)) | ||
``` | ||
|
||
#### -list `(arg)` | ||
|
||
Ensure `arg` is a list. | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3238,6 +3238,30 @@ if the first element should sort before the second." | |
(declare (debug (def-form form))) | ||
`(-sort (lambda (it other) (ignore it other) ,form) ,list)) | ||
|
||
(defun -to-head (n list) | ||
"Return a new list that move the element at Nth to the head of old LIST." | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Grammatical nits: But I think we can make this even shorter, to fit even within the default 65 column suggestion: "Return a copy of LIST with its Nth item moved to the front." WDYT? |
||
(declare (pure t) (side-effect-free t)) | ||
(if (> n (1- (length list))) | ||
(error "Index %d out of the range of list %S" n list)) | ||
Comment on lines
+3244
to
+3245
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is it better to signal here, or return the original list unchanged? There is a lot of precedent for the latter behaviour, e.g. BTW, there's a special |
||
(let* ((head (-take n list)) | ||
(rest (-drop n list)) | ||
Comment on lines
+3246
to
+3247
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What about using |
||
(target (pop rest))) | ||
(cons target (nconc head rest)))) | ||
|
||
(defun -shuffle (list &optional rng) | ||
"Return a new shuffled LIST, shuffling using RNG. | ||
|
||
The returned list is shuffled by using Fisher-Yates' Algorithm. See | ||
https://en.wikipedia.org/wiki/Fisher-Yates_shuffle for more details." | ||
Comment on lines
+3254
to
+3255
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the implementation is better described in a comment than the docstring. |
||
(declare (pure t) (side-effect-free t)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shuffling returns a different result each time, so it is not pure, and it is side-effect-free only if we remove the |
||
(let* ((len (length list)) | ||
(random-nums (-map (or rng #'random) (number-sequence len 1 -1))) | ||
result) | ||
(--each random-nums | ||
(setq list (-to-head it list)) | ||
(push (pop list) result)) | ||
(nreverse result))) | ||
|
||
(defun -list (&optional arg &rest args) | ||
"Ensure ARG is a list. | ||
If ARG is already a list, return it as is (not a copy). | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto re: autogenerating this file. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,6 +53,17 @@ | |
(defun even? (num) (= 0 (% num 2))) | ||
(defun square (num) (* num num)) | ||
|
||
(defun make-xorshift32-rng (seed) | ||
(let ((state (list seed)) | ||
(uint32-max (- (expt 2 32) 1))) | ||
(lambda (limit) | ||
(let* ((seed (car state)) | ||
(step1 (logxor seed (logand uint32-max (ash seed 13)))) | ||
(step2 (logxor step1 (logand uint32-max (ash seed -17)))) | ||
(final (logxor step2 (logand uint32-max (ash step2 5))))) | ||
(setcar state final) | ||
(mod final limit))))) | ||
|
||
(def-example-group "Maps" | ||
"Functions in this category take a transforming function, which | ||
is then applied sequentially to each or selected elements of the | ||
|
@@ -1921,6 +1932,19 @@ related predicates." | |
(--sort (< it other) '(3 1 2)) => '(1 2 3) | ||
(let ((l '(3 1 2))) (-sort '> l) l) => '(3 1 2)) | ||
|
||
(defexamples -to-head | ||
(-to-head 3 '(1 2 3 4 5)) => '(4 1 2 3 5) | ||
(-to-head 5 '(1 2 3 4 5)) !!> error | ||
(let ((l '(1 2 3 4 5))) | ||
(list (-to-head 2 l) l)) => '((3 1 2 4 5) (1 2 3 4 5))) | ||
|
||
(defexamples -shuffle | ||
(-shuffle '(1 2 3 4 5 6 7) (make-xorshift32-rng #xcafe)) => '(7 6 1 2 3 5 4) | ||
(-shuffle '(1 2 3 4 5 6 7) (make-xorshift32-rng #xbeef)) => '(4 3 2 5 6 7 1) | ||
(let ((l '(1 2 3 4 5 6 7))) | ||
(list (-shuffle '(1 2 3 4 5 6 7) (make-xorshift32-rng #xdead)) l)) => '((3 4 6 5 1 2 7) (1 2 3 4 5 6 7)) | ||
Comment on lines
+1942
to
+1945
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
(-shuffle nil) => nil) | ||
|
||
(defexamples -list | ||
(-list 1) => '(1) | ||
(-list '()) => '() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.md
is autogenerated from function docstrings, the top three examples of eachdefexamples
indev/examples.el
, andreadme-template.md
. So the docstrings and first three examples should beREADME.md
-quality, and this file should not be edited by hand.