3411 lines
119 KiB
Plaintext
3411 lines
119 KiB
Plaintext
|
This is dash.info, produced by makeinfo version 6.5 from dash.texi.
|
|||
|
|
|||
|
This manual is for ‘dash.el’ version 2.12.1.
|
|||
|
|
|||
|
Copyright © 2012-2015 Magnar Sveen
|
|||
|
|
|||
|
This program is free software; you can redistribute it and/or
|
|||
|
modify it under the terms of the GNU General Public License as
|
|||
|
published by the Free Software Foundation, either version 3 of the
|
|||
|
License, or (at your option) any later version.
|
|||
|
|
|||
|
This program is distributed in the hope that it will be useful, but
|
|||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
General Public License for more details.
|
|||
|
|
|||
|
You should have received a copy of the GNU General Public License
|
|||
|
along with this program. If not, see
|
|||
|
<http://www.gnu.org/licenses/>.
|
|||
|
INFO-DIR-SECTION Emacs
|
|||
|
START-INFO-DIR-ENTRY
|
|||
|
* Dash: (dash.info). A modern list library for GNU Emacs
|
|||
|
END-INFO-DIR-ENTRY
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Top, Next: Installation, Up: (dir)
|
|||
|
|
|||
|
dash
|
|||
|
****
|
|||
|
|
|||
|
This manual is for ‘dash.el’ version 2.12.1.
|
|||
|
|
|||
|
Copyright © 2012-2015 Magnar Sveen
|
|||
|
|
|||
|
This program is free software; you can redistribute it and/or
|
|||
|
modify it under the terms of the GNU General Public License as
|
|||
|
published by the Free Software Foundation, either version 3 of the
|
|||
|
License, or (at your option) any later version.
|
|||
|
|
|||
|
This program is distributed in the hope that it will be useful, but
|
|||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|||
|
General Public License for more details.
|
|||
|
|
|||
|
You should have received a copy of the GNU General Public License
|
|||
|
along with this program. If not, see
|
|||
|
<http://www.gnu.org/licenses/>.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Installation::
|
|||
|
* Functions::
|
|||
|
* Development::
|
|||
|
* Index::
|
|||
|
|
|||
|
— The Detailed Node Listing —
|
|||
|
|
|||
|
Installation
|
|||
|
|
|||
|
* Using in a package::
|
|||
|
* Syntax highlighting of dash functions::
|
|||
|
|
|||
|
Functions
|
|||
|
|
|||
|
* Maps::
|
|||
|
* Sublist selection::
|
|||
|
* List to list::
|
|||
|
* Reductions::
|
|||
|
* Unfolding::
|
|||
|
* Predicates::
|
|||
|
* Partitioning::
|
|||
|
* Indexing::
|
|||
|
* Set operations::
|
|||
|
* Other list operations::
|
|||
|
* Tree operations::
|
|||
|
* Threading macros::
|
|||
|
* Binding::
|
|||
|
* Side-effects::
|
|||
|
* Destructive operations::
|
|||
|
* Function combinators::
|
|||
|
|
|||
|
Development
|
|||
|
|
|||
|
* Contribute:: How to contribute
|
|||
|
* Changes:: List of significant changes by version
|
|||
|
* Contributors:: List of contributors
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Installation, Next: Functions, Prev: Top, Up: Top
|
|||
|
|
|||
|
1 Installation
|
|||
|
**************
|
|||
|
|
|||
|
It’s available on Melpa (https://melpa.org/); use ‘M-x package-install’:
|
|||
|
|
|||
|
‘M-x package-install <RET> dash’
|
|||
|
Install the dash library.
|
|||
|
|
|||
|
‘M-x package-install <RET> dash-functional’
|
|||
|
Optional, if you want the function combinators.
|
|||
|
|
|||
|
Alternatively, you can just dump dash.el or dash-functional.el in
|
|||
|
your load path somewhere.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Using in a package::
|
|||
|
* Syntax highlighting of dash functions::
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Using in a package, Next: Syntax highlighting of dash functions, Up: Installation
|
|||
|
|
|||
|
1.1 Using in a package
|
|||
|
======================
|
|||
|
|
|||
|
Add this to the big comment block at the top:
|
|||
|
|
|||
|
;; Package-Requires: ((dash "2.12.1"))
|
|||
|
|
|||
|
To get function combinators:
|
|||
|
|
|||
|
;; Package-Requires: ((dash "2.12.1") (dash-functional "1.2.0") (emacs "24"))
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Syntax highlighting of dash functions, Prev: Using in a package, Up: Installation
|
|||
|
|
|||
|
1.2 Syntax highlighting of dash functions
|
|||
|
=========================================
|
|||
|
|
|||
|
Font lock of dash functions in emacs lisp buffers is now optional.
|
|||
|
Include this in your emacs settings to get syntax highlighting:
|
|||
|
|
|||
|
(eval-after-load 'dash '(dash-enable-font-lock))
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Functions, Next: Development, Prev: Installation, Up: Top
|
|||
|
|
|||
|
2 Functions
|
|||
|
***********
|
|||
|
|
|||
|
This chapter contains reference documentation for the dash application
|
|||
|
programming interface (API). All functions and constructs in the library
|
|||
|
are prefixed with a dash (-).
|
|||
|
|
|||
|
There are also anaphoric versions of functions where that makes
|
|||
|
sense, prefixed with two dashes instead of one.
|
|||
|
|
|||
|
For instance, while ‘-map’ takes a function to map over the list, one
|
|||
|
can also use the anaphoric form with double dashes - which will then be
|
|||
|
executed with ‘it’ exposed as the list item. Here’s an example:
|
|||
|
|
|||
|
(-map (lambda (n) (* n n)) '(1 2 3 4)) ;; normal version
|
|||
|
|
|||
|
(--map (* it it) '(1 2 3 4)) ;; anaphoric version
|
|||
|
|
|||
|
Of course, the original can also be written like
|
|||
|
|
|||
|
(defun square (n) (* n n))
|
|||
|
|
|||
|
(-map 'square '(1 2 3 4))
|
|||
|
|
|||
|
which demonstrates the usefulness of both versions.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Maps::
|
|||
|
* Sublist selection::
|
|||
|
* List to list::
|
|||
|
* Reductions::
|
|||
|
* Unfolding::
|
|||
|
* Predicates::
|
|||
|
* Partitioning::
|
|||
|
* Indexing::
|
|||
|
* Set operations::
|
|||
|
* Other list operations::
|
|||
|
* Tree operations::
|
|||
|
* Threading macros::
|
|||
|
* Binding::
|
|||
|
* Side-effects::
|
|||
|
* Destructive operations::
|
|||
|
* Function combinators::
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Maps, Next: Sublist selection, Up: Functions
|
|||
|
|
|||
|
2.1 Maps
|
|||
|
========
|
|||
|
|
|||
|
Functions in this category take a transforming function, which is then
|
|||
|
applied sequentially to each or selected elements of the input list.
|
|||
|
The results are collected in order and returned as new list.
|
|||
|
|
|||
|
-- Function: -map (fn list)
|
|||
|
Return a new list consisting of the result of applying FN to the
|
|||
|
items in LIST.
|
|||
|
|
|||
|
(-map (lambda (num) (* num num)) '(1 2 3 4))
|
|||
|
⇒ '(1 4 9 16)
|
|||
|
(-map 'square '(1 2 3 4))
|
|||
|
⇒ '(1 4 9 16)
|
|||
|
(--map (* it it) '(1 2 3 4))
|
|||
|
⇒ '(1 4 9 16)
|
|||
|
|
|||
|
-- Function: -map-when (pred rep list)
|
|||
|
Return a new list where the elements in LIST that do not match the
|
|||
|
PRED function are unchanged, and where the elements in LIST that do
|
|||
|
match the PRED function are mapped through the REP function.
|
|||
|
|
|||
|
Alias: ‘-replace-where’
|
|||
|
|
|||
|
See also: ‘-update-at’ (*note -update-at::)
|
|||
|
|
|||
|
(-map-when 'even? 'square '(1 2 3 4))
|
|||
|
⇒ '(1 4 3 16)
|
|||
|
(--map-when (> it 2) (* it it) '(1 2 3 4))
|
|||
|
⇒ '(1 2 9 16)
|
|||
|
(--map-when (= it 2) 17 '(1 2 3 4))
|
|||
|
⇒ '(1 17 3 4)
|
|||
|
|
|||
|
-- Function: -map-first (pred rep list)
|
|||
|
Replace first item in LIST satisfying PRED with result of REP
|
|||
|
called on this item.
|
|||
|
|
|||
|
See also: ‘-map-when’ (*note -map-when::), ‘-replace-first’ (*note
|
|||
|
-replace-first::)
|
|||
|
|
|||
|
(-map-first 'even? 'square '(1 2 3 4))
|
|||
|
⇒ '(1 4 3 4)
|
|||
|
(--map-first (> it 2) (* it it) '(1 2 3 4))
|
|||
|
⇒ '(1 2 9 4)
|
|||
|
(--map-first (= it 2) 17 '(1 2 3 2))
|
|||
|
⇒ '(1 17 3 2)
|
|||
|
|
|||
|
-- Function: -map-last (pred rep list)
|
|||
|
Replace last item in LIST satisfying PRED with result of REP called
|
|||
|
on this item.
|
|||
|
|
|||
|
See also: ‘-map-when’ (*note -map-when::), ‘-replace-last’ (*note
|
|||
|
-replace-last::)
|
|||
|
|
|||
|
(-map-last 'even? 'square '(1 2 3 4))
|
|||
|
⇒ '(1 2 3 16)
|
|||
|
(--map-last (> it 2) (* it it) '(1 2 3 4))
|
|||
|
⇒ '(1 2 3 16)
|
|||
|
(--map-last (= it 2) 17 '(1 2 3 2))
|
|||
|
⇒ '(1 2 3 17)
|
|||
|
|
|||
|
-- Function: -map-indexed (fn list)
|
|||
|
Return a new list consisting of the result of (FN index item) for
|
|||
|
each item in LIST.
|
|||
|
|
|||
|
In the anaphoric form ‘--map-indexed’, the index is exposed as
|
|||
|
symbol ‘it-index’.
|
|||
|
|
|||
|
See also: ‘-each-indexed’ (*note -each-indexed::).
|
|||
|
|
|||
|
(-map-indexed (lambda (index item) (- item index)) '(1 2 3 4))
|
|||
|
⇒ '(1 1 1 1)
|
|||
|
(--map-indexed (- it it-index) '(1 2 3 4))
|
|||
|
⇒ '(1 1 1 1)
|
|||
|
|
|||
|
-- Function: -annotate (fn list)
|
|||
|
Return a list of cons cells where each cell is FN applied to each
|
|||
|
element of LIST paired with the unmodified element of LIST.
|
|||
|
|
|||
|
(-annotate '1+ '(1 2 3))
|
|||
|
⇒ '((2 . 1) (3 . 2) (4 . 3))
|
|||
|
(-annotate 'length '(("h" "e" "l" "l" "o") ("hello" "world")))
|
|||
|
⇒ '((5 "h" "e" "l" "l" "o") (2 "hello" "world"))
|
|||
|
(--annotate (< 1 it) '(0 1 2 3))
|
|||
|
⇒ '((nil . 0) (nil . 1) (t . 2) (t . 3))
|
|||
|
|
|||
|
-- Function: -splice (pred fun list)
|
|||
|
Splice lists generated by FUN in place of elements matching PRED in
|
|||
|
LIST.
|
|||
|
|
|||
|
FUN takes the element matching PRED as input.
|
|||
|
|
|||
|
This function can be used as replacement for ‘,@’ in case you need
|
|||
|
to splice several lists at marked positions (for example with
|
|||
|
keywords).
|
|||
|
|
|||
|
See also: ‘-splice-list’ (*note -splice-list::), ‘-insert-at’
|
|||
|
(*note -insert-at::)
|
|||
|
|
|||
|
(-splice 'even? (lambda (x) (list x x)) '(1 2 3 4))
|
|||
|
⇒ '(1 2 2 3 4 4)
|
|||
|
(--splice 't (list it it) '(1 2 3 4))
|
|||
|
⇒ '(1 1 2 2 3 3 4 4)
|
|||
|
(--splice (equal it :magic) '((list of) (magical) (code)) '((foo) (bar) :magic (baz)))
|
|||
|
⇒ '((foo) (bar) (list of) (magical) (code) (baz))
|
|||
|
|
|||
|
-- Function: -splice-list (pred new-list list)
|
|||
|
Splice NEW-LIST in place of elements matching PRED in LIST.
|
|||
|
|
|||
|
See also: ‘-splice’ (*note -splice::), ‘-insert-at’ (*note
|
|||
|
-insert-at::)
|
|||
|
|
|||
|
(-splice-list 'keywordp '(a b c) '(1 :foo 2))
|
|||
|
⇒ '(1 a b c 2)
|
|||
|
(-splice-list 'keywordp nil '(1 :foo 2))
|
|||
|
⇒ '(1 2)
|
|||
|
(--splice-list (keywordp it) '(a b c) '(1 :foo 2))
|
|||
|
⇒ '(1 a b c 2)
|
|||
|
|
|||
|
-- Function: -mapcat (fn list)
|
|||
|
Return the concatenation of the result of mapping FN over LIST.
|
|||
|
Thus function FN should return a list.
|
|||
|
|
|||
|
(-mapcat 'list '(1 2 3))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-mapcat (lambda (item) (list 0 item)) '(1 2 3))
|
|||
|
⇒ '(0 1 0 2 0 3)
|
|||
|
(--mapcat (list 0 it) '(1 2 3))
|
|||
|
⇒ '(0 1 0 2 0 3)
|
|||
|
|
|||
|
-- Function: -copy (arg)
|
|||
|
Create a shallow copy of LIST.
|
|||
|
|
|||
|
(fn LIST)
|
|||
|
|
|||
|
(-copy '(1 2 3))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(let ((a '(1 2 3))) (eq a (-copy a)))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Sublist selection, Next: List to list, Prev: Maps, Up: Functions
|
|||
|
|
|||
|
2.2 Sublist selection
|
|||
|
=====================
|
|||
|
|
|||
|
Functions returning a sublist of the original list.
|
|||
|
|
|||
|
-- Function: -filter (pred list)
|
|||
|
Return a new list of the items in LIST for which PRED returns a
|
|||
|
non-nil value.
|
|||
|
|
|||
|
Alias: ‘-select’
|
|||
|
|
|||
|
See also: ‘-keep’ (*note -keep::), ‘-remove’ (*note -remove::).
|
|||
|
|
|||
|
(-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
|
|||
|
⇒ '(2 4)
|
|||
|
(-filter 'even? '(1 2 3 4))
|
|||
|
⇒ '(2 4)
|
|||
|
(--filter (= 0 (% it 2)) '(1 2 3 4))
|
|||
|
⇒ '(2 4)
|
|||
|
|
|||
|
-- Function: -remove (pred list)
|
|||
|
Return a new list of the items in LIST for which PRED returns nil.
|
|||
|
|
|||
|
Alias: ‘-reject’
|
|||
|
|
|||
|
See also: ‘-filter’ (*note -filter::).
|
|||
|
|
|||
|
(-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
|
|||
|
⇒ '(1 3)
|
|||
|
(-remove 'even? '(1 2 3 4))
|
|||
|
⇒ '(1 3)
|
|||
|
(--remove (= 0 (% it 2)) '(1 2 3 4))
|
|||
|
⇒ '(1 3)
|
|||
|
|
|||
|
-- Function: -remove-first (pred list)
|
|||
|
Return a new list with the first item matching PRED removed.
|
|||
|
|
|||
|
Alias: ‘-reject-first’
|
|||
|
|
|||
|
See also: ‘-remove’ (*note -remove::), ‘-map-first’ (*note
|
|||
|
-map-first::)
|
|||
|
|
|||
|
(-remove-first 'even? '(1 3 5 4 7 8 10))
|
|||
|
⇒ '(1 3 5 7 8 10)
|
|||
|
(-remove-first 'stringp '(1 2 "first" "second" "third"))
|
|||
|
⇒ '(1 2 "second" "third")
|
|||
|
(--remove-first (> it 3) '(1 2 3 4 5 6 7 8 9 10))
|
|||
|
⇒ '(1 2 3 5 6 7 8 9 10)
|
|||
|
|
|||
|
-- Function: -remove-last (pred list)
|
|||
|
Return a new list with the last item matching PRED removed.
|
|||
|
|
|||
|
Alias: ‘-reject-last’
|
|||
|
|
|||
|
See also: ‘-remove’ (*note -remove::), ‘-map-last’ (*note
|
|||
|
-map-last::)
|
|||
|
|
|||
|
(-remove-last 'even? '(1 3 5 4 7 8 10 11))
|
|||
|
⇒ '(1 3 5 4 7 8 11)
|
|||
|
(-remove-last 'stringp '(1 2 "last" "second" "third"))
|
|||
|
⇒ '(1 2 "last" "second")
|
|||
|
(--remove-last (> it 3) '(1 2 3 4 5 6 7 8 9 10))
|
|||
|
⇒ '(1 2 3 4 5 6 7 8 9)
|
|||
|
|
|||
|
-- Function: -remove-item (item list)
|
|||
|
Remove all occurrences of ITEM from LIST.
|
|||
|
|
|||
|
Comparison is done with ‘equal’.
|
|||
|
|
|||
|
(-remove-item 3 '(1 2 3 2 3 4 5 3))
|
|||
|
⇒ '(1 2 2 4 5)
|
|||
|
(-remove-item 'foo '(foo bar baz foo))
|
|||
|
⇒ '(bar baz)
|
|||
|
(-remove-item "bob" '("alice" "bob" "eve" "bob" "dave"))
|
|||
|
⇒ '("alice" "eve" "dave")
|
|||
|
|
|||
|
-- Function: -non-nil (list)
|
|||
|
Return all non-nil elements of LIST.
|
|||
|
|
|||
|
(-non-nil '(1 nil 2 nil nil 3 4 nil 5 nil))
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
|
|||
|
-- Function: -slice (list from &optional to step)
|
|||
|
Return copy of LIST, starting from index FROM to index TO.
|
|||
|
|
|||
|
FROM or TO may be negative. These values are then interpreted
|
|||
|
modulo the length of the list.
|
|||
|
|
|||
|
If STEP is a number, only each STEPth item in the resulting section
|
|||
|
is returned. Defaults to 1.
|
|||
|
|
|||
|
(-slice '(1 2 3 4 5) 1)
|
|||
|
⇒ '(2 3 4 5)
|
|||
|
(-slice '(1 2 3 4 5) 0 3)
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-slice '(1 2 3 4 5 6 7 8 9) 1 -1 2)
|
|||
|
⇒ '(2 4 6 8)
|
|||
|
|
|||
|
-- Function: -take (n list)
|
|||
|
Return a new list of the first N items in LIST, or all items if
|
|||
|
there are fewer than N.
|
|||
|
|
|||
|
See also: ‘-take-last’ (*note -take-last::)
|
|||
|
|
|||
|
(-take 3 '(1 2 3 4 5))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-take 17 '(1 2 3 4 5))
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
|
|||
|
-- Function: -take-last (n list)
|
|||
|
Return the last N items of LIST in order.
|
|||
|
|
|||
|
See also: ‘-take’ (*note -take::)
|
|||
|
|
|||
|
(-take-last 3 '(1 2 3 4 5))
|
|||
|
⇒ '(3 4 5)
|
|||
|
(-take-last 17 '(1 2 3 4 5))
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
(-take-last 1 '(1 2 3 4 5))
|
|||
|
⇒ '(5)
|
|||
|
|
|||
|
-- Function: -drop (n list)
|
|||
|
Return the tail of LIST without the first N items.
|
|||
|
|
|||
|
See also: ‘-drop-last’ (*note -drop-last::)
|
|||
|
|
|||
|
(fn N LIST)
|
|||
|
|
|||
|
(-drop 3 '(1 2 3 4 5))
|
|||
|
⇒ '(4 5)
|
|||
|
(-drop 17 '(1 2 3 4 5))
|
|||
|
⇒ '()
|
|||
|
|
|||
|
-- Function: -drop-last (n list)
|
|||
|
Remove the last N items of LIST and return a copy.
|
|||
|
|
|||
|
See also: ‘-drop’ (*note -drop::)
|
|||
|
|
|||
|
(-drop-last 3 '(1 2 3 4 5))
|
|||
|
⇒ '(1 2)
|
|||
|
(-drop-last 17 '(1 2 3 4 5))
|
|||
|
⇒ '()
|
|||
|
|
|||
|
-- Function: -take-while (pred list)
|
|||
|
Return a new list of successive items from LIST while (PRED item)
|
|||
|
returns a non-nil value.
|
|||
|
|
|||
|
(-take-while 'even? '(1 2 3 4))
|
|||
|
⇒ '()
|
|||
|
(-take-while 'even? '(2 4 5 6))
|
|||
|
⇒ '(2 4)
|
|||
|
(--take-while (< it 4) '(1 2 3 4 3 2 1))
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
-- Function: -drop-while (pred list)
|
|||
|
Return the tail of LIST starting from the first item for which
|
|||
|
(PRED item) returns nil.
|
|||
|
|
|||
|
(-drop-while 'even? '(1 2 3 4))
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
(-drop-while 'even? '(2 4 5 6))
|
|||
|
⇒ '(5 6)
|
|||
|
(--drop-while (< it 4) '(1 2 3 4 3 2 1))
|
|||
|
⇒ '(4 3 2 1)
|
|||
|
|
|||
|
-- Function: -select-by-indices (indices list)
|
|||
|
Return a list whose elements are elements from LIST selected as
|
|||
|
‘(nth i list)‘ for all i from INDICES.
|
|||
|
|
|||
|
(-select-by-indices '(4 10 2 3 6) '("v" "e" "l" "o" "c" "i" "r" "a" "p" "t" "o" "r"))
|
|||
|
⇒ '("c" "o" "l" "o" "r")
|
|||
|
(-select-by-indices '(2 1 0) '("a" "b" "c"))
|
|||
|
⇒ '("c" "b" "a")
|
|||
|
(-select-by-indices '(0 1 2 0 1 3 3 1) '("f" "a" "r" "l"))
|
|||
|
⇒ '("f" "a" "r" "f" "a" "l" "l" "a")
|
|||
|
|
|||
|
-- Function: -select-columns (columns table)
|
|||
|
Select COLUMNS from TABLE.
|
|||
|
|
|||
|
TABLE is a list of lists where each element represents one row. It
|
|||
|
is assumed each row has the same length.
|
|||
|
|
|||
|
Each row is transformed such that only the specified COLUMNS are
|
|||
|
selected.
|
|||
|
|
|||
|
See also: ‘-select-column’ (*note -select-column::),
|
|||
|
‘-select-by-indices’ (*note -select-by-indices::)
|
|||
|
|
|||
|
(-select-columns '(0 2) '((1 2 3) (a b c) (:a :b :c)))
|
|||
|
⇒ '((1 3) (a c) (:a :c))
|
|||
|
(-select-columns '(1) '((1 2 3) (a b c) (:a :b :c)))
|
|||
|
⇒ '((2) (b) (:b))
|
|||
|
(-select-columns nil '((1 2 3) (a b c) (:a :b :c)))
|
|||
|
⇒ '(nil nil nil)
|
|||
|
|
|||
|
-- Function: -select-column (column table)
|
|||
|
Select COLUMN from TABLE.
|
|||
|
|
|||
|
TABLE is a list of lists where each element represents one row. It
|
|||
|
is assumed each row has the same length.
|
|||
|
|
|||
|
The single selected column is returned as a list.
|
|||
|
|
|||
|
See also: ‘-select-columns’ (*note -select-columns::),
|
|||
|
‘-select-by-indices’ (*note -select-by-indices::)
|
|||
|
|
|||
|
(-select-column 1 '((1 2 3) (a b c) (:a :b :c)))
|
|||
|
⇒ '(2 b :b)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: List to list, Next: Reductions, Prev: Sublist selection, Up: Functions
|
|||
|
|
|||
|
2.3 List to list
|
|||
|
================
|
|||
|
|
|||
|
Functions returning a modified copy of the input list.
|
|||
|
|
|||
|
-- Function: -keep (fn list)
|
|||
|
Return a new list of the non-nil results of applying FN to the
|
|||
|
items in LIST.
|
|||
|
|
|||
|
If you want to select the original items satisfying a predicate use
|
|||
|
‘-filter’ (*note -filter::).
|
|||
|
|
|||
|
(-keep 'cdr '((1 2 3) (4 5) (6)))
|
|||
|
⇒ '((2 3) (5))
|
|||
|
(-keep (lambda (num) (when (> num 3) (* 10 num))) '(1 2 3 4 5 6))
|
|||
|
⇒ '(40 50 60)
|
|||
|
(--keep (when (> it 3) (* 10 it)) '(1 2 3 4 5 6))
|
|||
|
⇒ '(40 50 60)
|
|||
|
|
|||
|
-- Function: -concat (&rest lists)
|
|||
|
Return a new list with the concatenation of the elements in the
|
|||
|
supplied LISTS.
|
|||
|
|
|||
|
(-concat '(1))
|
|||
|
⇒ '(1)
|
|||
|
(-concat '(1) '(2))
|
|||
|
⇒ '(1 2)
|
|||
|
(-concat '(1) '(2 3) '(4))
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
|
|||
|
-- Function: -flatten (l)
|
|||
|
Take a nested list L and return its contents as a single, flat
|
|||
|
list.
|
|||
|
|
|||
|
Note that because ‘nil’ represents a list of zero elements (an
|
|||
|
empty list), any mention of nil in L will disappear after
|
|||
|
flattening. If you need to preserve nils, consider ‘-flatten-n’
|
|||
|
(*note -flatten-n::) or map them to some unique symbol and then map
|
|||
|
them back.
|
|||
|
|
|||
|
Conses of two atoms are considered "terminals", that is, they
|
|||
|
aren’t flattened further.
|
|||
|
|
|||
|
See also: ‘-flatten-n’ (*note -flatten-n::)
|
|||
|
|
|||
|
(-flatten '((1)))
|
|||
|
⇒ '(1)
|
|||
|
(-flatten '((1 (2 3) (((4 (5)))))))
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
(-flatten '(1 2 (3 . 4)))
|
|||
|
⇒ '(1 2 (3 . 4))
|
|||
|
|
|||
|
-- Function: -flatten-n (num list)
|
|||
|
Flatten NUM levels of a nested LIST.
|
|||
|
|
|||
|
See also: ‘-flatten’ (*note -flatten::)
|
|||
|
|
|||
|
(-flatten-n 1 '((1 2) ((3 4) ((5 6)))))
|
|||
|
⇒ '(1 2 (3 4) ((5 6)))
|
|||
|
(-flatten-n 2 '((1 2) ((3 4) ((5 6)))))
|
|||
|
⇒ '(1 2 3 4 (5 6))
|
|||
|
(-flatten-n 3 '((1 2) ((3 4) ((5 6)))))
|
|||
|
⇒ '(1 2 3 4 5 6)
|
|||
|
|
|||
|
-- Function: -replace (old new list)
|
|||
|
Replace all OLD items in LIST with NEW.
|
|||
|
|
|||
|
Elements are compared using ‘equal’.
|
|||
|
|
|||
|
See also: ‘-replace-at’ (*note -replace-at::)
|
|||
|
|
|||
|
(-replace 1 "1" '(1 2 3 4 3 2 1))
|
|||
|
⇒ '("1" 2 3 4 3 2 "1")
|
|||
|
(-replace "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
|
|||
|
⇒ '("a" "nice" "bar" "sentence" "about" "bar")
|
|||
|
(-replace 1 2 nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -replace-first (old new list)
|
|||
|
Replace the first occurrence of OLD with NEW in LIST.
|
|||
|
|
|||
|
Elements are compared using ‘equal’.
|
|||
|
|
|||
|
See also: ‘-map-first’ (*note -map-first::)
|
|||
|
|
|||
|
(-replace-first 1 "1" '(1 2 3 4 3 2 1))
|
|||
|
⇒ '("1" 2 3 4 3 2 1)
|
|||
|
(-replace-first "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
|
|||
|
⇒ '("a" "nice" "bar" "sentence" "about" "foo")
|
|||
|
(-replace-first 1 2 nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -replace-last (old new list)
|
|||
|
Replace the last occurrence of OLD with NEW in LIST.
|
|||
|
|
|||
|
Elements are compared using ‘equal’.
|
|||
|
|
|||
|
See also: ‘-map-last’ (*note -map-last::)
|
|||
|
|
|||
|
(-replace-last 1 "1" '(1 2 3 4 3 2 1))
|
|||
|
⇒ '(1 2 3 4 3 2 "1")
|
|||
|
(-replace-last "foo" "bar" '("a" "nice" "foo" "sentence" "about" "foo"))
|
|||
|
⇒ '("a" "nice" "foo" "sentence" "about" "bar")
|
|||
|
(-replace-last 1 2 nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -insert-at (n x list)
|
|||
|
Return a list with X inserted into LIST at position N.
|
|||
|
|
|||
|
See also: ‘-splice’ (*note -splice::), ‘-splice-list’ (*note
|
|||
|
-splice-list::)
|
|||
|
|
|||
|
(-insert-at 1 'x '(a b c))
|
|||
|
⇒ '(a x b c)
|
|||
|
(-insert-at 12 'x '(a b c))
|
|||
|
⇒ '(a b c x)
|
|||
|
|
|||
|
-- Function: -replace-at (n x list)
|
|||
|
Return a list with element at Nth position in LIST replaced with X.
|
|||
|
|
|||
|
See also: ‘-replace’ (*note -replace::)
|
|||
|
|
|||
|
(-replace-at 0 9 '(0 1 2 3 4 5))
|
|||
|
⇒ '(9 1 2 3 4 5)
|
|||
|
(-replace-at 1 9 '(0 1 2 3 4 5))
|
|||
|
⇒ '(0 9 2 3 4 5)
|
|||
|
(-replace-at 4 9 '(0 1 2 3 4 5))
|
|||
|
⇒ '(0 1 2 3 9 5)
|
|||
|
|
|||
|
-- Function: -update-at (n func list)
|
|||
|
Return a list with element at Nth position in LIST replaced with
|
|||
|
‘(func (nth n list))‘.
|
|||
|
|
|||
|
See also: ‘-map-when’ (*note -map-when::)
|
|||
|
|
|||
|
(-update-at 0 (lambda (x) (+ x 9)) '(0 1 2 3 4 5))
|
|||
|
⇒ '(9 1 2 3 4 5)
|
|||
|
(-update-at 1 (lambda (x) (+ x 8)) '(0 1 2 3 4 5))
|
|||
|
⇒ '(0 9 2 3 4 5)
|
|||
|
(--update-at 2 (length it) '("foo" "bar" "baz" "quux"))
|
|||
|
⇒ '("foo" "bar" 3 "quux")
|
|||
|
|
|||
|
-- Function: -remove-at (n list)
|
|||
|
Return a list with element at Nth position in LIST removed.
|
|||
|
|
|||
|
See also: ‘-remove-at-indices’ (*note -remove-at-indices::),
|
|||
|
‘-remove’ (*note -remove::)
|
|||
|
|
|||
|
(-remove-at 0 '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("1" "2" "3" "4" "5")
|
|||
|
(-remove-at 1 '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("0" "2" "3" "4" "5")
|
|||
|
(-remove-at 2 '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("0" "1" "3" "4" "5")
|
|||
|
|
|||
|
-- Function: -remove-at-indices (indices list)
|
|||
|
Return a list whose elements are elements from LIST without
|
|||
|
elements selected as ‘(nth i list)‘ for all i from INDICES.
|
|||
|
|
|||
|
See also: ‘-remove-at’ (*note -remove-at::), ‘-remove’ (*note
|
|||
|
-remove::)
|
|||
|
|
|||
|
(-remove-at-indices '(0) '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("1" "2" "3" "4" "5")
|
|||
|
(-remove-at-indices '(0 2 4) '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("1" "3" "5")
|
|||
|
(-remove-at-indices '(0 5) '("0" "1" "2" "3" "4" "5"))
|
|||
|
⇒ '("1" "2" "3" "4")
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Reductions, Next: Unfolding, Prev: List to list, Up: Functions
|
|||
|
|
|||
|
2.4 Reductions
|
|||
|
==============
|
|||
|
|
|||
|
Functions reducing lists into single value.
|
|||
|
|
|||
|
-- Function: -reduce-from (fn initial-value list)
|
|||
|
Return the result of applying FN to INITIAL-VALUE and the first
|
|||
|
item in LIST, then applying FN to that result and the 2nd item,
|
|||
|
etc. If LIST contains no items, return INITIAL-VALUE and do not
|
|||
|
call FN.
|
|||
|
|
|||
|
In the anaphoric form ‘--reduce-from’, the accumulated value is
|
|||
|
exposed as symbol ‘acc’.
|
|||
|
|
|||
|
See also: ‘-reduce’ (*note -reduce::), ‘-reduce-r’ (*note
|
|||
|
-reduce-r::)
|
|||
|
|
|||
|
(-reduce-from '- 10 '(1 2 3))
|
|||
|
⇒ 4
|
|||
|
(-reduce-from (lambda (memo item) (format "(%s - %d)" memo item)) "10" '(1 2 3))
|
|||
|
⇒ "(((10 - 1) - 2) - 3)"
|
|||
|
(--reduce-from (concat acc " " it) "START" '("a" "b" "c"))
|
|||
|
⇒ "START a b c"
|
|||
|
|
|||
|
-- Function: -reduce-r-from (fn initial-value list)
|
|||
|
Replace conses with FN, nil with INITIAL-VALUE and evaluate the
|
|||
|
resulting expression. If LIST is empty, INITIAL-VALUE is returned
|
|||
|
and FN is not called.
|
|||
|
|
|||
|
Note: this function works the same as ‘-reduce-from’ (*note
|
|||
|
-reduce-from::) but the operation associates from right instead of
|
|||
|
from left.
|
|||
|
|
|||
|
See also: ‘-reduce-r’ (*note -reduce-r::), ‘-reduce’ (*note
|
|||
|
-reduce::)
|
|||
|
|
|||
|
(-reduce-r-from '- 10 '(1 2 3))
|
|||
|
⇒ -8
|
|||
|
(-reduce-r-from (lambda (item memo) (format "(%d - %s)" item memo)) "10" '(1 2 3))
|
|||
|
⇒ "(1 - (2 - (3 - 10)))"
|
|||
|
(--reduce-r-from (concat it " " acc) "END" '("a" "b" "c"))
|
|||
|
⇒ "a b c END"
|
|||
|
|
|||
|
-- Function: -reduce (fn list)
|
|||
|
Return the result of applying FN to the first 2 items in LIST, then
|
|||
|
applying FN to that result and the 3rd item, etc. If LIST contains
|
|||
|
no items, return the result of calling FN with no arguments. If
|
|||
|
LIST contains a single item, return that item and do not call FN.
|
|||
|
|
|||
|
In the anaphoric form ‘--reduce’, the accumulated value is exposed
|
|||
|
as symbol ‘acc’.
|
|||
|
|
|||
|
See also: ‘-reduce-from’ (*note -reduce-from::), ‘-reduce-r’ (*note
|
|||
|
-reduce-r::)
|
|||
|
|
|||
|
(-reduce '- '(1 2 3 4))
|
|||
|
⇒ -8
|
|||
|
(-reduce 'list '(1 2 3 4))
|
|||
|
⇒ '(((1 2) 3) 4)
|
|||
|
(--reduce (format "%s-%d" acc it) '(1 2 3))
|
|||
|
⇒ "1-2-3"
|
|||
|
|
|||
|
-- Function: -reduce-r (fn list)
|
|||
|
Replace conses with FN and evaluate the resulting expression. The
|
|||
|
final nil is ignored. If LIST contains no items, return the result
|
|||
|
of calling FN with no arguments. If LIST contains a single item,
|
|||
|
return that item and do not call FN.
|
|||
|
|
|||
|
The first argument of FN is the new item, the second is the
|
|||
|
accumulated value.
|
|||
|
|
|||
|
Note: this function works the same as ‘-reduce’ (*note -reduce::)
|
|||
|
but the operation associates from right instead of from left.
|
|||
|
|
|||
|
See also: ‘-reduce-r-from’ (*note -reduce-r-from::), ‘-reduce’
|
|||
|
(*note -reduce::)
|
|||
|
|
|||
|
(-reduce-r '- '(1 2 3 4))
|
|||
|
⇒ -2
|
|||
|
(-reduce-r (lambda (item memo) (format "%s-%d" memo item)) '(1 2 3))
|
|||
|
⇒ "3-2-1"
|
|||
|
(--reduce-r (format "%s-%d" acc it) '(1 2 3))
|
|||
|
⇒ "3-2-1"
|
|||
|
|
|||
|
-- Function: -reductions-from (fn init list)
|
|||
|
Return a list of the intermediate values of the reduction.
|
|||
|
|
|||
|
See ‘-reduce-from’ (*note -reduce-from::) for explanation of the
|
|||
|
arguments.
|
|||
|
|
|||
|
See also: ‘-reductions’ (*note -reductions::), ‘-reductions-r’
|
|||
|
(*note -reductions-r::), ‘-reduce-r’ (*note -reduce-r::)
|
|||
|
|
|||
|
(-reductions-from (lambda (a i) (format "(%s FN %d)" a i)) "INIT" '(1 2 3 4))
|
|||
|
⇒ '("INIT" "(INIT FN 1)" "((INIT FN 1) FN 2)" "(((INIT FN 1) FN 2) FN 3)" "((((INIT FN 1) FN 2) FN 3) FN 4)")
|
|||
|
(-reductions-from 'max 0 '(2 1 4 3))
|
|||
|
⇒ '(0 2 2 4 4)
|
|||
|
(-reductions-from '* 1 '(1 2 3 4))
|
|||
|
⇒ '(1 1 2 6 24)
|
|||
|
|
|||
|
-- Function: -reductions-r-from (fn init list)
|
|||
|
Return a list of the intermediate values of the reduction.
|
|||
|
|
|||
|
See ‘-reduce-r-from’ (*note -reduce-r-from::) for explanation of
|
|||
|
the arguments.
|
|||
|
|
|||
|
See also: ‘-reductions-r’ (*note -reductions-r::), ‘-reductions’
|
|||
|
(*note -reductions::), ‘-reduce’ (*note -reduce::)
|
|||
|
|
|||
|
(-reductions-r-from (lambda (i a) (format "(%d FN %s)" i a)) "INIT" '(1 2 3 4))
|
|||
|
⇒ '("(1 FN (2 FN (3 FN (4 FN INIT))))" "(2 FN (3 FN (4 FN INIT)))" "(3 FN (4 FN INIT))" "(4 FN INIT)" "INIT")
|
|||
|
(-reductions-r-from 'max 0 '(2 1 4 3))
|
|||
|
⇒ '(4 4 4 3 0)
|
|||
|
(-reductions-r-from '* 1 '(1 2 3 4))
|
|||
|
⇒ '(24 24 12 4 1)
|
|||
|
|
|||
|
-- Function: -reductions (fn list)
|
|||
|
Return a list of the intermediate values of the reduction.
|
|||
|
|
|||
|
See ‘-reduce’ (*note -reduce::) for explanation of the arguments.
|
|||
|
|
|||
|
See also: ‘-reductions-from’ (*note -reductions-from::),
|
|||
|
‘-reductions-r’ (*note -reductions-r::), ‘-reduce-r’ (*note
|
|||
|
-reduce-r::)
|
|||
|
|
|||
|
(-reductions (lambda (a i) (format "(%s FN %d)" a i)) '(1 2 3 4))
|
|||
|
⇒ '(1 "(1 FN 2)" "((1 FN 2) FN 3)" "(((1 FN 2) FN 3) FN 4)")
|
|||
|
(-reductions '+ '(1 2 3 4))
|
|||
|
⇒ '(1 3 6 10)
|
|||
|
(-reductions '* '(1 2 3 4))
|
|||
|
⇒ '(1 2 6 24)
|
|||
|
|
|||
|
-- Function: -reductions-r (fn list)
|
|||
|
Return a list of the intermediate values of the reduction.
|
|||
|
|
|||
|
See ‘-reduce-r’ (*note -reduce-r::) for explanation of the
|
|||
|
arguments.
|
|||
|
|
|||
|
See also: ‘-reductions-r-from’ (*note -reductions-r-from::),
|
|||
|
‘-reductions’ (*note -reductions::), ‘-reduce’ (*note -reduce::)
|
|||
|
|
|||
|
(-reductions-r (lambda (i a) (format "(%d FN %s)" i a)) '(1 2 3 4))
|
|||
|
⇒ '("(1 FN (2 FN (3 FN 4)))" "(2 FN (3 FN 4))" "(3 FN 4)" 4)
|
|||
|
(-reductions-r '+ '(1 2 3 4))
|
|||
|
⇒ '(10 9 7 4)
|
|||
|
(-reductions-r '* '(1 2 3 4))
|
|||
|
⇒ '(24 24 12 4)
|
|||
|
|
|||
|
-- Function: -count (pred list)
|
|||
|
Counts the number of items in LIST where (PRED item) is non-nil.
|
|||
|
|
|||
|
(-count 'even? '(1 2 3 4 5))
|
|||
|
⇒ 2
|
|||
|
(--count (< it 4) '(1 2 3 4))
|
|||
|
⇒ 3
|
|||
|
|
|||
|
-- Function: -sum (list)
|
|||
|
Return the sum of LIST.
|
|||
|
|
|||
|
(-sum '())
|
|||
|
⇒ 0
|
|||
|
(-sum '(1))
|
|||
|
⇒ 1
|
|||
|
(-sum '(1 2 3 4))
|
|||
|
⇒ 10
|
|||
|
|
|||
|
-- Function: -running-sum (list)
|
|||
|
Return a list with running sums of items in LIST.
|
|||
|
|
|||
|
LIST must be non-empty.
|
|||
|
|
|||
|
(-running-sum '(1 2 3 4))
|
|||
|
⇒ '(1 3 6 10)
|
|||
|
(-running-sum '(1))
|
|||
|
⇒ '(1)
|
|||
|
(-running-sum '())
|
|||
|
⇒ error
|
|||
|
|
|||
|
-- Function: -product (list)
|
|||
|
Return the product of LIST.
|
|||
|
|
|||
|
(-product '())
|
|||
|
⇒ 1
|
|||
|
(-product '(1))
|
|||
|
⇒ 1
|
|||
|
(-product '(1 2 3 4))
|
|||
|
⇒ 24
|
|||
|
|
|||
|
-- Function: -running-product (list)
|
|||
|
Return a list with running products of items in LIST.
|
|||
|
|
|||
|
LIST must be non-empty.
|
|||
|
|
|||
|
(-running-product '(1 2 3 4))
|
|||
|
⇒ '(1 2 6 24)
|
|||
|
(-running-product '(1))
|
|||
|
⇒ '(1)
|
|||
|
(-running-product '())
|
|||
|
⇒ error
|
|||
|
|
|||
|
-- Function: -inits (list)
|
|||
|
Return all prefixes of LIST.
|
|||
|
|
|||
|
(-inits '(1 2 3 4))
|
|||
|
⇒ '(nil (1) (1 2) (1 2 3) (1 2 3 4))
|
|||
|
(-inits nil)
|
|||
|
⇒ '(nil)
|
|||
|
(-inits '(1))
|
|||
|
⇒ '(nil (1))
|
|||
|
|
|||
|
-- Function: -tails (list)
|
|||
|
Return all suffixes of LIST
|
|||
|
|
|||
|
(-tails '(1 2 3 4))
|
|||
|
⇒ '((1 2 3 4) (2 3 4) (3 4) (4) nil)
|
|||
|
(-tails nil)
|
|||
|
⇒ '(nil)
|
|||
|
(-tails '(1))
|
|||
|
⇒ '((1) nil)
|
|||
|
|
|||
|
-- Function: -common-prefix (&rest lists)
|
|||
|
Return the longest common prefix of LISTS.
|
|||
|
|
|||
|
(-common-prefix '(1))
|
|||
|
⇒ '(1)
|
|||
|
(-common-prefix '(1 2) '(3 4) '(1 2))
|
|||
|
⇒ nil
|
|||
|
(-common-prefix '(1 2) '(1 2 3) '(1 2 3 4))
|
|||
|
⇒ '(1 2)
|
|||
|
|
|||
|
-- Function: -common-suffix (&rest lists)
|
|||
|
Return the longest common suffix of LISTS.
|
|||
|
|
|||
|
(-common-suffix '(1))
|
|||
|
⇒ '(1)
|
|||
|
(-common-suffix '(1 2) '(3 4) '(1 2))
|
|||
|
⇒ nil
|
|||
|
(-common-suffix '(1 2 3 4) '(2 3 4) '(3 4))
|
|||
|
⇒ '(3 4)
|
|||
|
|
|||
|
-- Function: -min (list)
|
|||
|
Return the smallest value from LIST of numbers or markers.
|
|||
|
|
|||
|
(-min '(0))
|
|||
|
⇒ 0
|
|||
|
(-min '(3 2 1))
|
|||
|
⇒ 1
|
|||
|
(-min '(1 2 3))
|
|||
|
⇒ 1
|
|||
|
|
|||
|
-- Function: -min-by (comparator list)
|
|||
|
Take a comparison function COMPARATOR and a LIST and return the
|
|||
|
least element of the list by the comparison function.
|
|||
|
|
|||
|
See also combinator ‘-on’ (*note -on::) which can transform the
|
|||
|
values before comparing them.
|
|||
|
|
|||
|
(-min-by '> '(4 3 6 1))
|
|||
|
⇒ 1
|
|||
|
(--min-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(--min-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
|
|||
|
⇒ '(2)
|
|||
|
|
|||
|
-- Function: -max (list)
|
|||
|
Return the largest value from LIST of numbers or markers.
|
|||
|
|
|||
|
(-max '(0))
|
|||
|
⇒ 0
|
|||
|
(-max '(3 2 1))
|
|||
|
⇒ 3
|
|||
|
(-max '(1 2 3))
|
|||
|
⇒ 3
|
|||
|
|
|||
|
-- Function: -max-by (comparator list)
|
|||
|
Take a comparison function COMPARATOR and a LIST and return the
|
|||
|
greatest element of the list by the comparison function.
|
|||
|
|
|||
|
See also combinator ‘-on’ (*note -on::) which can transform the
|
|||
|
values before comparing them.
|
|||
|
|
|||
|
(-max-by '> '(4 3 6 1))
|
|||
|
⇒ 6
|
|||
|
(--max-by (> (car it) (car other)) '((1 2 3) (2) (3 2)))
|
|||
|
⇒ '(3 2)
|
|||
|
(--max-by (> (length it) (length other)) '((1 2 3) (2) (3 2)))
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Unfolding, Next: Predicates, Prev: Reductions, Up: Functions
|
|||
|
|
|||
|
2.5 Unfolding
|
|||
|
=============
|
|||
|
|
|||
|
Operations dual to reductions, building lists from seed value rather
|
|||
|
than consuming a list to produce a single value.
|
|||
|
|
|||
|
-- Function: -iterate (fun init n)
|
|||
|
Return a list of iterated applications of FUN to INIT.
|
|||
|
|
|||
|
This means a list of form:
|
|||
|
|
|||
|
(init (fun init) (fun (fun init)) ...)
|
|||
|
|
|||
|
N is the length of the returned list.
|
|||
|
|
|||
|
(-iterate '1+ 1 10)
|
|||
|
⇒ '(1 2 3 4 5 6 7 8 9 10)
|
|||
|
(-iterate (lambda (x) (+ x x)) 2 5)
|
|||
|
⇒ '(2 4 8 16 32)
|
|||
|
(--iterate (* it it) 2 5)
|
|||
|
⇒ '(2 4 16 256 65536)
|
|||
|
|
|||
|
-- Function: -unfold (fun seed)
|
|||
|
Build a list from SEED using FUN.
|
|||
|
|
|||
|
This is "dual" operation to ‘-reduce-r’ (*note -reduce-r::): while
|
|||
|
-reduce-r consumes a list to produce a single value, ‘-unfold’
|
|||
|
(*note -unfold::) takes a seed value and builds a (potentially
|
|||
|
infinite!) list.
|
|||
|
|
|||
|
FUN should return ‘nil’ to stop the generating process, or a cons
|
|||
|
(A . B), where A will be prepended to the result and B is the new
|
|||
|
seed.
|
|||
|
|
|||
|
(-unfold (lambda (x) (unless (= x 0) (cons x (1- x)))) 10)
|
|||
|
⇒ '(10 9 8 7 6 5 4 3 2 1)
|
|||
|
(--unfold (when it (cons it (cdr it))) '(1 2 3 4))
|
|||
|
⇒ '((1 2 3 4) (2 3 4) (3 4) (4))
|
|||
|
(--unfold (when it (cons it (butlast it))) '(1 2 3 4))
|
|||
|
⇒ '((1 2 3 4) (1 2 3) (1 2) (1))
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Predicates, Next: Partitioning, Prev: Unfolding, Up: Functions
|
|||
|
|
|||
|
2.6 Predicates
|
|||
|
==============
|
|||
|
|
|||
|
-- Function: -any? (pred list)
|
|||
|
Return t if (PRED x) is non-nil for any x in LIST, else nil.
|
|||
|
|
|||
|
Alias: ‘-any-p’, ‘-some?’, ‘-some-p’
|
|||
|
|
|||
|
(-any? 'even? '(1 2 3))
|
|||
|
⇒ t
|
|||
|
(-any? 'even? '(1 3 5))
|
|||
|
⇒ nil
|
|||
|
(-any? 'null '(1 3 5))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -all? (pred list)
|
|||
|
Return t if (PRED x) is non-nil for all x in LIST, else nil.
|
|||
|
|
|||
|
Alias: ‘-all-p’, ‘-every?’, ‘-every-p’
|
|||
|
|
|||
|
(-all? 'even? '(1 2 3))
|
|||
|
⇒ nil
|
|||
|
(-all? 'even? '(2 4 6))
|
|||
|
⇒ t
|
|||
|
(--all? (= 0 (% it 2)) '(2 4 6))
|
|||
|
⇒ t
|
|||
|
|
|||
|
-- Function: -none? (pred list)
|
|||
|
Return t if (PRED x) is nil for all x in LIST, else nil.
|
|||
|
|
|||
|
Alias: ‘-none-p’
|
|||
|
|
|||
|
(-none? 'even? '(1 2 3))
|
|||
|
⇒ nil
|
|||
|
(-none? 'even? '(1 3 5))
|
|||
|
⇒ t
|
|||
|
(--none? (= 0 (% it 2)) '(1 2 3))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -only-some? (pred list)
|
|||
|
Return ‘t‘ if at least one item of LIST matches PRED and at least
|
|||
|
one item of LIST does not match PRED. Return ‘nil‘ both if all
|
|||
|
items match the predicate or if none of the items match the
|
|||
|
predicate.
|
|||
|
|
|||
|
Alias: ‘-only-some-p’
|
|||
|
|
|||
|
(-only-some? 'even? '(1 2 3))
|
|||
|
⇒ t
|
|||
|
(-only-some? 'even? '(1 3 5))
|
|||
|
⇒ nil
|
|||
|
(-only-some? 'even? '(2 4 6))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -contains? (list element)
|
|||
|
Return non-nil if LIST contains ELEMENT.
|
|||
|
|
|||
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|||
|
if that’s non-nil.
|
|||
|
|
|||
|
Alias: ‘-contains-p’
|
|||
|
|
|||
|
(-contains? '(1 2 3) 1)
|
|||
|
⇒ t
|
|||
|
(-contains? '(1 2 3) 2)
|
|||
|
⇒ t
|
|||
|
(-contains? '(1 2 3) 4)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -same-items? (list list2)
|
|||
|
Return true if LIST and LIST2 has the same items.
|
|||
|
|
|||
|
The order of the elements in the lists does not matter.
|
|||
|
|
|||
|
Alias: ‘-same-items-p’
|
|||
|
|
|||
|
(-same-items? '(1 2 3) '(1 2 3))
|
|||
|
⇒ t
|
|||
|
(-same-items? '(1 2 3) '(3 2 1))
|
|||
|
⇒ t
|
|||
|
(-same-items? '(1 2 3) '(1 2 3 4))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -is-prefix? (prefix list)
|
|||
|
Return non-nil if PREFIX is prefix of LIST.
|
|||
|
|
|||
|
Alias: ‘-is-prefix-p’
|
|||
|
|
|||
|
(-is-prefix? '(1 2 3) '(1 2 3 4 5))
|
|||
|
⇒ t
|
|||
|
(-is-prefix? '(1 2 3 4 5) '(1 2 3))
|
|||
|
⇒ nil
|
|||
|
(-is-prefix? '(1 3) '(1 2 3 4 5))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -is-suffix? (suffix list)
|
|||
|
Return non-nil if SUFFIX is suffix of LIST.
|
|||
|
|
|||
|
Alias: ‘-is-suffix-p’
|
|||
|
|
|||
|
(-is-suffix? '(3 4 5) '(1 2 3 4 5))
|
|||
|
⇒ t
|
|||
|
(-is-suffix? '(1 2 3 4 5) '(3 4 5))
|
|||
|
⇒ nil
|
|||
|
(-is-suffix? '(3 5) '(1 2 3 4 5))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -is-infix? (infix list)
|
|||
|
Return non-nil if INFIX is infix of LIST.
|
|||
|
|
|||
|
This operation runs in O(n^2) time
|
|||
|
|
|||
|
Alias: ‘-is-infix-p’
|
|||
|
|
|||
|
(-is-infix? '(1 2 3) '(1 2 3 4 5))
|
|||
|
⇒ t
|
|||
|
(-is-infix? '(2 3 4) '(1 2 3 4 5))
|
|||
|
⇒ t
|
|||
|
(-is-infix? '(3 4 5) '(1 2 3 4 5))
|
|||
|
⇒ t
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Partitioning, Next: Indexing, Prev: Predicates, Up: Functions
|
|||
|
|
|||
|
2.7 Partitioning
|
|||
|
================
|
|||
|
|
|||
|
Functions partitioning the input list into a list of lists.
|
|||
|
|
|||
|
-- Function: -split-at (n list)
|
|||
|
Return a list of ((-take N LIST) (-drop N LIST)), in no more than
|
|||
|
one pass through the list.
|
|||
|
|
|||
|
(-split-at 3 '(1 2 3 4 5))
|
|||
|
⇒ '((1 2 3) (4 5))
|
|||
|
(-split-at 17 '(1 2 3 4 5))
|
|||
|
⇒ '((1 2 3 4 5) nil)
|
|||
|
|
|||
|
-- Function: -split-with (pred list)
|
|||
|
Return a list of ((-take-while PRED LIST) (-drop-while PRED LIST)),
|
|||
|
in no more than one pass through the list.
|
|||
|
|
|||
|
(-split-with 'even? '(1 2 3 4))
|
|||
|
⇒ '(nil (1 2 3 4))
|
|||
|
(-split-with 'even? '(2 4 5 6))
|
|||
|
⇒ '((2 4) (5 6))
|
|||
|
(--split-with (< it 4) '(1 2 3 4 3 2 1))
|
|||
|
⇒ '((1 2 3) (4 3 2 1))
|
|||
|
|
|||
|
-- Macro: -split-on (item list)
|
|||
|
Split the LIST each time ITEM is found.
|
|||
|
|
|||
|
Unlike ‘-partition-by’ (*note -partition-by::), the ITEM is
|
|||
|
discarded from the results. Empty lists are also removed from the
|
|||
|
result.
|
|||
|
|
|||
|
Comparison is done by ‘equal’.
|
|||
|
|
|||
|
See also ‘-split-when’ (*note -split-when::)
|
|||
|
|
|||
|
(-split-on '| '(Nil | Leaf a | Node [Tree a]))
|
|||
|
⇒ '((Nil) (Leaf a) (Node [Tree a]))
|
|||
|
(-split-on ':endgroup '("a" "b" :endgroup "c" :endgroup "d" "e"))
|
|||
|
⇒ '(("a" "b") ("c") ("d" "e"))
|
|||
|
(-split-on ':endgroup '("a" "b" :endgroup :endgroup "d" "e"))
|
|||
|
⇒ '(("a" "b") ("d" "e"))
|
|||
|
|
|||
|
-- Function: -split-when (fn list)
|
|||
|
Split the LIST on each element where FN returns non-nil.
|
|||
|
|
|||
|
Unlike ‘-partition-by’ (*note -partition-by::), the "matched"
|
|||
|
element is discarded from the results. Empty lists are also
|
|||
|
removed from the result.
|
|||
|
|
|||
|
This function can be thought of as a generalization of
|
|||
|
‘split-string’.
|
|||
|
|
|||
|
(-split-when 'even? '(1 2 3 4 5 6))
|
|||
|
⇒ '((1) (3) (5))
|
|||
|
(-split-when 'even? '(1 2 3 4 6 8 9))
|
|||
|
⇒ '((1) (3) (9))
|
|||
|
(--split-when (memq it '(&optional &rest)) '(a b &optional c d &rest args))
|
|||
|
⇒ '((a b) (c d) (args))
|
|||
|
|
|||
|
-- Function: -separate (pred list)
|
|||
|
Return a list of ((-filter PRED LIST) (-remove PRED LIST)), in one
|
|||
|
pass through the list.
|
|||
|
|
|||
|
(-separate (lambda (num) (= 0 (% num 2))) '(1 2 3 4 5 6 7))
|
|||
|
⇒ '((2 4 6) (1 3 5 7))
|
|||
|
(--separate (< it 5) '(3 7 5 9 3 2 1 4 6))
|
|||
|
⇒ '((3 3 2 1 4) (7 5 9 6))
|
|||
|
(-separate 'cdr '((1 2) (1) (1 2 3) (4)))
|
|||
|
⇒ '(((1 2) (1 2 3)) ((1) (4)))
|
|||
|
|
|||
|
-- Function: -partition (n list)
|
|||
|
Return a new list with the items in LIST grouped into N-sized
|
|||
|
sublists. If there are not enough items to make the last group
|
|||
|
N-sized, those items are discarded.
|
|||
|
|
|||
|
(-partition 2 '(1 2 3 4 5 6))
|
|||
|
⇒ '((1 2) (3 4) (5 6))
|
|||
|
(-partition 2 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '((1 2) (3 4) (5 6))
|
|||
|
(-partition 3 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '((1 2 3) (4 5 6))
|
|||
|
|
|||
|
-- Function: -partition-all (n list)
|
|||
|
Return a new list with the items in LIST grouped into N-sized
|
|||
|
sublists. The last group may contain less than N items.
|
|||
|
|
|||
|
(-partition-all 2 '(1 2 3 4 5 6))
|
|||
|
⇒ '((1 2) (3 4) (5 6))
|
|||
|
(-partition-all 2 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '((1 2) (3 4) (5 6) (7))
|
|||
|
(-partition-all 3 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '((1 2 3) (4 5 6) (7))
|
|||
|
|
|||
|
-- Function: -partition-in-steps (n step list)
|
|||
|
Return a new list with the items in LIST grouped into N-sized
|
|||
|
sublists at offsets STEP apart. If there are not enough items to
|
|||
|
make the last group N-sized, those items are discarded.
|
|||
|
|
|||
|
(-partition-in-steps 2 1 '(1 2 3 4))
|
|||
|
⇒ '((1 2) (2 3) (3 4))
|
|||
|
(-partition-in-steps 3 2 '(1 2 3 4))
|
|||
|
⇒ '((1 2 3))
|
|||
|
(-partition-in-steps 3 2 '(1 2 3 4 5))
|
|||
|
⇒ '((1 2 3) (3 4 5))
|
|||
|
|
|||
|
-- Function: -partition-all-in-steps (n step list)
|
|||
|
Return a new list with the items in LIST grouped into N-sized
|
|||
|
sublists at offsets STEP apart. The last groups may contain less
|
|||
|
than N items.
|
|||
|
|
|||
|
(-partition-all-in-steps 2 1 '(1 2 3 4))
|
|||
|
⇒ '((1 2) (2 3) (3 4) (4))
|
|||
|
(-partition-all-in-steps 3 2 '(1 2 3 4))
|
|||
|
⇒ '((1 2 3) (3 4))
|
|||
|
(-partition-all-in-steps 3 2 '(1 2 3 4 5))
|
|||
|
⇒ '((1 2 3) (3 4 5) (5))
|
|||
|
|
|||
|
-- Function: -partition-by (fn list)
|
|||
|
Apply FN to each item in LIST, splitting it each time FN returns a
|
|||
|
new value.
|
|||
|
|
|||
|
(-partition-by 'even? '())
|
|||
|
⇒ '()
|
|||
|
(-partition-by 'even? '(1 1 2 2 2 3 4 6 8))
|
|||
|
⇒ '((1 1) (2 2 2) (3) (4 6 8))
|
|||
|
(--partition-by (< it 3) '(1 2 3 4 3 2 1))
|
|||
|
⇒ '((1 2) (3 4 3) (2 1))
|
|||
|
|
|||
|
-- Function: -partition-by-header (fn list)
|
|||
|
Apply FN to the first item in LIST. That is the header value.
|
|||
|
Apply FN to each item in LIST, splitting it each time FN returns
|
|||
|
the header value, but only after seeing at least one other value
|
|||
|
(the body).
|
|||
|
|
|||
|
(--partition-by-header (= it 1) '(1 2 3 1 2 1 2 3 4))
|
|||
|
⇒ '((1 2 3) (1 2) (1 2 3 4))
|
|||
|
(--partition-by-header (> it 0) '(1 2 0 1 0 1 2 3 0))
|
|||
|
⇒ '((1 2 0) (1 0) (1 2 3 0))
|
|||
|
(-partition-by-header 'even? '(2 1 1 1 4 1 3 5 6 6 1))
|
|||
|
⇒ '((2 1 1 1) (4 1 3 5) (6 6 1))
|
|||
|
|
|||
|
-- Function: -partition-after-pred (pred list)
|
|||
|
Partition directly after each time PRED is true on an element of
|
|||
|
LIST.
|
|||
|
|
|||
|
(-partition-after-pred #'odd? '())
|
|||
|
⇒ '()
|
|||
|
(-partition-after-pred #'odd? '(1))
|
|||
|
⇒ '((1))
|
|||
|
(-partition-after-pred #'odd? '(0 1))
|
|||
|
⇒ '((0 1))
|
|||
|
|
|||
|
-- Function: -partition-before-pred (pred list)
|
|||
|
Partition directly before each time PRED is true on an element of
|
|||
|
LIST.
|
|||
|
|
|||
|
(-partition-before-pred #'odd? '())
|
|||
|
⇒ '()
|
|||
|
(-partition-before-pred #'odd? '(1))
|
|||
|
⇒ '((1))
|
|||
|
(-partition-before-pred #'odd? '(0 1))
|
|||
|
⇒ '((0) (1))
|
|||
|
|
|||
|
-- Function: -partition-before-item (item list)
|
|||
|
Partition directly before each time ITEM appears in LIST.
|
|||
|
|
|||
|
(-partition-before-item 3 '())
|
|||
|
⇒ '()
|
|||
|
(-partition-before-item 3 '(1))
|
|||
|
⇒ '((1))
|
|||
|
(-partition-before-item 3 '(3))
|
|||
|
⇒ '((3))
|
|||
|
|
|||
|
-- Function: -partition-after-item (item list)
|
|||
|
Partition directly after each time ITEM appears in LIST.
|
|||
|
|
|||
|
(-partition-after-item 3 '())
|
|||
|
⇒ '()
|
|||
|
(-partition-after-item 3 '(1))
|
|||
|
⇒ '((1))
|
|||
|
(-partition-after-item 3 '(3))
|
|||
|
⇒ '((3))
|
|||
|
|
|||
|
-- Function: -group-by (fn list)
|
|||
|
Separate LIST into an alist whose keys are FN applied to the
|
|||
|
elements of LIST. Keys are compared by ‘equal’.
|
|||
|
|
|||
|
(-group-by 'even? '())
|
|||
|
⇒ '()
|
|||
|
(-group-by 'even? '(1 1 2 2 2 3 4 6 8))
|
|||
|
⇒ '((nil 1 1 3) (t 2 2 2 4 6 8))
|
|||
|
(--group-by (car (split-string it "/")) '("a/b" "c/d" "a/e"))
|
|||
|
⇒ '(("a" "a/b" "a/e") ("c" "c/d"))
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Indexing, Next: Set operations, Prev: Partitioning, Up: Functions
|
|||
|
|
|||
|
2.8 Indexing
|
|||
|
============
|
|||
|
|
|||
|
Return indices of elements based on predicates, sort elements by indices
|
|||
|
etc.
|
|||
|
|
|||
|
-- Function: -elem-index (elem list)
|
|||
|
Return the index of the first element in the given LIST which is
|
|||
|
equal to the query element ELEM, or nil if there is no such
|
|||
|
element.
|
|||
|
|
|||
|
(-elem-index 2 '(6 7 8 2 3 4))
|
|||
|
⇒ 3
|
|||
|
(-elem-index "bar" '("foo" "bar" "baz"))
|
|||
|
⇒ 1
|
|||
|
(-elem-index '(1 2) '((3) (5 6) (1 2) nil))
|
|||
|
⇒ 2
|
|||
|
|
|||
|
-- Function: -elem-indices (elem list)
|
|||
|
Return the indices of all elements in LIST equal to the query
|
|||
|
element ELEM, in ascending order.
|
|||
|
|
|||
|
(-elem-indices 2 '(6 7 8 2 3 4 2 1))
|
|||
|
⇒ '(3 6)
|
|||
|
(-elem-indices "bar" '("foo" "bar" "baz"))
|
|||
|
⇒ '(1)
|
|||
|
(-elem-indices '(1 2) '((3) (1 2) (5 6) (1 2) nil))
|
|||
|
⇒ '(1 3)
|
|||
|
|
|||
|
-- Function: -find-index (pred list)
|
|||
|
Take a predicate PRED and a LIST and return the index of the first
|
|||
|
element in the list satisfying the predicate, or nil if there is no
|
|||
|
such element.
|
|||
|
|
|||
|
See also ‘-first’ (*note -first::).
|
|||
|
|
|||
|
(-find-index 'even? '(2 4 1 6 3 3 5 8))
|
|||
|
⇒ 0
|
|||
|
(--find-index (< 5 it) '(2 4 1 6 3 3 5 8))
|
|||
|
⇒ 3
|
|||
|
(-find-index (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
|
|||
|
⇒ 1
|
|||
|
|
|||
|
-- Function: -find-last-index (pred list)
|
|||
|
Take a predicate PRED and a LIST and return the index of the last
|
|||
|
element in the list satisfying the predicate, or nil if there is no
|
|||
|
such element.
|
|||
|
|
|||
|
See also ‘-last’ (*note -last::).
|
|||
|
|
|||
|
(-find-last-index 'even? '(2 4 1 6 3 3 5 8))
|
|||
|
⇒ 7
|
|||
|
(--find-last-index (< 5 it) '(2 7 1 6 3 8 5 2))
|
|||
|
⇒ 5
|
|||
|
(-find-last-index (-partial 'string-lessp "baz") '("q" "foo" "baz"))
|
|||
|
⇒ 1
|
|||
|
|
|||
|
-- Function: -find-indices (pred list)
|
|||
|
Return the indices of all elements in LIST satisfying the predicate
|
|||
|
PRED, in ascending order.
|
|||
|
|
|||
|
(-find-indices 'even? '(2 4 1 6 3 3 5 8))
|
|||
|
⇒ '(0 1 3 7)
|
|||
|
(--find-indices (< 5 it) '(2 4 1 6 3 3 5 8))
|
|||
|
⇒ '(3 7)
|
|||
|
(-find-indices (-partial 'string-lessp "baz") '("bar" "foo" "baz"))
|
|||
|
⇒ '(1)
|
|||
|
|
|||
|
-- Function: -grade-up (comparator list)
|
|||
|
Grade elements of LIST using COMPARATOR relation, yielding a
|
|||
|
permutation vector such that applying this permutation to LIST
|
|||
|
sorts it in ascending order.
|
|||
|
|
|||
|
(-grade-up '< '(3 1 4 2 1 3 3))
|
|||
|
⇒ '(1 4 3 0 5 6 2)
|
|||
|
(let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-up '< l) l))
|
|||
|
⇒ '(1 1 2 3 3 3 4)
|
|||
|
|
|||
|
-- Function: -grade-down (comparator list)
|
|||
|
Grade elements of LIST using COMPARATOR relation, yielding a
|
|||
|
permutation vector such that applying this permutation to LIST
|
|||
|
sorts it in descending order.
|
|||
|
|
|||
|
(-grade-down '< '(3 1 4 2 1 3 3))
|
|||
|
⇒ '(2 0 5 6 3 1 4)
|
|||
|
(let ((l '(3 1 4 2 1 3 3))) (-select-by-indices (-grade-down '< l) l))
|
|||
|
⇒ '(4 3 3 3 2 1 1)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Set operations, Next: Other list operations, Prev: Indexing, Up: Functions
|
|||
|
|
|||
|
2.9 Set operations
|
|||
|
==================
|
|||
|
|
|||
|
Operations pretending lists are sets.
|
|||
|
|
|||
|
-- Function: -union (list list2)
|
|||
|
Return a new list containing the elements of LIST and elements of
|
|||
|
LIST2 that are not in LIST. The test for equality is done with
|
|||
|
‘equal’, or with ‘-compare-fn’ if that’s non-nil.
|
|||
|
|
|||
|
(-union '(1 2 3) '(3 4 5))
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
(-union '(1 2 3 4) '())
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
(-union '(1 1 2 2) '(3 2 1))
|
|||
|
⇒ '(1 1 2 2 3)
|
|||
|
|
|||
|
-- Function: -difference (list list2)
|
|||
|
Return a new list with only the members of LIST that are not in
|
|||
|
LIST2. The test for equality is done with ‘equal’, or with
|
|||
|
‘-compare-fn’ if that’s non-nil.
|
|||
|
|
|||
|
(-difference '() '())
|
|||
|
⇒ '()
|
|||
|
(-difference '(1 2 3) '(4 5 6))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-difference '(1 2 3 4) '(3 4 5 6))
|
|||
|
⇒ '(1 2)
|
|||
|
|
|||
|
-- Function: -intersection (list list2)
|
|||
|
Return a new list containing only the elements that are members of
|
|||
|
both LIST and LIST2. The test for equality is done with ‘equal’,
|
|||
|
or with ‘-compare-fn’ if that’s non-nil.
|
|||
|
|
|||
|
(-intersection '() '())
|
|||
|
⇒ '()
|
|||
|
(-intersection '(1 2 3) '(4 5 6))
|
|||
|
⇒ '()
|
|||
|
(-intersection '(1 2 3 4) '(3 4 5 6))
|
|||
|
⇒ '(3 4)
|
|||
|
|
|||
|
-- Function: -powerset (list)
|
|||
|
Return the power set of LIST.
|
|||
|
|
|||
|
(-powerset '())
|
|||
|
⇒ '(nil)
|
|||
|
(-powerset '(x y z))
|
|||
|
⇒ '((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
|
|||
|
|
|||
|
-- Function: -permutations (list)
|
|||
|
Return the permutations of LIST.
|
|||
|
|
|||
|
(-permutations '())
|
|||
|
⇒ '(nil)
|
|||
|
(-permutations '(1 2))
|
|||
|
⇒ '((1 2) (2 1))
|
|||
|
(-permutations '(a b c))
|
|||
|
⇒ '((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))
|
|||
|
|
|||
|
-- Function: -distinct (list)
|
|||
|
Return a new list with all duplicates removed. The test for
|
|||
|
equality is done with ‘equal’, or with ‘-compare-fn’ if that’s
|
|||
|
non-nil.
|
|||
|
|
|||
|
Alias: ‘-uniq’
|
|||
|
|
|||
|
(-distinct '())
|
|||
|
⇒ '()
|
|||
|
(-distinct '(1 2 2 4))
|
|||
|
⇒ '(1 2 4)
|
|||
|
(-distinct '(t t t))
|
|||
|
⇒ '(t)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Other list operations, Next: Tree operations, Prev: Set operations, Up: Functions
|
|||
|
|
|||
|
2.10 Other list operations
|
|||
|
==========================
|
|||
|
|
|||
|
Other list functions not fit to be classified elsewhere.
|
|||
|
|
|||
|
-- Function: -rotate (n list)
|
|||
|
Rotate LIST N places to the right. With N negative, rotate to the
|
|||
|
left. The time complexity is O(n).
|
|||
|
|
|||
|
(-rotate 3 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '(5 6 7 1 2 3 4)
|
|||
|
(-rotate -3 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '(4 5 6 7 1 2 3)
|
|||
|
(-rotate 16 '(1 2 3 4 5 6 7))
|
|||
|
⇒ '(6 7 1 2 3 4 5)
|
|||
|
|
|||
|
-- Function: -repeat (n x)
|
|||
|
Return a list with X repeated N times. Return nil if N is less
|
|||
|
than 1.
|
|||
|
|
|||
|
(-repeat 3 :a)
|
|||
|
⇒ '(:a :a :a)
|
|||
|
(-repeat 1 :a)
|
|||
|
⇒ '(:a)
|
|||
|
(-repeat 0 :a)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -cons* (&rest args)
|
|||
|
Make a new list from the elements of ARGS.
|
|||
|
|
|||
|
The last 2 members of ARGS are used as the final cons of the result
|
|||
|
so if the final member of ARGS is not a list the result is a dotted
|
|||
|
list.
|
|||
|
|
|||
|
(-cons* 1 2)
|
|||
|
⇒ '(1 . 2)
|
|||
|
(-cons* 1 2 3)
|
|||
|
⇒ '(1 2 . 3)
|
|||
|
(-cons* 1)
|
|||
|
⇒ 1
|
|||
|
|
|||
|
-- Function: -snoc (list elem &rest elements)
|
|||
|
Append ELEM to the end of the list.
|
|||
|
|
|||
|
This is like ‘cons’, but operates on the end of list.
|
|||
|
|
|||
|
If ELEMENTS is non nil, append these to the list as well.
|
|||
|
|
|||
|
(-snoc '(1 2 3) 4)
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
(-snoc '(1 2 3) 4 5 6)
|
|||
|
⇒ '(1 2 3 4 5 6)
|
|||
|
(-snoc '(1 2 3) '(4 5 6))
|
|||
|
⇒ '(1 2 3 (4 5 6))
|
|||
|
|
|||
|
-- Function: -interpose (sep list)
|
|||
|
Return a new list of all elements in LIST separated by SEP.
|
|||
|
|
|||
|
(-interpose "-" '())
|
|||
|
⇒ '()
|
|||
|
(-interpose "-" '("a"))
|
|||
|
⇒ '("a")
|
|||
|
(-interpose "-" '("a" "b" "c"))
|
|||
|
⇒ '("a" "-" "b" "-" "c")
|
|||
|
|
|||
|
-- Function: -interleave (&rest lists)
|
|||
|
Return a new list of the first item in each list, then the second
|
|||
|
etc.
|
|||
|
|
|||
|
(-interleave '(1 2) '("a" "b"))
|
|||
|
⇒ '(1 "a" 2 "b")
|
|||
|
(-interleave '(1 2) '("a" "b") '("A" "B"))
|
|||
|
⇒ '(1 "a" "A" 2 "b" "B")
|
|||
|
(-interleave '(1 2 3) '("a" "b"))
|
|||
|
⇒ '(1 "a" 2 "b")
|
|||
|
|
|||
|
-- Function: -zip-with (fn list1 list2)
|
|||
|
Zip the two lists LIST1 and LIST2 using a function FN. This
|
|||
|
function is applied pairwise taking as first argument element of
|
|||
|
LIST1 and as second argument element of LIST2 at corresponding
|
|||
|
position.
|
|||
|
|
|||
|
The anaphoric form ‘--zip-with’ binds the elements from LIST1 as
|
|||
|
symbol ‘it’, and the elements from LIST2 as symbol ‘other’.
|
|||
|
|
|||
|
(-zip-with '+ '(1 2 3) '(4 5 6))
|
|||
|
⇒ '(5 7 9)
|
|||
|
(-zip-with 'cons '(1 2 3) '(4 5 6))
|
|||
|
⇒ '((1 . 4) (2 . 5) (3 . 6))
|
|||
|
(--zip-with (concat it " and " other) '("Batman" "Jekyll") '("Robin" "Hyde"))
|
|||
|
⇒ '("Batman and Robin" "Jekyll and Hyde")
|
|||
|
|
|||
|
-- Function: -zip (&rest lists)
|
|||
|
Zip LISTS together. Group the head of each list, followed by the
|
|||
|
second elements of each list, and so on. The lengths of the
|
|||
|
returned groupings are equal to the length of the shortest input
|
|||
|
list.
|
|||
|
|
|||
|
If two lists are provided as arguments, return the groupings as a
|
|||
|
list of cons cells. Otherwise, return the groupings as a list of
|
|||
|
lists.
|
|||
|
|
|||
|
Use ‘-zip-lists’ (*note -zip-lists::) if you need the return value
|
|||
|
to always be a list of lists.
|
|||
|
|
|||
|
Alias: ‘-zip-pair’
|
|||
|
|
|||
|
See also: ‘-zip-lists’ (*note -zip-lists::)
|
|||
|
|
|||
|
(-zip '(1 2 3) '(4 5 6))
|
|||
|
⇒ '((1 . 4) (2 . 5) (3 . 6))
|
|||
|
(-zip '(1 2 3) '(4 5 6 7))
|
|||
|
⇒ '((1 . 4) (2 . 5) (3 . 6))
|
|||
|
(-zip '(1 2) '(3 4 5) '(6))
|
|||
|
⇒ '((1 3 6))
|
|||
|
|
|||
|
-- Function: -zip-lists (&rest lists)
|
|||
|
Zip LISTS together. Group the head of each list, followed by the
|
|||
|
second elements of each list, and so on. The lengths of the
|
|||
|
returned groupings are equal to the length of the shortest input
|
|||
|
list.
|
|||
|
|
|||
|
The return value is always list of lists, which is a difference
|
|||
|
from ‘-zip-pair’ which returns a cons-cell in case two input lists
|
|||
|
are provided.
|
|||
|
|
|||
|
See also: ‘-zip’ (*note -zip::)
|
|||
|
|
|||
|
(-zip-lists '(1 2 3) '(4 5 6))
|
|||
|
⇒ '((1 4) (2 5) (3 6))
|
|||
|
(-zip-lists '(1 2 3) '(4 5 6 7))
|
|||
|
⇒ '((1 4) (2 5) (3 6))
|
|||
|
(-zip-lists '(1 2) '(3 4 5) '(6))
|
|||
|
⇒ '((1 3 6))
|
|||
|
|
|||
|
-- Function: -zip-fill (fill-value &rest lists)
|
|||
|
Zip LISTS, with FILL-VALUE padded onto the shorter lists. The
|
|||
|
lengths of the returned groupings are equal to the length of the
|
|||
|
longest input list.
|
|||
|
|
|||
|
(-zip-fill 0 '(1 2 3 4 5) '(6 7 8 9))
|
|||
|
⇒ '((1 . 6) (2 . 7) (3 . 8) (4 . 9) (5 . 0))
|
|||
|
|
|||
|
-- Function: -unzip (lists)
|
|||
|
Unzip LISTS.
|
|||
|
|
|||
|
This works just like ‘-zip’ (*note -zip::) but takes a list of
|
|||
|
lists instead of a variable number of arguments, such that
|
|||
|
|
|||
|
(-unzip (-zip L1 L2 L3 ...))
|
|||
|
|
|||
|
is identity (given that the lists are the same length).
|
|||
|
|
|||
|
Note in particular that calling this on a list of two lists will
|
|||
|
return a list of cons-cells such that the above identity works.
|
|||
|
|
|||
|
See also: ‘-zip’ (*note -zip::)
|
|||
|
|
|||
|
(-unzip (-zip '(1 2 3) '(a b c) '("e" "f" "g")))
|
|||
|
⇒ '((1 2 3) (a b c) ("e" "f" "g"))
|
|||
|
(-unzip '((1 2) (3 4) (5 6) (7 8) (9 10)))
|
|||
|
⇒ '((1 3 5 7 9) (2 4 6 8 10))
|
|||
|
(-unzip '((1 2) (3 4)))
|
|||
|
⇒ '((1 . 3) (2 . 4))
|
|||
|
|
|||
|
-- Function: -cycle (list)
|
|||
|
Return an infinite copy of LIST that will cycle through the
|
|||
|
elements and repeat from the beginning.
|
|||
|
|
|||
|
(-take 5 (-cycle '(1 2 3)))
|
|||
|
⇒ '(1 2 3 1 2)
|
|||
|
(-take 7 (-cycle '(1 "and" 3)))
|
|||
|
⇒ '(1 "and" 3 1 "and" 3 1)
|
|||
|
(-zip (-cycle '(1 2 3)) '(1 2))
|
|||
|
⇒ '((1 . 1) (2 . 2))
|
|||
|
|
|||
|
-- Function: -pad (fill-value &rest lists)
|
|||
|
Appends FILL-VALUE to the end of each list in LISTS such that they
|
|||
|
will all have the same length.
|
|||
|
|
|||
|
(-pad 0 '())
|
|||
|
⇒ '(nil)
|
|||
|
(-pad 0 '(1))
|
|||
|
⇒ '((1))
|
|||
|
(-pad 0 '(1 2 3) '(4 5))
|
|||
|
⇒ '((1 2 3) (4 5 0))
|
|||
|
|
|||
|
-- Function: -table (fn &rest lists)
|
|||
|
Compute outer product of LISTS using function FN.
|
|||
|
|
|||
|
The function FN should have the same arity as the number of
|
|||
|
supplied lists.
|
|||
|
|
|||
|
The outer product is computed by applying fn to all possible
|
|||
|
combinations created by taking one element from each list in order.
|
|||
|
The dimension of the result is (length lists).
|
|||
|
|
|||
|
See also: ‘-table-flat’ (*note -table-flat::)
|
|||
|
|
|||
|
(-table '* '(1 2 3) '(1 2 3))
|
|||
|
⇒ '((1 2 3) (2 4 6) (3 6 9))
|
|||
|
(-table (lambda (a b) (-sum (-zip-with '* a b))) '((1 2) (3 4)) '((1 3) (2 4)))
|
|||
|
⇒ '((7 15) (10 22))
|
|||
|
(apply '-table 'list (-repeat 3 '(1 2)))
|
|||
|
⇒ '((((1 1 1) (2 1 1)) ((1 2 1) (2 2 1))) (((1 1 2) (2 1 2)) ((1 2 2) (2 2 2))))
|
|||
|
|
|||
|
-- Function: -table-flat (fn &rest lists)
|
|||
|
Compute flat outer product of LISTS using function FN.
|
|||
|
|
|||
|
The function FN should have the same arity as the number of
|
|||
|
supplied lists.
|
|||
|
|
|||
|
The outer product is computed by applying fn to all possible
|
|||
|
combinations created by taking one element from each list in order.
|
|||
|
The results are flattened, ignoring the tensor structure of the
|
|||
|
result. This is equivalent to calling:
|
|||
|
|
|||
|
(-flatten-n (1- (length lists)) (apply ’-table fn lists))
|
|||
|
|
|||
|
but the implementation here is much more efficient.
|
|||
|
|
|||
|
See also: ‘-flatten-n’ (*note -flatten-n::), ‘-table’ (*note
|
|||
|
-table::)
|
|||
|
|
|||
|
(-table-flat 'list '(1 2 3) '(a b c))
|
|||
|
⇒ '((1 a) (2 a) (3 a) (1 b) (2 b) (3 b) (1 c) (2 c) (3 c))
|
|||
|
(-table-flat '* '(1 2 3) '(1 2 3))
|
|||
|
⇒ '(1 2 3 2 4 6 3 6 9)
|
|||
|
(apply '-table-flat 'list (-repeat 3 '(1 2)))
|
|||
|
⇒ '((1 1 1) (2 1 1) (1 2 1) (2 2 1) (1 1 2) (2 1 2) (1 2 2) (2 2 2))
|
|||
|
|
|||
|
-- Function: -first (pred list)
|
|||
|
Return the first x in LIST where (PRED x) is non-nil, else nil.
|
|||
|
|
|||
|
To get the first item in the list no questions asked, use ‘car’.
|
|||
|
|
|||
|
Alias: ‘-find’
|
|||
|
|
|||
|
(-first 'even? '(1 2 3))
|
|||
|
⇒ 2
|
|||
|
(-first 'even? '(1 3 5))
|
|||
|
⇒ nil
|
|||
|
(-first 'null '(1 3 5))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -some (pred list)
|
|||
|
Return (PRED x) for the first LIST item where (PRED x) is non-nil,
|
|||
|
else nil.
|
|||
|
|
|||
|
Alias: ‘-any’
|
|||
|
|
|||
|
(-some 'even? '(1 2 3))
|
|||
|
⇒ t
|
|||
|
(-some 'null '(1 2 3))
|
|||
|
⇒ nil
|
|||
|
(-some 'null '(1 2 nil))
|
|||
|
⇒ t
|
|||
|
|
|||
|
-- Function: -last (pred list)
|
|||
|
Return the last x in LIST where (PRED x) is non-nil, else nil.
|
|||
|
|
|||
|
(-last 'even? '(1 2 3 4 5 6 3 3 3))
|
|||
|
⇒ 6
|
|||
|
(-last 'even? '(1 3 7 5 9))
|
|||
|
⇒ nil
|
|||
|
(--last (> (length it) 3) '("a" "looong" "word" "and" "short" "one"))
|
|||
|
⇒ "short"
|
|||
|
|
|||
|
-- Function: -first-item (list)
|
|||
|
Return the first item of LIST, or nil on an empty list.
|
|||
|
|
|||
|
See also: ‘-second-item’ (*note -second-item::), ‘-last-item’
|
|||
|
(*note -last-item::).
|
|||
|
|
|||
|
(fn LIST)
|
|||
|
|
|||
|
(-first-item '(1 2 3))
|
|||
|
⇒ 1
|
|||
|
(-first-item nil)
|
|||
|
⇒ nil
|
|||
|
(let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
|
|||
|
⇒ '(5 2 3)
|
|||
|
|
|||
|
-- Function: -second-item (arg1)
|
|||
|
Return the second item of LIST, or nil if LIST is too short.
|
|||
|
|
|||
|
See also: ‘-third-item’ (*note -third-item::).
|
|||
|
|
|||
|
(fn LIST)
|
|||
|
|
|||
|
(-second-item '(1 2 3))
|
|||
|
⇒ 2
|
|||
|
(-second-item nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -third-item (arg1)
|
|||
|
Return the third item of LIST, or nil if LIST is too short.
|
|||
|
|
|||
|
See also: ‘-fourth-item’ (*note -fourth-item::).
|
|||
|
|
|||
|
(fn LIST)
|
|||
|
|
|||
|
(-third-item '(1 2 3))
|
|||
|
⇒ 3
|
|||
|
(-third-item nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -fourth-item (list)
|
|||
|
Return the fourth item of LIST, or nil if LIST is too short.
|
|||
|
|
|||
|
See also: ‘-fifth-item’ (*note -fifth-item::).
|
|||
|
|
|||
|
(-fourth-item '(1 2 3 4))
|
|||
|
⇒ 4
|
|||
|
(-fourth-item nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -fifth-item (list)
|
|||
|
Return the fifth item of LIST, or nil if LIST is too short.
|
|||
|
|
|||
|
See also: ‘-last-item’ (*note -last-item::).
|
|||
|
|
|||
|
(-fifth-item '(1 2 3 4 5))
|
|||
|
⇒ 5
|
|||
|
(-fifth-item nil)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -last-item (list)
|
|||
|
Return the last item of LIST, or nil on an empty list.
|
|||
|
|
|||
|
(-last-item '(1 2 3))
|
|||
|
⇒ 3
|
|||
|
(-last-item nil)
|
|||
|
⇒ nil
|
|||
|
(let ((list (list 1 2 3))) (setf (-last-item list) 5) list)
|
|||
|
⇒ '(1 2 5)
|
|||
|
|
|||
|
-- Function: -butlast (list)
|
|||
|
Return a list of all items in list except for the last.
|
|||
|
|
|||
|
(-butlast '(1 2 3))
|
|||
|
⇒ '(1 2)
|
|||
|
(-butlast '(1 2))
|
|||
|
⇒ '(1)
|
|||
|
(-butlast '(1))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Function: -sort (comparator list)
|
|||
|
Sort LIST, stably, comparing elements using COMPARATOR. Return the
|
|||
|
sorted list. LIST is NOT modified by side effects. COMPARATOR is
|
|||
|
called with two elements of LIST, and should return non-nil if the
|
|||
|
first element should sort before the second.
|
|||
|
|
|||
|
(-sort '< '(3 1 2))
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-sort '> '(3 1 2))
|
|||
|
⇒ '(3 2 1)
|
|||
|
(--sort (< it other) '(3 1 2))
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
-- Function: -list (&rest args)
|
|||
|
Return a list with ARGS.
|
|||
|
|
|||
|
If first item of ARGS is already a list, simply return ARGS. If
|
|||
|
not, return a list with ARGS as elements.
|
|||
|
|
|||
|
(-list 1)
|
|||
|
⇒ '(1)
|
|||
|
(-list 1 2 3)
|
|||
|
⇒ '(1 2 3)
|
|||
|
(-list '(1 2 3))
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
-- Function: -fix (fn list)
|
|||
|
Compute the (least) fixpoint of FN with initial input LIST.
|
|||
|
|
|||
|
FN is called at least once, results are compared with ‘equal’.
|
|||
|
|
|||
|
(-fix (lambda (l) (-non-nil (--mapcat (-split-at (/ (length it) 2) it) l))) '((1 2 3 4 5 6)))
|
|||
|
⇒ '((1) (2) (3) (4) (5) (6))
|
|||
|
(let ((data '(("starwars" "scifi") ("jedi" "starwars" "warrior")))) (--fix (-uniq (--mapcat (cons it (cdr (assoc it data))) it)) '("jedi" "book")))
|
|||
|
⇒ '("jedi" "starwars" "warrior" "scifi" "book")
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Tree operations, Next: Threading macros, Prev: Other list operations, Up: Functions
|
|||
|
|
|||
|
2.11 Tree operations
|
|||
|
====================
|
|||
|
|
|||
|
Functions pretending lists are trees.
|
|||
|
|
|||
|
-- Function: -tree-seq (branch children tree)
|
|||
|
Return a sequence of the nodes in TREE, in depth-first search
|
|||
|
order.
|
|||
|
|
|||
|
BRANCH is a predicate of one argument that returns non-nil if the
|
|||
|
passed argument is a branch, that is, a node that can have
|
|||
|
children.
|
|||
|
|
|||
|
CHILDREN is a function of one argument that returns the children of
|
|||
|
the passed branch node.
|
|||
|
|
|||
|
Non-branch nodes are simply copied.
|
|||
|
|
|||
|
(-tree-seq 'listp 'identity '(1 (2 3) 4 (5 (6 7))))
|
|||
|
⇒ '((1 (2 3) 4 (5 (6 7))) 1 (2 3) 2 3 4 (5 (6 7)) 5 (6 7) 6 7)
|
|||
|
(-tree-seq 'listp 'reverse '(1 (2 3) 4 (5 (6 7))))
|
|||
|
⇒ '((1 (2 3) 4 (5 (6 7))) (5 (6 7)) (6 7) 7 6 5 4 (2 3) 3 2 1)
|
|||
|
(--tree-seq (vectorp it) (append it nil) [1 [2 3] 4 [5 [6 7]]])
|
|||
|
⇒ '([1 [2 3] 4 [5 [6 7]]] 1 [2 3] 2 3 4 [5 [6 7]] 5 [6 7] 6 7)
|
|||
|
|
|||
|
-- Function: -tree-map (fn tree)
|
|||
|
Apply FN to each element of TREE while preserving the tree
|
|||
|
structure.
|
|||
|
|
|||
|
(-tree-map '1+ '(1 (2 3) (4 (5 6) 7)))
|
|||
|
⇒ '(2 (3 4) (5 (6 7) 8))
|
|||
|
(-tree-map '(lambda (x) (cons x (expt 2 x))) '(1 (2 3) 4))
|
|||
|
⇒ '((1 . 2) ((2 . 4) (3 . 8)) (4 . 16))
|
|||
|
(--tree-map (length it) '("<body>" ("<p>" "text" "</p>") "</body>"))
|
|||
|
⇒ '(6 (3 4 4) 7)
|
|||
|
|
|||
|
-- Function: -tree-map-nodes (pred fun tree)
|
|||
|
Call FUN on each node of TREE that satisfies PRED.
|
|||
|
|
|||
|
If PRED returns nil, continue descending down this node. If PRED
|
|||
|
returns non-nil, apply FUN to this node and do not descend further.
|
|||
|
|
|||
|
(-tree-map-nodes 'vectorp (lambda (x) (-sum (append x nil))) '(1 [2 3] 4 (5 [6 7] 8)))
|
|||
|
⇒ '(1 5 4 (5 13 8))
|
|||
|
(-tree-map-nodes 'keywordp (lambda (x) (symbol-name x)) '(1 :foo 4 ((5 6 :bar) :baz 8)))
|
|||
|
⇒ '(1 ":foo" 4 ((5 6 ":bar") ":baz" 8))
|
|||
|
(--tree-map-nodes (eq (car-safe it) 'add-mode) (-concat it (list :mode 'emacs-lisp-mode)) '(with-mode emacs-lisp-mode (foo bar) (add-mode a b) (baz (add-mode c d))))
|
|||
|
⇒ '(with-mode emacs-lisp-mode (foo bar) (add-mode a b :mode emacs-lisp-mode) (baz (add-mode c d :mode emacs-lisp-mode)))
|
|||
|
|
|||
|
-- Function: -tree-reduce (fn tree)
|
|||
|
Use FN to reduce elements of list TREE. If elements of TREE are
|
|||
|
lists themselves, apply the reduction recursively.
|
|||
|
|
|||
|
FN is first applied to first element of the list and second
|
|||
|
element, then on this result and third element from the list etc.
|
|||
|
|
|||
|
See ‘-reduce-r’ (*note -reduce-r::) for how exactly are lists of
|
|||
|
zero or one element handled.
|
|||
|
|
|||
|
(-tree-reduce '+ '(1 (2 3) (4 5)))
|
|||
|
⇒ 15
|
|||
|
(-tree-reduce 'concat '("strings" (" on" " various") ((" levels"))))
|
|||
|
⇒ "strings on various levels"
|
|||
|
(--tree-reduce (cond ((stringp it) (concat it " " acc)) (t (let ((sn (symbol-name it))) (concat "<" sn ">" acc "</" sn ">")))) '(body (p "some words") (div "more" (b "bold") "words")))
|
|||
|
⇒ "<body><p>some words</p> <div>more <b>bold</b> words</div></body>"
|
|||
|
|
|||
|
-- Function: -tree-reduce-from (fn init-value tree)
|
|||
|
Use FN to reduce elements of list TREE. If elements of TREE are
|
|||
|
lists themselves, apply the reduction recursively.
|
|||
|
|
|||
|
FN is first applied to INIT-VALUE and first element of the list,
|
|||
|
then on this result and second element from the list etc.
|
|||
|
|
|||
|
The initial value is ignored on cons pairs as they always contain
|
|||
|
two elements.
|
|||
|
|
|||
|
(-tree-reduce-from '+ 1 '(1 (1 1) ((1))))
|
|||
|
⇒ 8
|
|||
|
(--tree-reduce-from (-concat acc (list it)) nil '(1 (2 3 (4 5)) (6 7)))
|
|||
|
⇒ '((7 6) ((5 4) 3 2) 1)
|
|||
|
|
|||
|
-- Function: -tree-mapreduce (fn folder tree)
|
|||
|
Apply FN to each element of TREE, and make a list of the results.
|
|||
|
If elements of TREE are lists themselves, apply FN recursively to
|
|||
|
elements of these nested lists.
|
|||
|
|
|||
|
Then reduce the resulting lists using FOLDER and initial value
|
|||
|
INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
|
|||
|
|
|||
|
This is the same as calling ‘-tree-reduce’ (*note -tree-reduce::)
|
|||
|
after ‘-tree-map’ (*note -tree-map::) but is twice as fast as it
|
|||
|
only traverse the structure once.
|
|||
|
|
|||
|
(-tree-mapreduce 'list 'append '(1 (2 (3 4) (5 6)) (7 (8 9))))
|
|||
|
⇒ '(1 2 3 4 5 6 7 8 9)
|
|||
|
(--tree-mapreduce 1 (+ it acc) '(1 (2 (4 9) (2 1)) (7 (4 3))))
|
|||
|
⇒ 9
|
|||
|
(--tree-mapreduce 0 (max acc (1+ it)) '(1 (2 (4 9) (2 1)) (7 (4 3))))
|
|||
|
⇒ 3
|
|||
|
|
|||
|
-- Function: -tree-mapreduce-from (fn folder init-value tree)
|
|||
|
Apply FN to each element of TREE, and make a list of the results.
|
|||
|
If elements of TREE are lists themselves, apply FN recursively to
|
|||
|
elements of these nested lists.
|
|||
|
|
|||
|
Then reduce the resulting lists using FOLDER and initial value
|
|||
|
INIT-VALUE. See ‘-reduce-r-from’ (*note -reduce-r-from::).
|
|||
|
|
|||
|
This is the same as calling ‘-tree-reduce-from’ (*note
|
|||
|
-tree-reduce-from::) after ‘-tree-map’ (*note -tree-map::) but is
|
|||
|
twice as fast as it only traverse the structure once.
|
|||
|
|
|||
|
(-tree-mapreduce-from 'identity '* 1 '(1 (2 (3 4) (5 6)) (7 (8 9))))
|
|||
|
⇒ 362880
|
|||
|
(--tree-mapreduce-from (+ it it) (cons it acc) nil '(1 (2 (4 9) (2 1)) (7 (4 3))))
|
|||
|
⇒ '(2 (4 (8 18) (4 2)) (14 (8 6)))
|
|||
|
(concat "{" (--tree-mapreduce-from (cond ((-cons-pair? it) (concat (symbol-name (car it)) " -> " (symbol-name (cdr it)))) (t (concat (symbol-name it) " : {"))) (concat it (unless (or (equal acc "}") (equal (substring it (1- (length it))) "{")) ", ") acc) "}" '((elips-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
|
|||
|
⇒ "{elips-mode : {foo : {bar -> booze{, baz -> qux{, c-mode : {foo -> bla, bum -> bam}}"
|
|||
|
|
|||
|
-- Function: -clone (list)
|
|||
|
Create a deep copy of LIST. The new list has the same elements and
|
|||
|
structure but all cons are replaced with new ones. This is useful
|
|||
|
when you need to clone a structure such as plist or alist.
|
|||
|
|
|||
|
(let* ((a '(1 2 3)) (b (-clone a))) (nreverse a) b)
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Threading macros, Next: Binding, Prev: Tree operations, Up: Functions
|
|||
|
|
|||
|
2.12 Threading macros
|
|||
|
=====================
|
|||
|
|
|||
|
-- Macro: -> (x &optional form &rest more)
|
|||
|
Thread the expr through the forms. Insert X as the second item in
|
|||
|
the first form, making a list of it if it is not a list already.
|
|||
|
If there are more forms, insert the first form as the second item
|
|||
|
in second form, etc.
|
|||
|
|
|||
|
(-> '(2 3 5))
|
|||
|
⇒ '(2 3 5)
|
|||
|
(-> '(2 3 5) (append '(8 13)))
|
|||
|
⇒ '(2 3 5 8 13)
|
|||
|
(-> '(2 3 5) (append '(8 13)) (-slice 1 -1))
|
|||
|
⇒ '(3 5 8)
|
|||
|
|
|||
|
-- Macro: ->> (x &optional form &rest more)
|
|||
|
Thread the expr through the forms. Insert X as the last item in
|
|||
|
the first form, making a list of it if it is not a list already.
|
|||
|
If there are more forms, insert the first form as the last item in
|
|||
|
second form, etc.
|
|||
|
|
|||
|
(->> '(1 2 3) (-map 'square))
|
|||
|
⇒ '(1 4 9)
|
|||
|
(->> '(1 2 3) (-map 'square) (-remove 'even?))
|
|||
|
⇒ '(1 9)
|
|||
|
(->> '(1 2 3) (-map 'square) (-reduce '+))
|
|||
|
⇒ 14
|
|||
|
|
|||
|
-- Macro: --> (x &rest forms)
|
|||
|
Starting with the value of X, thread each expression through FORMS.
|
|||
|
|
|||
|
Insert X at the position signified by the symbol ‘it’ in the first
|
|||
|
form. If there are more forms, insert the first form at the
|
|||
|
position signified by ‘it’ in in second form, etc.
|
|||
|
|
|||
|
(--> "def" (concat "abc" it "ghi"))
|
|||
|
⇒ "abcdefghi"
|
|||
|
(--> "def" (concat "abc" it "ghi") (upcase it))
|
|||
|
⇒ "ABCDEFGHI"
|
|||
|
(--> "def" (concat "abc" it "ghi") upcase)
|
|||
|
⇒ "ABCDEFGHI"
|
|||
|
|
|||
|
-- Macro: -as-> (value variable &rest forms)
|
|||
|
Starting with VALUE, thread VARIABLE through FORMS.
|
|||
|
|
|||
|
In the first form, bind VARIABLE to VALUE. In the second form,
|
|||
|
bind VARIABLE to the result of the first form, and so forth.
|
|||
|
|
|||
|
(-as-> 3 my-var (1+ my-var) (list my-var) (mapcar (lambda (ele) (* 2 ele)) my-var))
|
|||
|
⇒ '(8)
|
|||
|
(-as-> 3 my-var 1+)
|
|||
|
⇒ 4
|
|||
|
(-as-> 3 my-var)
|
|||
|
⇒ 3
|
|||
|
|
|||
|
-- Macro: -some-> (x &optional form &rest more)
|
|||
|
When expr is non-nil, thread it through the first form (via ‘->’
|
|||
|
(*note ->::)), and when that result is non-nil, through the next
|
|||
|
form, etc.
|
|||
|
|
|||
|
(-some-> '(2 3 5))
|
|||
|
⇒ '(2 3 5)
|
|||
|
(-some-> 5 square)
|
|||
|
⇒ 25
|
|||
|
(-some-> 5 even? square)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Macro: -some->> (x &optional form &rest more)
|
|||
|
When expr is non-nil, thread it through the first form (via ‘->>’
|
|||
|
(*note ->>::)), and when that result is non-nil, through the next
|
|||
|
form, etc.
|
|||
|
|
|||
|
(-some->> '(1 2 3) (-map 'square))
|
|||
|
⇒ '(1 4 9)
|
|||
|
(-some->> '(1 3 5) (-last 'even?) (+ 100))
|
|||
|
⇒ nil
|
|||
|
(-some->> '(2 4 6) (-last 'even?) (+ 100))
|
|||
|
⇒ 106
|
|||
|
|
|||
|
-- Macro: -some--> (x &optional form &rest more)
|
|||
|
When expr in non-nil, thread it through the first form (via ‘-->’
|
|||
|
(*note -->::)), and when that result is non-nil, through the next
|
|||
|
form, etc.
|
|||
|
|
|||
|
(-some--> "def" (concat "abc" it "ghi"))
|
|||
|
⇒ "abcdefghi"
|
|||
|
(-some--> nil (concat "abc" it "ghi"))
|
|||
|
⇒ nil
|
|||
|
(-some--> '(1 3 5) (-filter 'even? it) (append it it) (-map 'square it))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Binding, Next: Side-effects, Prev: Threading macros, Up: Functions
|
|||
|
|
|||
|
2.13 Binding
|
|||
|
============
|
|||
|
|
|||
|
Convenient versions of ‘let‘ and ‘let*‘ constructs combined with flow
|
|||
|
control.
|
|||
|
|
|||
|
-- Macro: -when-let (var-val &rest body)
|
|||
|
If VAL evaluates to non-nil, bind it to VAR and execute body.
|
|||
|
|
|||
|
Note: binding is done according to ‘-let’ (*note -let::).
|
|||
|
|
|||
|
(fn (VAR VAL) &rest BODY)
|
|||
|
|
|||
|
(-when-let (match-index (string-match "d" "abcd")) (+ match-index 2))
|
|||
|
⇒ 5
|
|||
|
(-when-let ((&plist :foo foo) (list :foo "foo")) foo)
|
|||
|
⇒ "foo"
|
|||
|
(-when-let ((&plist :foo foo) (list :bar "bar")) foo)
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Macro: -when-let* (vars-vals &rest body)
|
|||
|
If all VALS evaluate to true, bind them to their corresponding VARS
|
|||
|
and execute body. VARS-VALS should be a list of (VAR VAL) pairs.
|
|||
|
|
|||
|
Note: binding is done according to ‘-let*’ (*note -let*::). VALS
|
|||
|
are evaluated sequentially, and evaluation stops after the first
|
|||
|
nil VAL is encountered.
|
|||
|
|
|||
|
(-when-let* ((x 5) (y 3) (z (+ y 4))) (+ x y z))
|
|||
|
⇒ 15
|
|||
|
(-when-let* ((x 5) (y nil) (z 7)) (+ x y z))
|
|||
|
⇒ nil
|
|||
|
|
|||
|
-- Macro: -if-let (var-val then &rest else)
|
|||
|
If VAL evaluates to non-nil, bind it to VAR and do THEN, otherwise
|
|||
|
do ELSE.
|
|||
|
|
|||
|
Note: binding is done according to ‘-let’ (*note -let::).
|
|||
|
|
|||
|
(fn (VAR VAL) THEN &rest ELSE)
|
|||
|
|
|||
|
(-if-let (match-index (string-match "d" "abc")) (+ match-index 3) 7)
|
|||
|
⇒ 7
|
|||
|
(--if-let (even? 4) it nil)
|
|||
|
⇒ t
|
|||
|
|
|||
|
-- Macro: -if-let* (vars-vals then &rest else)
|
|||
|
If all VALS evaluate to true, bind them to their corresponding VARS
|
|||
|
and do THEN, otherwise do ELSE. VARS-VALS should be a list of (VAR
|
|||
|
VAL) pairs.
|
|||
|
|
|||
|
Note: binding is done according to ‘-let*’ (*note -let*::). VALS
|
|||
|
are evaluated sequentially, and evaluation stops after the first
|
|||
|
nil VAL is encountered.
|
|||
|
|
|||
|
(-if-let* ((x 5) (y 3) (z 7)) (+ x y z) "foo")
|
|||
|
⇒ 15
|
|||
|
(-if-let* ((x 5) (y nil) (z 7)) (+ x y z) "foo")
|
|||
|
⇒ "foo"
|
|||
|
(-if-let* (((_ _ x) '(nil nil 7))) x)
|
|||
|
⇒ 7
|
|||
|
|
|||
|
-- Macro: -let (varlist &rest body)
|
|||
|
Bind variables according to VARLIST then eval BODY.
|
|||
|
|
|||
|
VARLIST is a list of lists of the form (PATTERN SOURCE). Each
|
|||
|
PATTERN is matched against the SOURCE "structurally". SOURCE is
|
|||
|
only evaluated once for each PATTERN. Each PATTERN is matched
|
|||
|
recursively, and can therefore contain sub-patterns which are
|
|||
|
matched against corresponding sub-expressions of SOURCE.
|
|||
|
|
|||
|
All the SOURCEs are evalled before any symbols are bound (i.e. "in
|
|||
|
parallel").
|
|||
|
|
|||
|
If VARLIST only contains one (PATTERN SOURCE) element, you can
|
|||
|
optionally specify it using a vector and discarding the outer-most
|
|||
|
parens. Thus
|
|||
|
|
|||
|
(-let ((PATTERN SOURCE)) ..)
|
|||
|
|
|||
|
becomes
|
|||
|
|
|||
|
(-let [PATTERN SOURCE] ..).
|
|||
|
|
|||
|
‘-let’ (*note -let::) uses a convention of not binding places
|
|||
|
(symbols) starting with _ whenever it’s possible. You can use this
|
|||
|
to skip over entries you don’t care about. However, this is not
|
|||
|
*always* possible (as a result of implementation) and these symbols
|
|||
|
might get bound to undefined values.
|
|||
|
|
|||
|
Following is the overview of supported patterns. Remember that
|
|||
|
patterns can be matched recursively, so every a, b, aK in the
|
|||
|
following can be a matching construct and not necessarily a
|
|||
|
symbol/variable.
|
|||
|
|
|||
|
Symbol:
|
|||
|
|
|||
|
a - bind the SOURCE to A. This is just like regular ‘let’.
|
|||
|
|
|||
|
Conses and lists:
|
|||
|
|
|||
|
(a) - bind ‘car’ of cons/list to A
|
|||
|
|
|||
|
(a . b) - bind car of cons to A and ‘cdr’ to B
|
|||
|
|
|||
|
(a b) - bind car of list to A and ‘cadr’ to B
|
|||
|
|
|||
|
(a1 a2 a3 ...) - bind 0th car of list to A1, 1st to A2, 2nd to A3
|
|||
|
...
|
|||
|
|
|||
|
(a1 a2 a3 ... aN . rest) - as above, but bind the Nth cdr to
|
|||
|
REST.
|
|||
|
|
|||
|
Vectors:
|
|||
|
|
|||
|
[a] - bind 0th element of a non-list sequence to A (works with
|
|||
|
vectors, strings, bit arrays...)
|
|||
|
|
|||
|
[a1 a2 a3 ...] - bind 0th element of non-list sequence to A0, 1st
|
|||
|
to A1, 2nd to A2, ... If the PATTERN is shorter than SOURCE, the
|
|||
|
values at places not in PATTERN are ignored. If the PATTERN is
|
|||
|
longer than SOURCE, an ‘error’ is thrown.
|
|||
|
|
|||
|
[a1 a2 a3 ... &rest rest] - as above, but bind the rest of the
|
|||
|
sequence to REST. This is conceptually the same as improper list
|
|||
|
matching (a1 a2 ... aN . rest)
|
|||
|
|
|||
|
Key/value stores:
|
|||
|
|
|||
|
(&plist key0 a0 ... keyN aN) - bind value mapped by keyK in the
|
|||
|
SOURCE plist to aK. If the value is not found, aK is nil. Uses
|
|||
|
‘plist-get’ to fetch values.
|
|||
|
|
|||
|
(&alist key0 a0 ... keyN aN) - bind value mapped by keyK in the
|
|||
|
SOURCE alist to aK. If the value is not found, aK is nil. Uses
|
|||
|
‘assoc’ to fetch values.
|
|||
|
|
|||
|
(&hash key0 a0 ... keyN aN) - bind value mapped by keyK in the
|
|||
|
SOURCE hash table to aK. If the value is not found, aK is nil.
|
|||
|
Uses ‘gethash’ to fetch values.
|
|||
|
|
|||
|
Further, special keyword &keys supports "inline" matching of
|
|||
|
plist-like key-value pairs, similarly to &keys keyword of
|
|||
|
‘cl-defun’.
|
|||
|
|
|||
|
(a1 a2 ... aN &keys key1 b1 ... keyN bK)
|
|||
|
|
|||
|
This binds N values from the list to a1 ... aN, then interprets
|
|||
|
the cdr as a plist (see key/value matching above).
|
|||
|
|
|||
|
A shorthand notation for kv-destructuring exists which allows the
|
|||
|
patterns be optionally left out and derived from the key name in
|
|||
|
the following fashion:
|
|||
|
|
|||
|
- a key :foo is converted into ‘foo’ pattern, - a key ’bar is
|
|||
|
converted into ‘bar’ pattern, - a key "baz" is converted into ‘baz’
|
|||
|
pattern.
|
|||
|
|
|||
|
That is, the entire value under the key is bound to the derived
|
|||
|
variable without any further destructuring.
|
|||
|
|
|||
|
This is possible only when the form following the key is not a
|
|||
|
valid pattern (i.e. not a symbol, a cons cell or a vector).
|
|||
|
Otherwise the matching proceeds as usual and in case of an invalid
|
|||
|
spec fails with an error.
|
|||
|
|
|||
|
Thus the patterns are normalized as follows:
|
|||
|
|
|||
|
;; derive all the missing patterns (&plist :foo ’bar "baz") =>
|
|||
|
(&plist :foo foo ’bar bar "baz" baz)
|
|||
|
|
|||
|
;; we can specify some but not others (&plist :foo ’bar
|
|||
|
explicit-bar) => (&plist :foo foo ’bar explicit-bar)
|
|||
|
|
|||
|
;; nothing happens, we store :foo in x (&plist :foo x) => (&plist
|
|||
|
:foo x)
|
|||
|
|
|||
|
;; nothing happens, we match recursively (&plist :foo (a b c)) =>
|
|||
|
(&plist :foo (a b c))
|
|||
|
|
|||
|
You can name the source using the syntax SYMBOL &as PATTERN. This
|
|||
|
syntax works with lists (proper or improper), vectors and all types
|
|||
|
of maps.
|
|||
|
|
|||
|
(list &as a b c) (list 1 2 3)
|
|||
|
|
|||
|
binds A to 1, B to 2, C to 3 and LIST to (1 2 3).
|
|||
|
|
|||
|
Similarly:
|
|||
|
|
|||
|
(bounds &as beg . end) (cons 1 2)
|
|||
|
|
|||
|
binds BEG to 1, END to 2 and BOUNDS to (1 . 2).
|
|||
|
|
|||
|
(items &as first . rest) (list 1 2 3)
|
|||
|
|
|||
|
binds FIRST to 1, REST to (2 3) and ITEMS to (1 2 3)
|
|||
|
|
|||
|
[vect &as _ b c] [1 2 3]
|
|||
|
|
|||
|
binds B to 2, C to 3 and VECT to [1 2 3] (_ avoids binding as
|
|||
|
usual).
|
|||
|
|
|||
|
(plist &as &plist :b b) (list :a 1 :b 2 :c 3)
|
|||
|
|
|||
|
binds B to 2 and PLIST to (:a 1 :b 2 :c 3). Same for &alist and
|
|||
|
&hash.
|
|||
|
|
|||
|
This is especially useful when we want to capture the result of a
|
|||
|
computation and destructure at the same time. Consider the form
|
|||
|
(function-returning-complex-structure) returning a list of two
|
|||
|
vectors with two items each. We want to capture this entire result
|
|||
|
and pass it to another computation, but at the same time we want to
|
|||
|
get the second item from each vector. We can achieve it with
|
|||
|
pattern
|
|||
|
|
|||
|
(result &as [_ a] [_ b]) (function-returning-complex-structure)
|
|||
|
|
|||
|
Note: Clojure programmers may know this feature as the ":as
|
|||
|
binding". The difference is that we put the &as at the front
|
|||
|
because we need to support improper list binding.
|
|||
|
|
|||
|
(-let (([a (b c) d] [1 (2 3) 4])) (list a b c d))
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
(-let [(a b c . d) (list 1 2 3 4 5 6)] (list a b c d))
|
|||
|
⇒ '(1 2 3 (4 5 6))
|
|||
|
(-let [(&plist :foo foo :bar bar) (list :baz 3 :foo 1 :qux 4 :bar 2)] (list foo bar))
|
|||
|
⇒ '(1 2)
|
|||
|
|
|||
|
-- Macro: -let* (varlist &rest body)
|
|||
|
Bind variables according to VARLIST then eval BODY.
|
|||
|
|
|||
|
VARLIST is a list of lists of the form (PATTERN SOURCE). Each
|
|||
|
PATTERN is matched against the SOURCE structurally. SOURCE is only
|
|||
|
evaluated once for each PATTERN.
|
|||
|
|
|||
|
Each SOURCE can refer to the symbols already bound by this VARLIST.
|
|||
|
This is useful if you want to destructure SOURCE recursively but
|
|||
|
also want to name the intermediate structures.
|
|||
|
|
|||
|
See ‘-let’ (*note -let::) for the list of all possible patterns.
|
|||
|
|
|||
|
(-let* (((a . b) (cons 1 2)) ((c . d) (cons 3 4))) (list a b c d))
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
(-let* (((a . b) (cons 1 (cons 2 3))) ((c . d) b)) (list a b c d))
|
|||
|
⇒ '(1 (2 . 3) 2 3)
|
|||
|
(-let* (((&alist "foo" foo "bar" bar) (list (cons "foo" 1) (cons "bar" (list 'a 'b 'c)))) ((a b c) bar)) (list foo a b c bar))
|
|||
|
⇒ '(1 a b c (a b c))
|
|||
|
|
|||
|
-- Macro: -lambda (match-form &rest body)
|
|||
|
Return a lambda which destructures its input as MATCH-FORM and
|
|||
|
executes BODY.
|
|||
|
|
|||
|
Note that you have to enclose the MATCH-FORM in a pair of parens,
|
|||
|
such that:
|
|||
|
|
|||
|
(-lambda (x) body) (-lambda (x y ...) body)
|
|||
|
|
|||
|
has the usual semantics of ‘lambda’. Furthermore, these get
|
|||
|
translated into normal lambda, so there is no performance penalty.
|
|||
|
|
|||
|
See ‘-let’ (*note -let::) for the description of destructuring
|
|||
|
mechanism.
|
|||
|
|
|||
|
(-map (-lambda ((x y)) (+ x y)) '((1 2) (3 4) (5 6)))
|
|||
|
⇒ '(3 7 11)
|
|||
|
(-map (-lambda ([x y]) (+ x y)) '([1 2] [3 4] [5 6]))
|
|||
|
⇒ '(3 7 11)
|
|||
|
(funcall (-lambda ((_ . a) (_ . b)) (-concat a b)) '(1 2 3) '(4 5 6))
|
|||
|
⇒ '(2 3 5 6)
|
|||
|
|
|||
|
-- Macro: -setq (&rest forms)
|
|||
|
Bind each MATCH-FORM to the value of its VAL.
|
|||
|
|
|||
|
MATCH-FORM destructuring is done according to the rules of ‘-let’
|
|||
|
(*note -let::).
|
|||
|
|
|||
|
This macro allows you to bind multiple variables by destructuring
|
|||
|
the value, so for example:
|
|||
|
|
|||
|
(-setq (a b) x (&plist :c c) plist)
|
|||
|
|
|||
|
expands roughly speaking to the following code
|
|||
|
|
|||
|
(setq a (car x) b (cadr x) c (plist-get plist :c))
|
|||
|
|
|||
|
Care is taken to only evaluate each VAL once so that in case of
|
|||
|
multiple assignments it does not cause unexpected side effects.
|
|||
|
|
|||
|
(fn [MATCH-FORM VAL]...)
|
|||
|
|
|||
|
(progn (-setq a 1) a)
|
|||
|
⇒ 1
|
|||
|
(progn (-setq (a b) (list 1 2)) (list a b))
|
|||
|
⇒ '(1 2)
|
|||
|
(progn (-setq (&plist :c c) (list :c "c")) c)
|
|||
|
⇒ "c"
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Side-effects, Next: Destructive operations, Prev: Binding, Up: Functions
|
|||
|
|
|||
|
2.14 Side-effects
|
|||
|
=================
|
|||
|
|
|||
|
Functions iterating over lists for side-effect only.
|
|||
|
|
|||
|
-- Function: -each (list fn)
|
|||
|
Call FN with every item in LIST. Return nil, used for side-effects
|
|||
|
only.
|
|||
|
|
|||
|
(let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))))
|
|||
|
⇒ nil
|
|||
|
(let (s) (-each '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
|
|||
|
⇒ '(3 2 1)
|
|||
|
(let (s) (--each '(1 2 3) (setq s (cons it s))) s)
|
|||
|
⇒ '(3 2 1)
|
|||
|
|
|||
|
-- Function: -each-while (list pred fn)
|
|||
|
Call FN with every item in LIST while (PRED item) is non-nil.
|
|||
|
Return nil, used for side-effects only.
|
|||
|
|
|||
|
(let (s) (-each-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
|
|||
|
⇒ '(4 2)
|
|||
|
(let (s) (--each-while '(1 2 3 4) (< it 3) (!cons it s)) s)
|
|||
|
⇒ '(2 1)
|
|||
|
|
|||
|
-- Function: -each-indexed (list fn)
|
|||
|
Call (FN index item) for each item in LIST.
|
|||
|
|
|||
|
In the anaphoric form ‘--each-indexed’, the index is exposed as
|
|||
|
symbol ‘it-index’.
|
|||
|
|
|||
|
See also: ‘-map-indexed’ (*note -map-indexed::).
|
|||
|
|
|||
|
(let (s) (-each-indexed '(a b c) (lambda (index item) (setq s (cons (list item index) s)))) s)
|
|||
|
⇒ '((c 2) (b 1) (a 0))
|
|||
|
(let (s) (--each-indexed '(a b c) (setq s (cons (list it it-index) s))) s)
|
|||
|
⇒ '((c 2) (b 1) (a 0))
|
|||
|
|
|||
|
-- Function: -each-r (list fn)
|
|||
|
Call FN with every item in LIST in reversed order. Return nil,
|
|||
|
used for side-effects only.
|
|||
|
|
|||
|
(let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))))
|
|||
|
⇒ nil
|
|||
|
(let (s) (-each-r '(1 2 3) (lambda (item) (setq s (cons item s)))) s)
|
|||
|
⇒ '(1 2 3)
|
|||
|
(let (s) (--each-r '(1 2 3) (setq s (cons it s))) s)
|
|||
|
⇒ '(1 2 3)
|
|||
|
|
|||
|
-- Function: -each-r-while (list pred fn)
|
|||
|
Call FN with every item in reversed LIST while (PRED item) is
|
|||
|
non-nil. Return nil, used for side-effects only.
|
|||
|
|
|||
|
(let (s) (-each-r-while '(2 4 5 6) 'even? (lambda (item) (!cons item s))) s)
|
|||
|
⇒ '(6)
|
|||
|
(let (s) (--each-r-while '(1 2 3 4) (>= it 3) (!cons it s)) s)
|
|||
|
⇒ '(3 4)
|
|||
|
|
|||
|
-- Function: -dotimes (num fn)
|
|||
|
Repeatedly calls FN (presumably for side-effects) passing in
|
|||
|
integers from 0 through NUM-1.
|
|||
|
|
|||
|
(let (s) (-dotimes 3 (lambda (n) (!cons n s))) s)
|
|||
|
⇒ '(2 1 0)
|
|||
|
(let (s) (--dotimes 5 (!cons it s)) s)
|
|||
|
⇒ '(4 3 2 1 0)
|
|||
|
|
|||
|
-- Macro: -doto (eval-initial-value &rest forms)
|
|||
|
Eval a form, then insert that form as the 2nd argument to other
|
|||
|
forms. The EVAL-INITIAL-VALUE form is evaluated once. Its result
|
|||
|
is passed to FORMS, which are then evaluated sequentially. Returns
|
|||
|
the target form.
|
|||
|
|
|||
|
(-doto '(1 2 3) (!cdr) (!cdr))
|
|||
|
⇒ '(3)
|
|||
|
(-doto '(1 . 2) (setcar 3) (setcdr 4))
|
|||
|
⇒ '(3 . 4)
|
|||
|
|
|||
|
-- Macro: --doto (eval-initial-value &rest forms)
|
|||
|
Anaphoric form of ‘-doto’ (*note -doto::). Note: ‘it’ is not
|
|||
|
required in each form.
|
|||
|
|
|||
|
(gethash "key" (--doto (make-hash-table :test 'equal) (puthash "key" "value" it)))
|
|||
|
⇒ "value"
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Destructive operations, Next: Function combinators, Prev: Side-effects, Up: Functions
|
|||
|
|
|||
|
2.15 Destructive operations
|
|||
|
===========================
|
|||
|
|
|||
|
-- Macro: !cons (car cdr)
|
|||
|
Destructive: Set CDR to the cons of CAR and CDR.
|
|||
|
|
|||
|
(let (l) (!cons 5 l) l)
|
|||
|
⇒ '(5)
|
|||
|
(let ((l '(3))) (!cons 5 l) l)
|
|||
|
⇒ '(5 3)
|
|||
|
|
|||
|
-- Macro: !cdr (list)
|
|||
|
Destructive: Set LIST to the cdr of LIST.
|
|||
|
|
|||
|
(let ((l '(3))) (!cdr l) l)
|
|||
|
⇒ '()
|
|||
|
(let ((l '(3 5))) (!cdr l) l)
|
|||
|
⇒ '(5)
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Function combinators, Prev: Destructive operations, Up: Functions
|
|||
|
|
|||
|
2.16 Function combinators
|
|||
|
=========================
|
|||
|
|
|||
|
These combinators require Emacs 24 for its lexical scope. So they are
|
|||
|
offered in a separate package: ‘dash-functional‘.
|
|||
|
|
|||
|
-- Function: -partial (fn &rest args)
|
|||
|
Takes a function FN and fewer than the normal arguments to FN, and
|
|||
|
returns a fn that takes a variable number of additional ARGS. When
|
|||
|
called, the returned function calls FN with ARGS first and then
|
|||
|
additional args.
|
|||
|
|
|||
|
(funcall (-partial '- 5) 3)
|
|||
|
⇒ 2
|
|||
|
(funcall (-partial '+ 5 2) 3)
|
|||
|
⇒ 10
|
|||
|
|
|||
|
-- Function: -rpartial (fn &rest args)
|
|||
|
Takes a function FN and fewer than the normal arguments to FN, and
|
|||
|
returns a fn that takes a variable number of additional ARGS. When
|
|||
|
called, the returned function calls FN with the additional args
|
|||
|
first and then ARGS.
|
|||
|
|
|||
|
(funcall (-rpartial '- 5) 8)
|
|||
|
⇒ 3
|
|||
|
(funcall (-rpartial '- 5 2) 10)
|
|||
|
⇒ 3
|
|||
|
|
|||
|
-- Function: -juxt (&rest fns)
|
|||
|
Takes a list of functions and returns a fn that is the
|
|||
|
juxtaposition of those fns. The returned fn takes a variable
|
|||
|
number of args, and returns a list containing the result of
|
|||
|
applying each fn to the args (left-to-right).
|
|||
|
|
|||
|
(funcall (-juxt '+ '-) 3 5)
|
|||
|
⇒ '(8 -2)
|
|||
|
(-map (-juxt 'identity 'square) '(1 2 3))
|
|||
|
⇒ '((1 1) (2 4) (3 9))
|
|||
|
|
|||
|
-- Function: -compose (&rest fns)
|
|||
|
Takes a list of functions and returns a fn that is the composition
|
|||
|
of those fns. The returned fn takes a variable number of
|
|||
|
arguments, and returns the result of applying each fn to the result
|
|||
|
of applying the previous fn to the arguments (right-to-left).
|
|||
|
|
|||
|
(funcall (-compose 'square '+) 2 3)
|
|||
|
⇒ (square (+ 2 3))
|
|||
|
(funcall (-compose 'identity 'square) 3)
|
|||
|
⇒ (square 3)
|
|||
|
(funcall (-compose 'square 'identity) 3)
|
|||
|
⇒ (square 3)
|
|||
|
|
|||
|
-- Function: -applify (fn)
|
|||
|
Changes an n-arity function FN to a 1-arity function that expects a
|
|||
|
list with n items as arguments
|
|||
|
|
|||
|
(-map (-applify '+) '((1 1 1) (1 2 3) (5 5 5)))
|
|||
|
⇒ '(3 6 15)
|
|||
|
(-map (-applify (lambda (a b c) `(,a (,b (,c))))) '((1 1 1) (1 2 3) (5 5 5)))
|
|||
|
⇒ '((1 (1 (1))) (1 (2 (3))) (5 (5 (5))))
|
|||
|
(funcall (-applify '<) '(3 6))
|
|||
|
⇒ t
|
|||
|
|
|||
|
-- Function: -on (operator transformer)
|
|||
|
Return a function of two arguments that first applies TRANSFORMER
|
|||
|
to each of them and then applies OPERATOR on the results (in the
|
|||
|
same order).
|
|||
|
|
|||
|
In types: (b -> b -> c) -> (a -> b) -> a -> a -> c
|
|||
|
|
|||
|
(-sort (-on '< 'length) '((1 2 3) (1) (1 2)))
|
|||
|
⇒ '((1) (1 2) (1 2 3))
|
|||
|
(-min-by (-on '> 'length) '((1 2 3) (4) (1 2)))
|
|||
|
⇒ '(4)
|
|||
|
(-min-by (-on 'string-lessp 'number-to-string) '(2 100 22))
|
|||
|
⇒ 22
|
|||
|
|
|||
|
-- Function: -flip (func)
|
|||
|
Swap the order of arguments for binary function FUNC.
|
|||
|
|
|||
|
In types: (a -> b -> c) -> b -> a -> c
|
|||
|
|
|||
|
(funcall (-flip '<) 2 1)
|
|||
|
⇒ t
|
|||
|
(funcall (-flip '-) 3 8)
|
|||
|
⇒ 5
|
|||
|
(-sort (-flip '<) '(4 3 6 1))
|
|||
|
⇒ '(6 4 3 1)
|
|||
|
|
|||
|
-- Function: -const (c)
|
|||
|
Return a function that returns C ignoring any additional arguments.
|
|||
|
|
|||
|
In types: a -> b -> a
|
|||
|
|
|||
|
(funcall (-const 2) 1 3 "foo")
|
|||
|
⇒ 2
|
|||
|
(-map (-const 1) '("a" "b" "c" "d"))
|
|||
|
⇒ '(1 1 1 1)
|
|||
|
(-sum (-map (-const 1) '("a" "b" "c" "d")))
|
|||
|
⇒ 4
|
|||
|
|
|||
|
-- Macro: -cut (&rest params)
|
|||
|
Take n-ary function and n arguments and specialize some of them.
|
|||
|
Arguments denoted by <> will be left unspecialized.
|
|||
|
|
|||
|
See SRFI-26 for detailed description.
|
|||
|
|
|||
|
(funcall (-cut list 1 <> 3 <> 5) 2 4)
|
|||
|
⇒ '(1 2 3 4 5)
|
|||
|
(-map (-cut funcall <> 5) '(1+ 1- (lambda (x) (/ 1.0 x))))
|
|||
|
⇒ '(6 4 0.2)
|
|||
|
(-map (-cut <> 1 2 3) (list 'list 'vector 'string))
|
|||
|
⇒ '((1 2 3) [1 2 3] "")
|
|||
|
|
|||
|
-- Function: -not (pred)
|
|||
|
Take a unary predicate PRED and return a unary predicate that
|
|||
|
returns t if PRED returns nil and nil if PRED returns non-nil.
|
|||
|
|
|||
|
(funcall (-not 'even?) 5)
|
|||
|
⇒ t
|
|||
|
(-filter (-not (-partial '< 4)) '(1 2 3 4 5 6 7 8))
|
|||
|
⇒ '(1 2 3 4)
|
|||
|
|
|||
|
-- Function: -orfn (&rest preds)
|
|||
|
Take list of unary predicates PREDS and return a unary predicate
|
|||
|
with argument x that returns non-nil if at least one of the PREDS
|
|||
|
returns non-nil on x.
|
|||
|
|
|||
|
In types: [a -> Bool] -> a -> Bool
|
|||
|
|
|||
|
(-filter (-orfn 'even? (-partial (-flip '<) 5)) '(1 2 3 4 5 6 7 8 9 10))
|
|||
|
⇒ '(1 2 3 4 6 8 10)
|
|||
|
(funcall (-orfn 'stringp 'even?) "foo")
|
|||
|
⇒ t
|
|||
|
|
|||
|
-- Function: -andfn (&rest preds)
|
|||
|
Take list of unary predicates PREDS and return a unary predicate
|
|||
|
with argument x that returns non-nil if all of the PREDS returns
|
|||
|
non-nil on x.
|
|||
|
|
|||
|
In types: [a -> Bool] -> a -> Bool
|
|||
|
|
|||
|
(funcall (-andfn (-cut < <> 10) 'even?) 6)
|
|||
|
⇒ t
|
|||
|
(funcall (-andfn (-cut < <> 10) 'even?) 12)
|
|||
|
⇒ nil
|
|||
|
(-filter (-andfn (-not 'even?) (-cut >= 5 <>)) '(1 2 3 4 5 6 7 8 9 10))
|
|||
|
⇒ '(1 3 5)
|
|||
|
|
|||
|
-- Function: -iteratefn (fn n)
|
|||
|
Return a function FN composed N times with itself.
|
|||
|
|
|||
|
FN is a unary function. If you need to use a function of higher
|
|||
|
arity, use ‘-applify’ (*note -applify::) first to turn it into a
|
|||
|
unary function.
|
|||
|
|
|||
|
With n = 0, this acts as identity function.
|
|||
|
|
|||
|
In types: (a -> a) -> Int -> a -> a.
|
|||
|
|
|||
|
This function satisfies the following law:
|
|||
|
|
|||
|
(funcall (-iteratefn fn n) init) = (-last-item (-iterate fn init
|
|||
|
(1+ n))).
|
|||
|
|
|||
|
(funcall (-iteratefn (lambda (x) (* x x)) 3) 2)
|
|||
|
⇒ 256
|
|||
|
(funcall (-iteratefn '1+ 3) 1)
|
|||
|
⇒ 4
|
|||
|
(funcall (-iteratefn 'cdr 3) '(1 2 3 4 5))
|
|||
|
⇒ '(4 5)
|
|||
|
|
|||
|
-- Function: -fixfn (fn &optional equal-test halt-test)
|
|||
|
Return a function that computes the (least) fixpoint of FN.
|
|||
|
|
|||
|
FN must be a unary function. The returned lambda takes a single
|
|||
|
argument, X, the initial value for the fixpoint iteration. The
|
|||
|
iteration halts when either of the following conditions is
|
|||
|
satisfied:
|
|||
|
|
|||
|
1. Iteration converges to the fixpoint, with equality being tested
|
|||
|
using EQUAL-TEST. If EQUAL-TEST is not specified, ‘equal’ is used.
|
|||
|
For functions over the floating point numbers, it may be necessary
|
|||
|
to provide an appropriate approximate comparison test.
|
|||
|
|
|||
|
2. HALT-TEST returns a non-nil value. HALT-TEST defaults to a
|
|||
|
simple counter that returns t after ‘-fixfn-max-iterations’, to
|
|||
|
guard against infinite iteration. Otherwise, HALT-TEST must be a
|
|||
|
function that accepts a single argument, the current value of X,
|
|||
|
and returns non-nil as long as iteration should continue. In this
|
|||
|
way, a more sophisticated convergence test may be supplied by the
|
|||
|
caller.
|
|||
|
|
|||
|
The return value of the lambda is either the fixpoint or, if
|
|||
|
iteration halted before converging, a cons with car ‘halted’ and
|
|||
|
cdr the final output from HALT-TEST.
|
|||
|
|
|||
|
In types: (a -> a) -> a -> a.
|
|||
|
|
|||
|
(funcall (-fixfn 'cos 'approx-equal) 0.7)
|
|||
|
⇒ 0.7390851332151607
|
|||
|
(funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
|
|||
|
⇒ 1.8555845286409378
|
|||
|
(funcall (-fixfn 'sin 'approx-equal) 0.1)
|
|||
|
⇒ '(halted . t)
|
|||
|
|
|||
|
-- Function: -prodfn (&rest fns)
|
|||
|
Take a list of n functions and return a function that takes a list
|
|||
|
of length n, applying i-th function to i-th element of the input
|
|||
|
list. Returns a list of length n.
|
|||
|
|
|||
|
In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
|
|||
|
|
|||
|
This function satisfies the following laws:
|
|||
|
|
|||
|
(-compose (-prodfn f g ...) (-prodfn f’ g’ ...)) = (-prodfn
|
|||
|
(-compose f f’) (-compose g g’) ...) (-prodfn f g ...) = (-juxt
|
|||
|
(-compose f (-partial ’nth 0)) (-compose g (-partial ’nth 1)) ...)
|
|||
|
(-compose (-prodfn f g ...) (-juxt f’ g’ ...)) = (-juxt (-compose
|
|||
|
f f’) (-compose g g’) ...) (-compose (-partial ’nth n) (-prod f1
|
|||
|
f2 ...)) = (-compose fn (-partial ’nth n))
|
|||
|
|
|||
|
(funcall (-prodfn '1+ '1- 'number-to-string) '(1 2 3))
|
|||
|
⇒ '(2 1 "3")
|
|||
|
(-map (-prodfn '1+ '1-) '((1 2) (3 4) (5 6) (7 8)))
|
|||
|
⇒ '((2 1) (4 3) (6 5) (8 7))
|
|||
|
(apply '+ (funcall (-prodfn 'length 'string-to-number) '((1 2 3) "15")))
|
|||
|
⇒ 18
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Development, Next: Index, Prev: Functions, Up: Top
|
|||
|
|
|||
|
3 Development
|
|||
|
*************
|
|||
|
|
|||
|
The dash repository is hosted on GitHub:
|
|||
|
<https://github.com/magnars/dash.el>
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Contribute:: How to contribute
|
|||
|
* Changes:: List of significant changes by version
|
|||
|
* Contributors:: List of contributors
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Contribute, Next: Changes, Up: Development
|
|||
|
|
|||
|
3.1 Contribute
|
|||
|
==============
|
|||
|
|
|||
|
Yes, please do. Pure functions in the list manipulation realm only,
|
|||
|
please. There’s a suite of tests in dev/examples.el, so remember to add
|
|||
|
tests for your function, or it might get broken later.
|
|||
|
|
|||
|
Run the tests with ‘./run-tests.sh’. Create the docs with
|
|||
|
‘./create-docs.sh’. I highly recommend that you install these as a
|
|||
|
pre-commit hook, so that the tests are always running and the docs are
|
|||
|
always in sync:
|
|||
|
|
|||
|
cp pre-commit.sh .git/hooks/pre-commit
|
|||
|
|
|||
|
Oh, and don’t edit ‘README.md’ directly, it is auto-generated.
|
|||
|
Change ‘readme-template.md’ or ‘examples-to-docs.el’ instead. The same
|
|||
|
goes for the info manual.
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Changes, Next: Contributors, Prev: Contribute, Up: Development
|
|||
|
|
|||
|
3.2 Changes
|
|||
|
===========
|
|||
|
|
|||
|
Changes in 2.10:
|
|||
|
|
|||
|
• Add ‘-let’ destructuring to ‘-if-let’ and ‘-when-let’ (Fredrik
|
|||
|
Bergroth)
|
|||
|
|
|||
|
Changes in 2.9:
|
|||
|
|
|||
|
• Add ‘-let’, ‘-let*’ and ‘-lambda’ with destructuring
|
|||
|
• Add ‘-tree-seq’ and ‘-tree-map-nodes’
|
|||
|
• Add ‘-non-nil’
|
|||
|
• Add ‘-fix’
|
|||
|
• Add ‘-fixfn’ (dash-functional 1.2)
|
|||
|
• Add ‘-copy’ (Wilfred Hughes)
|
|||
|
|
|||
|
Changes in 2.8:
|
|||
|
|
|||
|
• Add ‘-butlast’
|
|||
|
|
|||
|
Changes in 2.7:
|
|||
|
|
|||
|
• ‘-zip’ now supports more than two lists (Steve Lamb)
|
|||
|
• Add ‘-cycle’, ‘-pad’, ‘-annotate’, ‘-zip-fill’ (Steve Lamb)
|
|||
|
• Add ‘-table’, ‘-table-flat’ (finite cartesian product)
|
|||
|
• Add ‘-flatten-n’
|
|||
|
• ‘-slice’ now supports "step" argument
|
|||
|
• Add functional combinators ‘-iteratefn’, ‘-prodfn’
|
|||
|
• Add ‘-replace’, ‘-splice’, ‘-splice-list’ which generalize
|
|||
|
‘-replace-at’ and ‘-insert-at’
|
|||
|
• Add ‘-compose’, ‘-iteratefn’ and ‘-prodfn’ (dash-functional 1.1)
|
|||
|
|
|||
|
Changes in 2.6:
|
|||
|
|
|||
|
• Add ‘-is-prefix-p’, ‘-is-suffix-p’, ‘-is-infix-p’ (Matus Goljer)
|
|||
|
• Add ‘-iterate’, ‘-unfold’ (Matus Goljer)
|
|||
|
• Add ‘-split-on’, ‘-split-when’ (Matus Goljer)
|
|||
|
• Add ‘-find-last-index’ (Matus Goljer)
|
|||
|
• Add ‘-list’ (Johan Andersson)
|
|||
|
|
|||
|
Changes in 2.5:
|
|||
|
|
|||
|
• Add ‘-same-items?’ (Johan Andersson)
|
|||
|
• A few bugfixes
|
|||
|
|
|||
|
Changes in 2.4:
|
|||
|
|
|||
|
• Add ‘-snoc’ (Matus Goljer)
|
|||
|
• Add ‘-replace-at’, ‘-update-at’, ‘-remove-at’, and
|
|||
|
‘-remove-at-indices’ (Matus Goljer)
|
|||
|
|
|||
|
Changes in 2.3:
|
|||
|
|
|||
|
• Add tree operations (Matus Goljer)
|
|||
|
• Make font-lock optional
|
|||
|
|
|||
|
Changes in 2.2:
|
|||
|
|
|||
|
• Add ‘-compose’ (Christina Whyte)
|
|||
|
|
|||
|
Changes in 2.1:
|
|||
|
|
|||
|
• Add indexing operations (Matus Goljer)
|
|||
|
|
|||
|
Changes in 2.0:
|
|||
|
|
|||
|
• Split out ‘dash-functional.el’ (Matus Goljer)
|
|||
|
• Add ‘-andfn’, ‘-orfn’, ‘-not’, ‘-cut’, ‘-const’, ‘-flip’ and ‘-on’.
|
|||
|
(Matus Goljer)
|
|||
|
• Fix ‘-min’, ‘-max’, ‘-min-by’ and ‘-max-by’ (Matus Goljer)
|
|||
|
|
|||
|
Changes in 1.8:
|
|||
|
|
|||
|
• Add ‘-first-item’ and ‘-last-item’ (Wilfred Hughes)
|
|||
|
|
|||
|
Changes in 1.7:
|
|||
|
|
|||
|
• Add ‘-rotate’ (Matus Goljer)
|
|||
|
|
|||
|
Changes in 1.6:
|
|||
|
|
|||
|
• Add ‘-min’, ‘-max’, ‘-min-by’ and ‘-max-by’ (Johan Andersson)
|
|||
|
|
|||
|
Changes in 1.5:
|
|||
|
|
|||
|
• Add ‘-sum’ and ‘-product’ (Johan Andersson)
|
|||
|
|
|||
|
Changes in 1.4:
|
|||
|
|
|||
|
• Add ‘-sort’
|
|||
|
• Add ‘-reduce-r’ (Matus Goljer)
|
|||
|
• Add ‘-reduce-r-from’ (Matus Goljer)
|
|||
|
|
|||
|
Changes in 1.3:
|
|||
|
|
|||
|
• Add ‘-partition-in-steps’
|
|||
|
• Add ‘-partition-all-in-steps’
|
|||
|
|
|||
|
Changes in 1.2:
|
|||
|
|
|||
|
• Add ‘-last’ (Matus Goljer)
|
|||
|
• Add ‘-insert-at’ (Emanuel Evans)
|
|||
|
• Add ‘-when-let’ and ‘-if-let’ (Emanuel Evans)
|
|||
|
• Add ‘-when-let*’ and ‘-if-let*’ (Emanuel Evans)
|
|||
|
• Some bugfixes
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Contributors, Prev: Changes, Up: Development
|
|||
|
|
|||
|
3.3 Contributors
|
|||
|
================
|
|||
|
|
|||
|
• Matus Goljer (https://github.com/Fuco1) contributed lots of
|
|||
|
features and functions.
|
|||
|
• Takafumi Arakaki (https://github.com/tkf) contributed ‘-group-by’.
|
|||
|
• tali713 (https://github.com/tali713) is the author of ‘-applify’.
|
|||
|
• Víctor M. Valenzuela (https://github.com/vemv) contributed
|
|||
|
‘-repeat’.
|
|||
|
• Nic Ferrier (https://github.com/nicferrier) contributed ‘-cons*’.
|
|||
|
• Wilfred Hughes (https://github.com/Wilfred) contributed ‘-slice’,
|
|||
|
‘-first-item’ and ‘-last-item’.
|
|||
|
• Emanuel Evans (https://github.com/shosti) contributed ‘-if-let’,
|
|||
|
‘-when-let’ and ‘-insert-at’.
|
|||
|
• Johan Andersson (https://github.com/rejeep) contributed ‘-sum’,
|
|||
|
‘-product’ and ‘-same-items?’
|
|||
|
• Christina Whyte (https://github.com/kurisuwhyte) contributed
|
|||
|
‘-compose’
|
|||
|
• Steve Lamb (https://github.com/steventlamb) contributed ‘-cycle’,
|
|||
|
‘-pad’, ‘-annotate’, ‘-zip-fill’ and an n-ary version of ‘-zip’.
|
|||
|
• Fredrik Bergroth (https://github.com/fbergroth) made the ‘-if-let’
|
|||
|
family use ‘-let’ destructuring and improved script for generating
|
|||
|
documentation.
|
|||
|
• Mark Oteiza (https://github.com/holomorph) contributed the script
|
|||
|
to create an info manual.
|
|||
|
• Vasilij Schneidermann (https://github.com/wasamasa) contributed
|
|||
|
‘-some’.
|
|||
|
• William West (https://github.com/occidens) made ‘-fixfn’ more
|
|||
|
robust at handling floats.
|
|||
|
|
|||
|
Thanks!
|
|||
|
|
|||
|
|
|||
|
File: dash.info, Node: Index, Prev: Development, Up: Top
|
|||
|
|
|||
|
Index
|
|||
|
*****
|
|||
|
|
|||
|
|