2022-04-22 02:54:47 +00:00
|
|
|
|
This is dash.info, produced by makeinfo version 6.7 from dash.texi.
|
|
|
|
|
|
|
|
|
|
This manual is for Dash version 2.19.1.
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Copyright © 2012–2023 Free Software Foundation, Inc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
Permission is granted to copy, distribute and/or modify this
|
|
|
|
|
document under the terms of the GNU Free Documentation License,
|
|
|
|
|
Version 1.3 or any later version published by the Free Software
|
|
|
|
|
Foundation; with the Invariant Sections being “GNU General Public
|
|
|
|
|
License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
|
|
|
|
|
the license is included in the section entitled “GNU Free
|
|
|
|
|
Documentation License”.
|
|
|
|
|
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 version 2.19.1.
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Copyright © 2012–2023 Free Software Foundation, Inc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
Permission is granted to copy, distribute and/or modify this
|
|
|
|
|
document under the terms of the GNU Free Documentation License,
|
|
|
|
|
Version 1.3 or any later version published by the Free Software
|
|
|
|
|
Foundation; with the Invariant Sections being “GNU General Public
|
|
|
|
|
License,” and no Front-Cover Texts or Back-Cover Texts. A copy of
|
|
|
|
|
the license is included in the section entitled “GNU Free
|
|
|
|
|
Documentation License”.
|
|
|
|
|
|
|
|
|
|
* Menu:
|
|
|
|
|
|
|
|
|
|
* Installation:: Installing and configuring Dash.
|
|
|
|
|
* Functions:: Dash API reference.
|
|
|
|
|
* Development:: Contributing to Dash development.
|
|
|
|
|
|
|
|
|
|
Appendices
|
|
|
|
|
|
|
|
|
|
* FDL:: The license for this documentation.
|
|
|
|
|
* GPL:: Conditions for copying and changing Dash.
|
|
|
|
|
* Index:: Index including functions and macros.
|
|
|
|
|
|
|
|
|
|
— The Detailed Node Listing —
|
|
|
|
|
|
|
|
|
|
Installation
|
|
|
|
|
|
|
|
|
|
* Using in a package:: Listing Dash as a package dependency.
|
|
|
|
|
* Fontification of special variables:: Font Lock of anaphoric macro variables.
|
|
|
|
|
* Info symbol lookup:: Looking up Dash symbols in this manual.
|
|
|
|
|
|
|
|
|
|
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.
|
|
|
|
|
* Contributors:: List of contributors.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Installation, Next: Functions, Prev: Top, Up: Top
|
|
|
|
|
|
|
|
|
|
1 Installation
|
|
|
|
|
**************
|
|
|
|
|
|
|
|
|
|
Dash is available on GNU ELPA (https://elpa.gnu.org/), GNU-devel ELPA
|
|
|
|
|
(https://elpa.gnu.org/devel/), and MELPA (https://melpa.org/), and can
|
|
|
|
|
be installed with the standard command ‘package-install’ (*note
|
|
|
|
|
(emacs)Package Installation::).
|
|
|
|
|
|
|
|
|
|
‘M-x package-install <RET> dash <RET>’
|
|
|
|
|
Install the Dash library.
|
|
|
|
|
|
|
|
|
|
Alternatively, you can just dump ‘dash.el’ in your ‘load-path’
|
|
|
|
|
somewhere (*note (emacs)Lisp Libraries::).
|
|
|
|
|
|
|
|
|
|
* Menu:
|
|
|
|
|
|
|
|
|
|
* Using in a package:: Listing Dash as a package dependency.
|
|
|
|
|
* Fontification of special variables:: Font Lock of anaphoric macro variables.
|
|
|
|
|
* Info symbol lookup:: Looking up Dash symbols in this manual.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Using in a package, Next: Fontification of special variables, Up: Installation
|
|
|
|
|
|
|
|
|
|
1.1 Using in a package
|
|
|
|
|
======================
|
|
|
|
|
|
|
|
|
|
If you use Dash in your own package, be sure to list it as a dependency
|
|
|
|
|
in the library’s headers as follows (*note (elisp)Library Headers::).
|
|
|
|
|
|
|
|
|
|
;; Package-Requires: ((dash "2.19.1"))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Fontification of special variables, Next: Info symbol lookup, Prev: Using in a package, Up: Installation
|
|
|
|
|
|
|
|
|
|
1.2 Fontification of special variables
|
|
|
|
|
======================================
|
|
|
|
|
|
|
|
|
|
The autoloaded minor mode ‘dash-fontify-mode’ is provided for optional
|
|
|
|
|
fontification of anaphoric Dash variables (‘it’, ‘acc’, etc.) in Emacs
|
|
|
|
|
Lisp buffers using search-based Font Lock (*note (emacs)Font Lock::).
|
|
|
|
|
In older Emacs versions which do not dynamically detect macros, the
|
|
|
|
|
minor mode also fontifies calls to Dash macros.
|
|
|
|
|
|
|
|
|
|
To automatically enable the minor mode in all Emacs Lisp buffers,
|
|
|
|
|
just call its autoloaded global counterpart ‘global-dash-fontify-mode’,
|
|
|
|
|
either interactively or from your ‘user-init-file’:
|
|
|
|
|
|
|
|
|
|
(global-dash-fontify-mode)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Info symbol lookup, Prev: Fontification of special variables, Up: Installation
|
|
|
|
|
|
|
|
|
|
1.3 Info symbol lookup
|
|
|
|
|
======================
|
|
|
|
|
|
|
|
|
|
While editing Elisp files, you can use ‘C-h S’ (‘info-lookup-symbol’) to
|
|
|
|
|
look up Elisp symbols in the relevant Info manuals (*note (emacs)Info
|
|
|
|
|
Lookup::). To enable the same for Dash symbols, use the command
|
|
|
|
|
‘dash-register-info-lookup’. It can be called directly when needed, or
|
|
|
|
|
automatically from your ‘user-init-file’. For example:
|
|
|
|
|
|
|
|
|
|
(with-eval-after-load 'info-look
|
|
|
|
|
(dash-register-info-lookup))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Functions, Next: Development, Prev: Installation, Up: Top
|
|
|
|
|
|
|
|
|
|
2 Functions
|
|
|
|
|
***********
|
|
|
|
|
|
|
|
|
|
This chapter contains reference documentation for the Dash API
|
|
|
|
|
(Application Programming Interface). The names of all public functions
|
|
|
|
|
defined in the library are prefixed with a dash character (‘-’).
|
|
|
|
|
|
|
|
|
|
The library also provides anaphoric macro versions of functions where
|
|
|
|
|
that makes sense. The names of these macros are prefixed with two
|
|
|
|
|
dashes (‘--’) instead of one.
|
|
|
|
|
|
|
|
|
|
For instance, while the function ‘-map’ applies a function to each
|
|
|
|
|
element of a list, its anaphoric counterpart ‘--map’ evaluates a form
|
|
|
|
|
with the local variable ‘it’ temporarily bound to the current list
|
|
|
|
|
element instead.
|
|
|
|
|
|
|
|
|
|
;; Normal version.
|
|
|
|
|
(-map (lambda (n) (* n n)) '(1 2 3 4))
|
|
|
|
|
⇒ (1 4 9 16)
|
|
|
|
|
|
|
|
|
|
;; Anaphoric version.
|
|
|
|
|
(--map (* it it) '(1 2 3 4))
|
|
|
|
|
⇒ (1 4 9 16)
|
|
|
|
|
|
|
|
|
|
The normal version can, of course, also be written as in the
|
|
|
|
|
following example, which demonstrates the utility of both versions.
|
|
|
|
|
|
|
|
|
|
(defun my-square (n)
|
|
|
|
|
"Return N multiplied by itself."
|
|
|
|
|
(* n n))
|
|
|
|
|
|
|
|
|
|
(-map #'my-square '(1 2 3 4))
|
|
|
|
|
⇒ (1 4 9 16)
|
|
|
|
|
|
|
|
|
|
* 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 a new list.
|
|
|
|
|
|
|
|
|
|
-- Function: -map (fn list)
|
|
|
|
|
Apply FN to each item in LIST and return the list of results.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--map’.
|
|
|
|
|
|
|
|
|
|
(-map (lambda (num) (* num num)) '(1 2 3 4))
|
|
|
|
|
⇒ (1 4 9 16)
|
|
|
|
|
(-map #'1+ '(1 2 3 4))
|
|
|
|
|
⇒ (2 3 4 5)
|
|
|
|
|
(--map (* it it) '(1 2 3 4))
|
|
|
|
|
⇒ (1 4 9 16)
|
|
|
|
|
|
|
|
|
|
-- Function: -map-when (pred rep list)
|
|
|
|
|
Use PRED to conditionally apply REP to each item in LIST. Return a
|
|
|
|
|
copy of LIST where the items for which PRED returns ‘nil’ are
|
|
|
|
|
unchanged, and the rest 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)
|
|
|
|
|
Use PRED to determine the first item in LIST to call REP on.
|
|
|
|
|
Return a copy of LIST where the first item for which PRED returns
|
|
|
|
|
non-‘nil’ is replaced with the result of calling REP on that 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)
|
|
|
|
|
Use PRED to determine the last item in LIST to call REP on. Return
|
|
|
|
|
a copy of LIST where the last item for which PRED returns non-‘nil’
|
|
|
|
|
is replaced with the result of calling REP on that 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)
|
|
|
|
|
Apply FN to each index and item in LIST and return the list of
|
|
|
|
|
results. This is like ‘-map’ (*note -map::), but FN takes two
|
|
|
|
|
arguments: the index of the current element within LIST, and the
|
|
|
|
|
element itself.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--map-indexed’.
|
|
|
|
|
|
|
|
|
|
For a side-effecting variant, 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)
|
|
|
|
|
(-map-indexed #'* '(1 2 3 4))
|
|
|
|
|
⇒ (0 2 6 12)
|
|
|
|
|
|
|
|
|
|
-- Function: -annotate (fn list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Pair each item in LIST with the result of passing it to FN.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return an alist of (RESULT . ITEM), where each ITEM is the
|
|
|
|
|
corresponding element of LIST, and RESULT is the value obtained by
|
|
|
|
|
calling FN on ITEM.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--annotate’.
|
|
|
|
|
|
|
|
|
|
(-annotate #'1+ '(1 2 3))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ ((2 . 1) (3 . 2) (4 . 3))
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-annotate #'length '((f o o) (bar baz)))
|
|
|
|
|
⇒ ((3 f o o) (2 bar baz))
|
|
|
|
|
(--annotate (> it 1) '(0 1 2 3))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ ((nil . 0) (nil . 1) (t . 2) (t . 3))
|
|
|
|
|
|
|
|
|
|
-- Function: -splice (pred fun list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Splice lists generated by FUN in place of items satisfying PRED in
|
2022-04-22 02:54:47 +00:00
|
|
|
|
LIST.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Call PRED on each element of LIST. Whenever the result of PRED is
|
|
|
|
|
‘nil’, leave that ‘it’ as-is. Otherwise, call FUN on the same ‘it’
|
|
|
|
|
that satisfied PRED. The result should be a (possibly empty) list
|
|
|
|
|
of items to splice in place of ‘it’ in LIST.
|
|
|
|
|
|
|
|
|
|
This can be useful as an alternative to the ‘,@’ construct in a ‘`’
|
|
|
|
|
structure, in case you need to splice several lists at marked
|
|
|
|
|
positions (for example with keywords).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
This function’s anaphoric counterpart is ‘--splice’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
See also: ‘-splice-list’ (*note -splice-list::), ‘-insert-at’
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(*note -insert-at::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-splice #'numberp (lambda (n) (list n n)) '(a 1 b 2))
|
|
|
|
|
⇒ (a 1 1 b 2 2)
|
|
|
|
|
(--splice t (list it it) '(1 2 3 4))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (1 1 2 2 3 3 4 4)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(--splice (eq it :magic) '((magical) (code)) '((foo) :magic (bar)))
|
|
|
|
|
⇒ ((foo) (magical) (code) (bar))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- 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 (list)
|
|
|
|
|
Create a shallow copy of 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
|
|
|
|
|
non-‘nil’.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-select’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--filter’.
|
|
|
|
|
|
|
|
|
|
For similar operations, see also ‘-keep’ (*note -keep::) and
|
|
|
|
|
‘-remove’ (*note -remove::).
|
|
|
|
|
|
|
|
|
|
(-filter (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
|
|
|
|
|
⇒ (2 4)
|
|
|
|
|
(-filter #'natnump '(-2 -1 0 1 2))
|
|
|
|
|
⇒ (0 1 2)
|
|
|
|
|
(--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’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--remove’.
|
|
|
|
|
|
|
|
|
|
For similar operations, see also ‘-keep’ (*note -keep::) and
|
|
|
|
|
‘-filter’ (*note -filter::).
|
|
|
|
|
|
|
|
|
|
(-remove (lambda (num) (= 0 (% num 2))) '(1 2 3 4))
|
|
|
|
|
⇒ (1 3)
|
|
|
|
|
(-remove #'natnump '(-2 -1 0 1 2))
|
|
|
|
|
⇒ (-2 -1)
|
|
|
|
|
(--remove (= 0 (% it 2)) '(1 2 3 4))
|
|
|
|
|
⇒ (1 3)
|
|
|
|
|
|
|
|
|
|
-- Function: -remove-first (pred list)
|
|
|
|
|
Remove the first item from LIST for which PRED returns non-‘nil’.
|
|
|
|
|
This is a non-destructive operation, but only the front of LIST
|
|
|
|
|
leading up to the removed item is a copy; the rest is LIST’s
|
|
|
|
|
original tail. If no item is removed, then the result is a
|
|
|
|
|
complete copy.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-reject-first’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--remove-first’.
|
|
|
|
|
|
|
|
|
|
See also ‘-map-first’ (*note -map-first::), ‘-remove-item’ (*note
|
|
|
|
|
-remove-item::), and ‘-remove-last’ (*note -remove-last::).
|
|
|
|
|
|
|
|
|
|
(-remove-first #'natnump '(-2 -1 0 1 2))
|
|
|
|
|
⇒ (-2 -1 1 2)
|
|
|
|
|
(-remove-first #'stringp '(1 2 "first" "second"))
|
|
|
|
|
⇒ (1 2 "second")
|
|
|
|
|
(--remove-first (> it 3) '(1 2 3 4 5 6))
|
|
|
|
|
⇒ (1 2 3 5 6)
|
|
|
|
|
|
|
|
|
|
-- Function: -remove-last (pred list)
|
|
|
|
|
Remove the last item from LIST for which PRED returns non-‘nil’.
|
|
|
|
|
The result is a copy of LIST regardless of whether an element is
|
|
|
|
|
removed.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-reject-last’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--remove-last’.
|
|
|
|
|
|
|
|
|
|
See also ‘-map-last’ (*note -map-last::), ‘-remove-item’ (*note
|
|
|
|
|
-remove-item::), and ‘-remove-first’ (*note -remove-first::).
|
|
|
|
|
|
|
|
|
|
(-remove-last #'natnump '(1 3 5 4 7 8 10 -11))
|
|
|
|
|
⇒ (1 3 5 4 7 8 -11)
|
|
|
|
|
(-remove-last #'stringp '(1 2 "last" "second"))
|
|
|
|
|
⇒ (1 2 "last")
|
|
|
|
|
(--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)
|
|
|
|
|
Return a copy of LIST with all occurrences of ITEM removed. The
|
|
|
|
|
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"))
|
|
|
|
|
⇒ ("alice" "eve")
|
|
|
|
|
|
|
|
|
|
-- Function: -non-nil (list)
|
|
|
|
|
Return a copy of LIST with all ‘nil’ items removed.
|
|
|
|
|
|
|
|
|
|
(-non-nil '(nil 1 nil 2 nil nil 3 4 nil 5 nil))
|
|
|
|
|
⇒ (1 2 3 4 5)
|
|
|
|
|
(-non-nil '((nil)))
|
|
|
|
|
⇒ ((nil))
|
|
|
|
|
(-non-nil ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
|
|
|
|
|
-- 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 copy of the first N items in LIST. Return a copy of LIST
|
|
|
|
|
if it contains N items or fewer. Return ‘nil’ if N is zero or
|
|
|
|
|
less.
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
(-take 0 '(1 2 3 4 5))
|
|
|
|
|
⇒ ()
|
|
|
|
|
|
|
|
|
|
-- Function: -take-last (n list)
|
|
|
|
|
Return a copy of the last N items of LIST in order. Return a copy
|
|
|
|
|
of LIST if it contains N items or fewer. Return ‘nil’ if N is zero
|
|
|
|
|
or less.
|
|
|
|
|
|
|
|
|
|
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 (not a copy) of LIST without the first N items.
|
|
|
|
|
Return ‘nil’ if LIST contains N items or fewer. Return LIST if N
|
|
|
|
|
is zero or less.
|
|
|
|
|
|
|
|
|
|
For another variant, see also ‘-drop-last’ (*note -drop-last::).
|
|
|
|
|
|
|
|
|
|
(-drop 3 '(1 2 3 4 5))
|
|
|
|
|
⇒ (4 5)
|
|
|
|
|
(-drop 17 '(1 2 3 4 5))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-drop 0 '(1 2 3 4 5))
|
|
|
|
|
⇒ (1 2 3 4 5)
|
|
|
|
|
|
|
|
|
|
-- Function: -drop-last (n list)
|
|
|
|
|
Return a copy of LIST without its last N items. Return a copy of
|
|
|
|
|
LIST if N is zero or less. Return ‘nil’ if LIST contains N items
|
|
|
|
|
or fewer.
|
|
|
|
|
|
|
|
|
|
See also: ‘-drop’ (*note -drop::).
|
|
|
|
|
|
|
|
|
|
(-drop-last 3 '(1 2 3 4 5))
|
|
|
|
|
⇒ (1 2)
|
|
|
|
|
(-drop-last 17 '(1 2 3 4 5))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-drop-last 0 '(1 2 3 4 5))
|
|
|
|
|
⇒ (1 2 3 4 5)
|
|
|
|
|
|
|
|
|
|
-- Function: -take-while (pred list)
|
|
|
|
|
Take successive items from LIST for which PRED returns non-‘nil’.
|
|
|
|
|
PRED is a function of one argument. Return a new list of the
|
|
|
|
|
successive elements from the start of LIST for which PRED returns
|
|
|
|
|
non-‘nil’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--take-while’.
|
|
|
|
|
|
|
|
|
|
For another variant, see also ‘-drop-while’ (*note -drop-while::).
|
|
|
|
|
|
|
|
|
|
(-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)
|
|
|
|
|
Drop successive items from LIST for which PRED returns non-‘nil’.
|
|
|
|
|
PRED is a function of one argument. Return the tail (not a copy)
|
|
|
|
|
of LIST starting from its first element for which PRED returns
|
|
|
|
|
‘nil’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--drop-while’.
|
|
|
|
|
|
|
|
|
|
For another variant, see also ‘-take-while’ (*note -take-while::).
|
|
|
|
|
|
|
|
|
|
(-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 each
|
|
|
|
|
item in LIST. Like ‘-filter’ (*note -filter::), but returns the
|
|
|
|
|
non-‘nil’ results of FN instead of the corresponding elements of
|
|
|
|
|
LIST.
|
|
|
|
|
|
|
|
|
|
Its anaphoric counterpart is ‘--keep’.
|
|
|
|
|
|
|
|
|
|
(-keep #'cdr '((1 2 3) (4 5) (6)))
|
|
|
|
|
⇒ ((2 3) (5))
|
|
|
|
|
(-keep (lambda (n) (and (> n 3) (* 10 n))) '(1 2 3 4 5 6))
|
|
|
|
|
⇒ (40 50 60)
|
|
|
|
|
(--keep (and (> it 3) (* 10 it)) '(1 2 3 4 5 6))
|
|
|
|
|
⇒ (40 50 60)
|
|
|
|
|
|
|
|
|
|
-- Function: -concat (&rest sequences)
|
|
|
|
|
Concatenate all the arguments and make the result a list. The
|
|
|
|
|
result is a list whose elements are the elements of all the
|
2022-11-08 03:31:08 +00:00
|
|
|
|
arguments. Each argument may be a list, vector or string.
|
|
|
|
|
|
|
|
|
|
All arguments except the last argument are copied. The last
|
|
|
|
|
argument is just used as the tail of the new list.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-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)
|
|
|
|
|
Use FUNC to update the Nth element of LIST. Return a copy of LIST
|
|
|
|
|
where the Nth element is replaced with the result of calling FUNC
|
|
|
|
|
on it.
|
|
|
|
|
|
|
|
|
|
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)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Return LIST with its element at index N removed. That is, remove
|
|
|
|
|
any element selected as (nth N LIST) from LIST and return the
|
|
|
|
|
result.
|
|
|
|
|
|
|
|
|
|
This is a non-destructive operation: parts of LIST (but not
|
|
|
|
|
necessarily all of it) are copied as needed to avoid destructively
|
|
|
|
|
modifying it.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
See also: ‘-remove-at-indices’ (*note -remove-at-indices::),
|
2023-03-22 11:44:34 +00:00
|
|
|
|
‘-remove’ (*note -remove::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-remove-at 0 '(a b c))
|
|
|
|
|
⇒ (b c)
|
|
|
|
|
(-remove-at 1 '(a b c))
|
|
|
|
|
⇒ (a c)
|
|
|
|
|
(-remove-at 2 '(a b c))
|
|
|
|
|
⇒ (a b)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -remove-at-indices (indices list)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Return LIST with its elements at INDICES removed. That is, for
|
|
|
|
|
each index I in INDICES, remove any element selected as (nth I
|
|
|
|
|
LIST) from LIST.
|
|
|
|
|
|
|
|
|
|
This is a non-destructive operation: parts of LIST (but not
|
|
|
|
|
necessarily all of it) are copied as needed to avoid destructively
|
|
|
|
|
modifying it.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
See also: ‘-remove-at’ (*note -remove-at::), ‘-remove’ (*note
|
2023-03-22 11:44:34 +00:00
|
|
|
|
-remove::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-remove-at-indices '(0) '(a b c d e))
|
|
|
|
|
⇒ (b c d e)
|
|
|
|
|
(-remove-at-indices '(1 3) '(a b c d e))
|
|
|
|
|
⇒ (a c e)
|
|
|
|
|
(-remove-at-indices '(4 0 2) '(a b c d e))
|
|
|
|
|
⇒ (b d)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Reductions, Next: Unfolding, Prev: List to list, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.4 Reductions
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
Functions reducing lists to a single value (which may also be a list).
|
|
|
|
|
|
|
|
|
|
-- Function: -reduce-from (fn init list)
|
|
|
|
|
Reduce the function FN across LIST, starting with INIT. Return the
|
|
|
|
|
result of applying FN to INIT and the first element of LIST, then
|
|
|
|
|
applying FN to that result and the second element, etc. If LIST is
|
|
|
|
|
empty, return INIT without calling FN.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reduce-from’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reduce’ (*note -reduce::) and
|
|
|
|
|
‘-reduce-r’ (*note -reduce-r::).
|
|
|
|
|
|
|
|
|
|
(-reduce-from #'- 10 '(1 2 3))
|
|
|
|
|
⇒ 4
|
|
|
|
|
(-reduce-from #'list 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 init list)
|
|
|
|
|
Reduce the function FN across LIST in reverse, starting with INIT.
|
|
|
|
|
Return the result of applying FN to the last element of LIST and
|
|
|
|
|
INIT, then applying FN to the second-to-last element and the
|
|
|
|
|
previous result of FN, etc. That is, the first argument of FN is
|
|
|
|
|
the current element, and its second argument the accumulated value.
|
|
|
|
|
If LIST is empty, return INIT without calling FN.
|
|
|
|
|
|
|
|
|
|
This function is like ‘-reduce-from’ (*note -reduce-from::) but the
|
|
|
|
|
operation associates from the right rather than left. In other
|
|
|
|
|
words, it starts from the end of LIST and flips the arguments to
|
|
|
|
|
FN. Conceptually, it is like replacing the conses in LIST with
|
|
|
|
|
applications of FN, and its last link with INIT, and evaluating the
|
|
|
|
|
resulting expression.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reduce-r-from’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reduce-r’ (*note -reduce-r::) and
|
|
|
|
|
‘-reduce’ (*note -reduce::).
|
|
|
|
|
|
|
|
|
|
(-reduce-r-from #'- 10 '(1 2 3))
|
|
|
|
|
⇒ -8
|
|
|
|
|
(-reduce-r-from #'list 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)
|
|
|
|
|
Reduce the function FN across LIST. Return the result of applying
|
|
|
|
|
FN to the first two elements of LIST, then applying FN to that
|
|
|
|
|
result and the third element, etc. If LIST contains a single
|
|
|
|
|
element, return it without calling FN. If LIST is empty, return
|
|
|
|
|
the result of calling FN with no arguments.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reduce’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reduce-from’ (*note -reduce-from::) and
|
|
|
|
|
‘-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)
|
|
|
|
|
Reduce the function FN across LIST in reverse. Return the result
|
|
|
|
|
of applying FN to the last two elements of LIST, then applying FN
|
|
|
|
|
to the third-to-last element and the previous result of FN, etc.
|
|
|
|
|
That is, the first argument of FN is the current element, and its
|
|
|
|
|
second argument the accumulated value. If LIST contains a single
|
|
|
|
|
element, return it without calling FN. If LIST is empty, return
|
|
|
|
|
the result of calling FN with no arguments.
|
|
|
|
|
|
|
|
|
|
This function is like ‘-reduce’ (*note -reduce::) but the operation
|
|
|
|
|
associates from the right rather than left. In other words, it
|
|
|
|
|
starts from the end of LIST and flips the arguments to FN.
|
|
|
|
|
Conceptually, it is like replacing the conses in LIST with
|
|
|
|
|
applications of FN, ignoring its last link, and evaluating the
|
|
|
|
|
resulting expression.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reduce-r’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reduce-r-from’ (*note -reduce-r-from::)
|
|
|
|
|
and ‘-reduce’ (*note -reduce::).
|
|
|
|
|
|
|
|
|
|
(-reduce-r #'- '(1 2 3 4))
|
|
|
|
|
⇒ -2
|
|
|
|
|
(-reduce-r #'list '(1 2 3 4))
|
|
|
|
|
⇒ (1 (2 (3 4)))
|
|
|
|
|
(--reduce-r (format "%s-%d" acc it) '(1 2 3))
|
|
|
|
|
⇒ "3-2-1"
|
|
|
|
|
|
|
|
|
|
-- Function: -reductions-from (fn init list)
|
|
|
|
|
Return a list of FN’s intermediate reductions across LIST. That
|
|
|
|
|
is, a list of the intermediate values of the accumulator when
|
|
|
|
|
‘-reduce-from’ (*note -reduce-from::) (which see) is called with
|
|
|
|
|
the same arguments.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reductions-from’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reductions’ (*note -reductions::) and
|
|
|
|
|
‘-reductions-r’ (*note -reductions-r::).
|
|
|
|
|
|
|
|
|
|
(-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)
|
|
|
|
|
(--reductions-from (format "(FN %s %d)" acc it) "INIT" '(1 2 3))
|
|
|
|
|
⇒ ("INIT" "(FN INIT 1)" "(FN (FN INIT 1) 2)" "(FN (FN (FN INIT 1) 2) 3)")
|
|
|
|
|
|
|
|
|
|
-- Function: -reductions-r-from (fn init list)
|
|
|
|
|
Return a list of FN’s intermediate reductions across reversed LIST.
|
|
|
|
|
That is, a list of the intermediate values of the accumulator when
|
|
|
|
|
‘-reduce-r-from’ (*note -reduce-r-from::) (which see) is called
|
|
|
|
|
with the same arguments.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reductions-r-from’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reductions’ (*note -reductions::) and
|
|
|
|
|
‘-reductions-r’ (*note -reductions-r::).
|
|
|
|
|
|
|
|
|
|
(-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)
|
|
|
|
|
(--reductions-r-from (format "(FN %d %s)" it acc) "INIT" '(1 2 3))
|
|
|
|
|
⇒ ("(FN 1 (FN 2 (FN 3 INIT)))" "(FN 2 (FN 3 INIT))" "(FN 3 INIT)" "INIT")
|
|
|
|
|
|
|
|
|
|
-- Function: -reductions (fn list)
|
|
|
|
|
Return a list of FN’s intermediate reductions across LIST. That
|
|
|
|
|
is, a list of the intermediate values of the accumulator when
|
|
|
|
|
‘-reduce’ (*note -reduce::) (which see) is called with the same
|
|
|
|
|
arguments.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reductions’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reductions’ (*note -reductions::) and
|
|
|
|
|
‘-reductions-r’ (*note -reductions-r::).
|
|
|
|
|
|
|
|
|
|
(-reductions #'+ '(1 2 3 4))
|
|
|
|
|
⇒ (1 3 6 10)
|
|
|
|
|
(-reductions #'* '(1 2 3 4))
|
|
|
|
|
⇒ (1 2 6 24)
|
|
|
|
|
(--reductions (format "(FN %s %d)" acc it) '(1 2 3))
|
|
|
|
|
⇒ (1 "(FN 1 2)" "(FN (FN 1 2) 3)")
|
|
|
|
|
|
|
|
|
|
-- Function: -reductions-r (fn list)
|
|
|
|
|
Return a list of FN’s intermediate reductions across reversed LIST.
|
|
|
|
|
That is, a list of the intermediate values of the accumulator when
|
|
|
|
|
‘-reduce-r’ (*note -reduce-r::) (which see) is called with the same
|
|
|
|
|
arguments.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--reductions-r’.
|
|
|
|
|
|
|
|
|
|
For other folds, see also ‘-reductions-r-from’ (*note
|
|
|
|
|
-reductions-r-from::) and ‘-reductions’ (*note -reductions::).
|
|
|
|
|
|
|
|
|
|
(-reductions-r #'+ '(1 2 3 4))
|
|
|
|
|
⇒ (10 9 7 4)
|
|
|
|
|
(-reductions-r #'* '(1 2 3 4))
|
|
|
|
|
⇒ (24 24 12 4)
|
|
|
|
|
(--reductions-r (format "(FN %d %s)" it acc) '(1 2 3))
|
|
|
|
|
⇒ ("(FN 1 (FN 2 3))" "(FN 2 3)" 3)
|
|
|
|
|
|
|
|
|
|
-- 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→ Wrong type argument: consp, nil
|
|
|
|
|
|
|
|
|
|
-- 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→ Wrong type argument: consp, nil
|
|
|
|
|
|
|
|
|
|
-- 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)
|
2023-07-27 19:42:55 +00:00
|
|
|
|
Return all suffixes of LIST.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-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))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-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))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-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)
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -frequencies (list)
|
|
|
|
|
Count the occurrences of each distinct element of LIST.
|
|
|
|
|
|
|
|
|
|
Return an alist of (ELEMENT . N), where each ELEMENT occurs N
|
|
|
|
|
times in LIST.
|
|
|
|
|
|
|
|
|
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|
|
|
|
if that is non-‘nil’.
|
|
|
|
|
|
|
|
|
|
See also ‘-count’ (*note -count::) and ‘-group-by’ (*note
|
|
|
|
|
-group-by::).
|
|
|
|
|
|
|
|
|
|
(-frequencies ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-frequencies '(1 2 3 1 2 1))
|
|
|
|
|
⇒ ((1 . 3) (2 . 2) (3 . 1))
|
|
|
|
|
(let ((-compare-fn #'string=)) (-frequencies '(a "a")))
|
|
|
|
|
⇒ ((a . 2))
|
|
|
|
|
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Unfolding, Next: Predicates, Prev: Reductions, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.5 Unfolding
|
|
|
|
|
=============
|
|
|
|
|
|
|
|
|
|
Operations dual to reductions, building lists from a 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 the 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))
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -repeat (n x)
|
|
|
|
|
Return a new list of length N with each element being X. Return
|
|
|
|
|
‘nil’ if N is less than 1.
|
|
|
|
|
|
|
|
|
|
(-repeat 3 :a)
|
|
|
|
|
⇒ (:a :a :a)
|
|
|
|
|
(-repeat 1 :a)
|
|
|
|
|
⇒ (:a)
|
|
|
|
|
(-repeat 0 :a)
|
|
|
|
|
⇒ ()
|
|
|
|
|
|
|
|
|
|
-- Function: -cycle (list)
|
|
|
|
|
Return an infinite circular copy of LIST. The returned list cycles
|
|
|
|
|
through the elements of LIST and repeats 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)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-zip-lists (-cycle '(3)) '(1 2))
|
|
|
|
|
⇒ ((3 1) (3 2))
|
2022-08-04 18:39:38 +00:00
|
|
|
|
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Predicates, Next: Partitioning, Prev: Unfolding, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.6 Predicates
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
Reductions of one or more lists to a boolean value.
|
|
|
|
|
|
|
|
|
|
-- Function: -some (pred list)
|
|
|
|
|
Return (PRED x) for the first LIST item where (PRED x) is
|
|
|
|
|
non-‘nil’, else ‘nil’.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-any’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--some’.
|
|
|
|
|
|
|
|
|
|
(-some #'stringp '(1 "2" 3))
|
|
|
|
|
⇒ t
|
|
|
|
|
(--some (string-match-p "x" it) '("foo" "axe" "xor"))
|
|
|
|
|
⇒ 1
|
|
|
|
|
(--some (= it-index 3) '(0 1 2))
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
|
|
|
|
-- Function: -every (pred list)
|
|
|
|
|
Return non-‘nil’ if PRED returns non-‘nil’ for all items in LIST.
|
|
|
|
|
If so, return the last such result of PRED. Otherwise, once an
|
|
|
|
|
item is reached for which PRED returns ‘nil’, return ‘nil’ without
|
|
|
|
|
calling PRED on any further LIST elements.
|
|
|
|
|
|
|
|
|
|
This function is like ‘-every-p’, but on success returns the last
|
|
|
|
|
non-‘nil’ result of PRED instead of just ‘t’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--every’.
|
|
|
|
|
|
|
|
|
|
(-every #'numberp '(1 2 3))
|
|
|
|
|
⇒ t
|
|
|
|
|
(--every (string-match-p "x" it) '("axe" "xor"))
|
|
|
|
|
⇒ 0
|
|
|
|
|
(--every (= it it-index) '(0 1 3))
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
|
|
|
|
-- 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? #'numberp '(nil 0 t))
|
|
|
|
|
⇒ t
|
|
|
|
|
(-any? #'numberp '(nil t t))
|
|
|
|
|
⇒ 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’.
|
|
|
|
|
In the latter case, stop after the first X for which (PRED X) is
|
|
|
|
|
‘nil’, without calling PRED on any subsequent elements of LIST.
|
|
|
|
|
|
|
|
|
|
The similar function ‘-every’ (*note -every::) is more widely
|
|
|
|
|
useful, since it returns the last non-‘nil’ result of PRED instead
|
|
|
|
|
of just ‘t’ on success.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-all-p’, ‘-every-p’, ‘-every?’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--all?’.
|
|
|
|
|
|
|
|
|
|
(-all? #'numberp '(1 2 3))
|
|
|
|
|
⇒ t
|
|
|
|
|
(-all? #'numberp '(2 t 6))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(--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 different LIST items both satisfy and do not satisfy
|
|
|
|
|
PRED. That is, if PRED returns both ‘nil’ for at least one item,
|
|
|
|
|
and non-‘nil’ for at least one other item in LIST. Return ‘nil’ if
|
|
|
|
|
all items satisfy the predicate or none of them do.
|
|
|
|
|
|
|
|
|
|
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’
|
2022-08-04 18:39:38 +00:00
|
|
|
|
if that is non-‘nil’. As with ‘member’, the return value is
|
|
|
|
|
actually the tail of LIST whose car is ELEMENT.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Alias: ‘-contains-p’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-contains? '(1 2 3) 1)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
⇒ (1 2 3)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-contains? '(1 2 3) 2)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
⇒ (2 3)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-contains? '(1 2 3) 4)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
⇒ ()
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -is-prefix? (prefix list)
|
|
|
|
|
Return non-‘nil’ if PREFIX is a 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 a 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
|
|
|
|
|
|
|
|
|
|
-- Function: -cons-pair? (obj)
|
|
|
|
|
Return non-‘nil’ if OBJ is a true cons pair. That is, a cons (A .
|
|
|
|
|
B) where B is not a list.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-cons-pair-p’.
|
|
|
|
|
|
|
|
|
|
(-cons-pair? '(1 . 2))
|
|
|
|
|
⇒ t
|
|
|
|
|
(-cons-pair? '(1 2))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(-cons-pair? '(1))
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
Split LIST into two sublists after the Nth element. The result is
|
|
|
|
|
a list of two elements (TAKE DROP) where TAKE is a new list of the
|
|
|
|
|
first N elements of LIST, and DROP is the remaining elements of
|
|
|
|
|
LIST (not a copy). TAKE and DROP are like the results of ‘-take’
|
|
|
|
|
(*note -take::) and ‘-drop’ (*note -drop::), respectively, but the
|
|
|
|
|
split is done in a single list traversal.
|
|
|
|
|
|
|
|
|
|
(-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)
|
|
|
|
|
(-split-at 0 '(1 2 3 4 5))
|
|
|
|
|
⇒ (nil (1 2 3 4 5))
|
|
|
|
|
|
|
|
|
|
-- Function: -split-with (pred list)
|
|
|
|
|
Split LIST into a prefix satisfying PRED, and the rest. The first
|
|
|
|
|
sublist is the prefix of LIST with successive elements satisfying
|
|
|
|
|
PRED, and the second sublist is the remaining elements that do not.
|
|
|
|
|
The result is like performing
|
|
|
|
|
|
|
|
|
|
((-take-while PRED LIST) (-drop-while PRED LIST))
|
|
|
|
|
|
|
|
|
|
but in no more than a single pass through 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)
|
|
|
|
|
Split LIST into two sublists based on whether items satisfy PRED.
|
|
|
|
|
The result is like performing
|
|
|
|
|
|
|
|
|
|
((-filter PRED LIST) (-remove PRED LIST))
|
|
|
|
|
|
|
|
|
|
but in a single pass through 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)
|
|
|
|
|
Partition LIST into sublists of length N that are STEP items apart.
|
|
|
|
|
Like ‘-partition-all-in-steps’ (*note -partition-all-in-steps::),
|
|
|
|
|
but 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)
|
|
|
|
|
Partition LIST into sublists of length N that are STEP items apart.
|
|
|
|
|
Adjacent groups may overlap if N exceeds the STEP stride. Trailing
|
|
|
|
|
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 LIST after each element for which PRED returns non-‘nil’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--partition-after-pred’.
|
|
|
|
|
|
|
|
|
|
(-partition-after-pred #'booleanp ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-partition-after-pred #'booleanp '(t t))
|
|
|
|
|
⇒ ((t) (t))
|
|
|
|
|
(-partition-after-pred #'booleanp '(0 0 t t 0 t))
|
|
|
|
|
⇒ ((0 0 t) (t) (0 t))
|
|
|
|
|
|
|
|
|
|
-- Function: -partition-before-pred (pred list)
|
|
|
|
|
Partition directly before each time PRED is true on an element of
|
|
|
|
|
LIST.
|
|
|
|
|
|
|
|
|
|
(-partition-before-pred #'booleanp ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-partition-before-pred #'booleanp '(0 t))
|
|
|
|
|
⇒ ((0) (t))
|
|
|
|
|
(-partition-before-pred #'booleanp '(0 0 t 0 t t))
|
|
|
|
|
⇒ ((0 0) (t 0) (t) (t))
|
|
|
|
|
|
|
|
|
|
-- 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
|
|
|
|
|
============
|
|
|
|
|
|
|
|
|
|
Functions retrieving or sorting based on list indices and related
|
|
|
|
|
predicates.
|
|
|
|
|
|
|
|
|
|
-- Function: -elem-index (elem list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the first index of ELEM in LIST. That is, the index within
|
|
|
|
|
LIST of the first element that is ‘equal’ to ELEM. Return ‘nil’ if
|
|
|
|
|
there is no such element.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-find-index’ (*note -find-index::).
|
|
|
|
|
|
|
|
|
|
(-elem-index 2 '(6 7 8 3 4))
|
|
|
|
|
⇒ nil
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-elem-index "bar" '("foo" "bar" "baz"))
|
|
|
|
|
⇒ 1
|
|
|
|
|
(-elem-index '(1 2) '((3) (5 6) (1 2) nil))
|
|
|
|
|
⇒ 2
|
|
|
|
|
|
|
|
|
|
-- Function: -elem-indices (elem list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the list of indices at which ELEM appears in LIST. That is,
|
|
|
|
|
the indices of all elements of LIST ‘equal’ to ELEM, in the same
|
|
|
|
|
ascending order as they appear in LIST.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-elem-indices 2 '(6 7 8 3 4 1))
|
|
|
|
|
⇒ ()
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-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)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the index of the first item satisfying PRED in LIST. Return
|
|
|
|
|
‘nil’ if no such item is found.
|
|
|
|
|
|
|
|
|
|
PRED is called with one argument, the current list element, until
|
|
|
|
|
it returns non-‘nil’, at which point the search terminates.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--find-index’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-first’ (*note -first::), ‘-find-last-index’ (*note
|
|
|
|
|
-find-last-index::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-find-index #'numberp '(a b c))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(-find-index #'natnump '(1 0 -1))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 0
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(--find-index (> it 5) '(2 4 1 6 3 3 5 8))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 3
|
|
|
|
|
|
|
|
|
|
-- Function: -find-last-index (pred list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the index of the last item satisfying PRED in LIST. Return
|
|
|
|
|
‘nil’ if no such item is found.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Predicate PRED is called with one argument each time, namely the
|
|
|
|
|
current list element.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
This function’s anaphoric counterpart is ‘--find-last-index’.
|
|
|
|
|
|
|
|
|
|
See also: ‘-last’ (*note -last::), ‘-find-index’ (*note
|
|
|
|
|
-find-index::).
|
|
|
|
|
|
|
|
|
|
(-find-last-index #'numberp '(a b c))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(--find-last-index (> it 5) '(2 7 1 6 3 8 5 2))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 5
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-find-last-index (-partial #'string< 'a) '(c b a))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 1
|
|
|
|
|
|
|
|
|
|
-- Function: -find-indices (pred list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the list of indices in LIST satisfying PRED.
|
|
|
|
|
|
|
|
|
|
Each element of LIST in turn is passed to PRED. If the result is
|
|
|
|
|
non-‘nil’, the index of that element in LIST is included in the
|
|
|
|
|
result. The returned indices are in ascending order, i.e., in the
|
|
|
|
|
same order as they appear in LIST.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--find-indices’.
|
|
|
|
|
|
|
|
|
|
See also: ‘-find-index’ (*note -find-index::), ‘-elem-indices’
|
|
|
|
|
(*note -elem-indices::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-find-indices #'numberp '(a b c))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-find-indices #'numberp '(8 1 d 2 b c a 3))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (0 1 3 7)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(--find-indices (> it 5) '(2 4 1 6 3 3 5 8))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (3 7)
|
|
|
|
|
|
|
|
|
|
-- Function: -grade-up (comparator list)
|
|
|
|
|
Grade elements of LIST using COMPARATOR relation. This yields 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. This yields 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.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -union (list1 list2)
|
|
|
|
|
Return a new list of distinct elements appearing in either LIST1 or
|
|
|
|
|
LIST2.
|
|
|
|
|
|
|
|
|
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|
|
|
|
if that is non-‘nil’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-union '(1 2 3) '(3 4 5))
|
|
|
|
|
⇒ (1 2 3 4 5)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-union '(1 2 2 4) ())
|
|
|
|
|
⇒ (1 2 4)
|
|
|
|
|
(-union '(1 1 2 2) '(4 4 3 2 1))
|
|
|
|
|
⇒ (1 2 4 3)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -difference (list1 list2)
|
|
|
|
|
Return a new list with the distinct members of LIST1 that are not
|
|
|
|
|
in LIST2.
|
|
|
|
|
|
|
|
|
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|
|
|
|
if that is non-‘nil’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-difference () ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-difference '(1 2 3) '(4 5 6))
|
|
|
|
|
⇒ (1 2 3)
|
|
|
|
|
(-difference '(1 2 3 4) '(3 4 5 6))
|
|
|
|
|
⇒ (1 2)
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -intersection (list1 list2)
|
|
|
|
|
Return a new list of distinct elements appearing in both LIST1 and
|
|
|
|
|
LIST2.
|
|
|
|
|
|
|
|
|
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|
|
|
|
if that is non-‘nil’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-intersection () ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-intersection '(1 2 3) '(4 5 6))
|
|
|
|
|
⇒ ()
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-intersection '(1 2 2 3) '(4 3 3 2))
|
|
|
|
|
⇒ (2 3)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -powerset (list)
|
|
|
|
|
Return the power set of LIST.
|
|
|
|
|
|
|
|
|
|
(-powerset ())
|
|
|
|
|
⇒ (nil)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-powerset '(x y))
|
|
|
|
|
⇒ ((x y) (x) (y) nil)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-powerset '(x y z))
|
|
|
|
|
⇒ ((x y z) (x y) (x z) (x) (y z) (y) (z) nil)
|
|
|
|
|
|
|
|
|
|
-- Function: -permutations (list)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return the distinct permutations of LIST.
|
|
|
|
|
|
|
|
|
|
Duplicate elements of LIST are determined by ‘equal’, or by
|
|
|
|
|
‘-compare-fn’ if that is non-‘nil’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-permutations ())
|
|
|
|
|
⇒ (nil)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-permutations '(a a b))
|
|
|
|
|
⇒ ((a a b) (a b a) (b a a))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-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)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return a copy of LIST with all duplicate elements removed.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
The test for equality is done with ‘equal’, or with ‘-compare-fn’
|
|
|
|
|
if that is non-‘nil’.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-uniq’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-distinct ())
|
|
|
|
|
⇒ ()
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-distinct '(1 1 2 3 3))
|
|
|
|
|
⇒ (1 2 3)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-distinct '(t t t))
|
|
|
|
|
⇒ (t)
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
-- Function: -same-items? (list1 list2)
|
|
|
|
|
Return non-‘nil’ if LIST1 and LIST2 have the same distinct
|
|
|
|
|
elements.
|
|
|
|
|
|
|
|
|
|
The order of the elements in the lists does not matter. The lists
|
|
|
|
|
may be of different lengths, i.e., contain duplicate elements. The
|
|
|
|
|
test for equality is done with ‘equal’, or with ‘-compare-fn’ if
|
|
|
|
|
that is non-‘nil’.
|
|
|
|
|
|
|
|
|
|
Alias: ‘-same-items-p’.
|
|
|
|
|
|
|
|
|
|
(-same-items? '(1 2 3) '(1 2 3))
|
|
|
|
|
⇒ t
|
|
|
|
|
(-same-items? '(1 1 2 3) '(3 3 2 1))
|
|
|
|
|
⇒ t
|
|
|
|
|
(-same-items? '(1 2 3) '(1 2 3 4))
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
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 (left if N is negative). 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: -cons* (&rest args)
|
|
|
|
|
Make a new list from the elements of ARGS. The last 2 elements of
|
|
|
|
|
ARGS are used as the final cons of the result, so if the final
|
|
|
|
|
element of ARGS is not a list, the result is a dotted list. With
|
|
|
|
|
no ARGS, return ‘nil’.
|
|
|
|
|
|
|
|
|
|
(-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 any ELEMENTS are given, append them 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: -iota (count &optional start step)
|
|
|
|
|
Return a list containing COUNT numbers. Starts from START and adds
|
|
|
|
|
STEP each time. The default START is zero, the default STEP is 1.
|
|
|
|
|
This function takes its name from the corresponding primitive in
|
|
|
|
|
the APL language.
|
|
|
|
|
|
|
|
|
|
(-iota 6)
|
|
|
|
|
⇒ (0 1 2 3 4 5)
|
|
|
|
|
(-iota 4 2.5 -2)
|
|
|
|
|
⇒ (2.5 0.5 -1.5 -3.5)
|
|
|
|
|
(-iota -1)
|
|
|
|
|
error→ Wrong type argument: natnump, -1
|
|
|
|
|
|
|
|
|
|
-- Function: -zip-with (fn list1 list2)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Zip LIST1 and LIST2 into a new list using the function FN. That
|
|
|
|
|
is, apply FN pairwise taking as first argument the next element of
|
|
|
|
|
LIST1 and as second argument the next element of LIST2 at the
|
|
|
|
|
corresponding position. The result is as long as the shorter list.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
This function’s anaphoric counterpart is ‘--zip-with’.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
For other zips, see also ‘-zip-lists’ (*note -zip-lists::) and
|
|
|
|
|
‘-zip-fill’ (*note -zip-fill::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-zip-with #'+ '(1 2 3 4) '(5 6 7))
|
|
|
|
|
⇒ (6 8 10)
|
|
|
|
|
(-zip-with #'cons '(1 2 3) '(4 5 6 7))
|
|
|
|
|
⇒ ((1 . 4) (2 . 5) (3 . 6))
|
|
|
|
|
(--zip-with (format "%s & %s" it other) '(Batman Jekyll) '(Robin Hyde))
|
|
|
|
|
⇒ ("Batman & Robin" "Jekyll & Hyde")
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
-- Function: -zip-pair (list1 list2)
|
|
|
|
|
Zip LIST1 and LIST2 together.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Make a pair with the head of each list, followed by a pair with the
|
|
|
|
|
second element of each list, and so on. The number of pairs
|
|
|
|
|
returned is equal to the length of the shorter input list.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
See also: ‘-zip-lists’ (*note -zip-lists::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-zip-pair '(1 2 3 4) '(5 6 7))
|
|
|
|
|
⇒ ((1 . 5) (2 . 6) (3 . 7))
|
|
|
|
|
(-zip-pair '(1 2 3) '(4 5 6))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ ((1 . 4) (2 . 5) (3 . 6))
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-zip-pair '(1 2) '(3))
|
|
|
|
|
⇒ ((1 . 3))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -zip-lists (&rest lists)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Zip LISTS together.
|
|
|
|
|
|
|
|
|
|
Group the head of each list, followed by the second element of each
|
|
|
|
|
list, and so on. The number of returned groupings is equal to the
|
|
|
|
|
length of the shortest input list, and the length of each grouping
|
|
|
|
|
is equal to the number of input LISTS.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
The return value is always a list of proper lists, in contrast to
|
|
|
|
|
‘-zip’ (*note -zip::) which returns a list of dotted pairs when
|
|
|
|
|
only two input LISTS are provided.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
See also: ‘-zip-pair’ (*note -zip-pair::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-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))
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
-- Function: -zip-lists-fill (fill-value &rest lists)
|
|
|
|
|
Zip LISTS together, padding shorter lists with FILL-VALUE. This is
|
|
|
|
|
like ‘-zip-lists’ (*note -zip-lists::) (which see), except it
|
|
|
|
|
retains all elements at positions beyond the end of the shortest
|
|
|
|
|
list. The number of returned groupings is equal to the length of
|
|
|
|
|
the longest input list, and the length of each grouping is equal to
|
|
|
|
|
the number of input LISTS.
|
|
|
|
|
|
|
|
|
|
(-zip-lists-fill 0 '(1 2) '(3 4 5) '(6))
|
|
|
|
|
⇒ ((1 3 6) (2 4 0) (0 5 0))
|
|
|
|
|
(-zip-lists-fill 0 '(1 2) '(3 4) '(5 6))
|
|
|
|
|
⇒ ((1 3 5) (2 4 6))
|
|
|
|
|
(-zip-lists-fill 0 '(1 2 3) nil)
|
|
|
|
|
⇒ ((1 0) (2 0) (3 0))
|
|
|
|
|
|
|
|
|
|
-- Function: -zip (&rest lists)
|
|
|
|
|
Zip LISTS together.
|
|
|
|
|
|
|
|
|
|
Group the head of each list, followed by the second element of each
|
|
|
|
|
list, and so on. The number of returned groupings is equal to the
|
|
|
|
|
length of the shortest input list, and the number of items in each
|
|
|
|
|
grouping is equal to the number of input LISTS.
|
|
|
|
|
|
|
|
|
|
If only two LISTS are provided as arguments, return the groupings
|
|
|
|
|
as a list of dotted pairs. Otherwise, return the groupings as a
|
|
|
|
|
list of proper lists.
|
|
|
|
|
|
|
|
|
|
Since the return value changes form depending on the number of
|
|
|
|
|
arguments, it is generally recommended to use ‘-zip-lists’ (*note
|
|
|
|
|
-zip-lists::) instead, or ‘-zip-pair’ (*note -zip-pair::) if a list
|
|
|
|
|
of dotted pairs is desired.
|
|
|
|
|
|
|
|
|
|
See also: ‘-unzip’ (*note -unzip::).
|
|
|
|
|
|
|
|
|
|
(-zip '(1 2 3 4) '(5 6 7) '(8 9))
|
|
|
|
|
⇒ ((1 5 8) (2 6 9))
|
|
|
|
|
(-zip '(1 2 3) '(4 5 6) '(7 8 9))
|
|
|
|
|
⇒ ((1 4 7) (2 5 8) (3 6 9))
|
|
|
|
|
(-zip '(1 2 3))
|
|
|
|
|
⇒ ((1) (2) (3))
|
|
|
|
|
|
2022-04-22 02:54:47 +00:00
|
|
|
|
-- Function: -zip-fill (fill-value &rest lists)
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Zip LISTS together, padding shorter lists with FILL-VALUE. This is
|
|
|
|
|
like ‘-zip’ (*note -zip::) (which see), except it retains all
|
|
|
|
|
elements at positions beyond the end of the shortest list. The
|
|
|
|
|
number of returned groupings is equal to the length of the longest
|
|
|
|
|
input list, and the length of each grouping is equal to the number
|
|
|
|
|
of input LISTS.
|
|
|
|
|
|
|
|
|
|
Since the return value changes form depending on the number of
|
|
|
|
|
arguments, it is generally recommended to use ‘-zip-lists-fill’
|
|
|
|
|
(*note -zip-lists-fill::) instead, unless a list of dotted pairs is
|
|
|
|
|
explicitly desired.
|
|
|
|
|
|
|
|
|
|
(-zip-fill 0 '(1 2 3) '(4 5))
|
|
|
|
|
⇒ ((1 . 4) (2 . 5) (3 . 0))
|
|
|
|
|
(-zip-fill 0 () '(1 2 3))
|
|
|
|
|
⇒ ((0 . 1) (0 . 2) (0 . 3))
|
|
|
|
|
(-zip-fill 0 '(1 2) '(3 4) '(5 6))
|
|
|
|
|
⇒ ((1 3 5) (2 4 6))
|
|
|
|
|
|
|
|
|
|
-- Function: -unzip-lists (lists)
|
|
|
|
|
Unzip LISTS.
|
|
|
|
|
|
|
|
|
|
This works just like ‘-zip-lists’ (*note -zip-lists::) (which see),
|
|
|
|
|
but takes a list of lists instead of a variable number of
|
|
|
|
|
arguments, such that
|
|
|
|
|
|
|
|
|
|
(-unzip-lists (-zip-lists ARGS...))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
is identity (given that the lists comprising ARGS are of the same
|
|
|
|
|
length).
|
|
|
|
|
|
|
|
|
|
(-unzip-lists (-zip-lists '(1 2) '(3 4) '(5 6)))
|
|
|
|
|
⇒ ((1 2) (3 4) (5 6))
|
|
|
|
|
(-unzip-lists '((1 2 3) (4 5) (6 7) (8 9)))
|
|
|
|
|
⇒ ((1 4 6 8) (2 5 7 9))
|
|
|
|
|
(-unzip-lists '((1 2 3) (4 5 6)))
|
|
|
|
|
⇒ ((1 4) (2 5) (3 6))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -unzip (lists)
|
|
|
|
|
Unzip LISTS.
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
This works just like ‘-zip’ (*note -zip::) (which see), but takes a
|
|
|
|
|
list of lists instead of a variable number of arguments, such that
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-unzip (-zip L1 L2 L3 ...))
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
is identity (given that the lists are of the same length, and that
|
|
|
|
|
‘-zip’ (*note -zip::) is not called with two arguments, because of
|
|
|
|
|
the caveat described in its docstring).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Note in particular that calling ‘-unzip’ (*note -unzip::) on a list
|
|
|
|
|
of two lists will return a list of dotted pairs.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
Since the return value changes form depending on the number of
|
|
|
|
|
LISTS, it is generally recommended to use ‘-unzip-lists’ (*note
|
|
|
|
|
-unzip-lists::) instead.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-unzip (-zip '(1 2) '(3 4) '(5 6)))
|
|
|
|
|
⇒ ((1 . 2) (3 . 4) (5 . 6))
|
|
|
|
|
(-unzip '((1 2 3) (4 5 6)))
|
|
|
|
|
⇒ ((1 . 4) (2 . 5) (3 . 6))
|
|
|
|
|
(-unzip '((1 2 3) (4 5) (6 7) (8 9)))
|
|
|
|
|
⇒ ((1 4 6 8) (2 5 7 9))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -pad (fill-value &rest lists)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Pad each of LISTS with FILL-VALUE until they all have equal
|
|
|
|
|
lengths.
|
|
|
|
|
|
|
|
|
|
Ensure all LISTS are as long as the longest one by repeatedly
|
|
|
|
|
appending FILL-VALUE to the shorter lists, and return the resulting
|
|
|
|
|
LISTS.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
(-pad 0 ())
|
|
|
|
|
⇒ (nil)
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-pad 0 '(1 2) '(3 4))
|
|
|
|
|
⇒ ((1 2) (3 4))
|
|
|
|
|
(-pad 0 '(1 2) '(3 4 5 6) '(7 8 9))
|
|
|
|
|
⇒ ((1 2 0 0) (3 4 5 6) (7 8 9 0))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- 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 item in LIST for which PRED returns non-‘nil’.
|
2022-08-04 18:39:38 +00:00
|
|
|
|
Return ‘nil’ if no such element is found.
|
|
|
|
|
|
|
|
|
|
To get the first item in the list no questions asked, use
|
|
|
|
|
‘-first-item’ (*note -first-item::).
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
Alias: ‘-find’.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--first’.
|
|
|
|
|
|
|
|
|
|
(-first #'natnump '(-1 0 1))
|
|
|
|
|
⇒ 0
|
|
|
|
|
(-first #'null '(1 2 3))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(--first (> it 2) '(1 2 3))
|
|
|
|
|
⇒ 3
|
|
|
|
|
|
|
|
|
|
-- 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’
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(*note -last-item::), etc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-first-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-first-item '(1 2 3 4 5))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 1
|
|
|
|
|
(let ((list (list 1 2 3))) (setf (-first-item list) 5) list)
|
|
|
|
|
⇒ (5 2 3)
|
|
|
|
|
|
|
|
|
|
-- Function: -second-item (list)
|
|
|
|
|
Return the second item of LIST, or ‘nil’ if LIST is too short.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-first-item’ (*note -first-item::), ‘-third-item’ (*note
|
|
|
|
|
-third-item::), etc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-second-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-second-item '(1 2 3 4 5))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 2
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(let ((list (list 1 2))) (setf (-second-item list) 5) list)
|
|
|
|
|
⇒ (1 5)
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
-- Function: -third-item (list)
|
|
|
|
|
Return the third item of LIST, or ‘nil’ if LIST is too short.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-second-item’ (*note -second-item::), ‘-fourth-item’
|
|
|
|
|
(*note -fourth-item::), etc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-third-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-third-item '(1 2))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-third-item '(1 2 3 4 5))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 3
|
|
|
|
|
|
|
|
|
|
-- Function: -fourth-item (list)
|
|
|
|
|
Return the fourth item of LIST, or ‘nil’ if LIST is too short.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-third-item’ (*note -third-item::), ‘-fifth-item’ (*note
|
|
|
|
|
-fifth-item::), etc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-fourth-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-fourth-item '(1 2 3))
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-fourth-item '(1 2 3 4 5))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ 4
|
|
|
|
|
|
|
|
|
|
-- Function: -fifth-item (list)
|
|
|
|
|
Return the fifth item of LIST, or ‘nil’ if LIST is too short.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-fourth-item’ (*note -fourth-item::), ‘-last-item’
|
|
|
|
|
(*note -last-item::), etc.
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
(-fifth-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-fifth-item '(1 2 3 4))
|
|
|
|
|
⇒ ()
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(-fifth-item '(1 2 3 4 5))
|
|
|
|
|
⇒ 5
|
|
|
|
|
|
|
|
|
|
-- Function: -last-item (list)
|
|
|
|
|
Return the last item of LIST, or ‘nil’ on an empty list.
|
|
|
|
|
|
2022-08-04 18:39:38 +00:00
|
|
|
|
See also: ‘-first-item’ (*note -first-item::), etc.
|
|
|
|
|
|
|
|
|
|
(-last-item ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-last-item '(1 2 3 4 5))
|
|
|
|
|
⇒ 5
|
2022-04-22 02:54:47 +00:00
|
|
|
|
(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.
|
|
|
|
|
|
2023-07-27 19:42:55 +00:00
|
|
|
|
(-sort #'< '(3 1 2))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (1 2 3)
|
2023-07-27 19:42:55 +00:00
|
|
|
|
(-sort #'> '(3 1 2))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (3 2 1)
|
|
|
|
|
(--sort (< it other) '(3 1 2))
|
|
|
|
|
⇒ (1 2 3)
|
|
|
|
|
|
|
|
|
|
-- Function: -list (arg)
|
|
|
|
|
Ensure ARG is a list. If ARG is already a list, return it as is
|
|
|
|
|
(not a copy). Otherwise, return a new list with ARG as its only
|
|
|
|
|
element.
|
|
|
|
|
|
|
|
|
|
Another supported calling convention is (-list &rest ARGS). In
|
|
|
|
|
this case, if ARG is not a list, a new list with all of ARGS as
|
|
|
|
|
elements is returned. This use is supported for backward
|
|
|
|
|
compatibility and is otherwise deprecated.
|
|
|
|
|
|
|
|
|
|
(-list 1)
|
|
|
|
|
⇒ (1)
|
|
|
|
|
(-list ())
|
|
|
|
|
⇒ ()
|
|
|
|
|
(-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)))
|
|
|
|
|
⇒ ((1) (2) (3))
|
|
|
|
|
(let ((l '((starwars scifi) (jedi starwars warrior)))) (--fix (-uniq (--mapcat (cons it (cdr (assq it l))) 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) "}" '((elisp-mode (foo (bar . booze)) (baz . qux)) (c-mode (foo . bla) (bum . bam)))))
|
|
|
|
|
⇒ "{elisp-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.
|
|
|
|
|
|
2023-07-27 19:42:55 +00:00
|
|
|
|
(let* ((a (list (list 1))) (b (-clone a))) (setcar (car a) 2) b)
|
|
|
|
|
⇒ ((1))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Threading macros, Next: Binding, Prev: Tree operations, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.12 Threading macros
|
|
|
|
|
=====================
|
|
|
|
|
|
|
|
|
|
Macros that conditionally combine sequential forms for brevity or
|
|
|
|
|
readability.
|
|
|
|
|
|
|
|
|
|
-- 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--> (expr &rest forms)
|
|
|
|
|
Thread EXPR through FORMS via ‘-->’ (*note -->::), while the result
|
|
|
|
|
is non-‘nil’. When EXPR evaluates to non-‘nil’, thread the result
|
|
|
|
|
through the first of FORMS, and when that result is non-‘nil’,
|
|
|
|
|
thread it through the next form, etc.
|
|
|
|
|
|
|
|
|
|
(-some--> "def" (concat "abc" it "ghi"))
|
|
|
|
|
⇒ "abcdefghi"
|
|
|
|
|
(-some--> nil (concat "abc" it "ghi"))
|
|
|
|
|
⇒ nil
|
|
|
|
|
(-some--> '(0 1) (-remove #'natnump it) (append it it) (-map #'1+ it))
|
|
|
|
|
⇒ ()
|
|
|
|
|
|
|
|
|
|
-- Macro: -doto (init &rest forms)
|
|
|
|
|
Evaluate INIT and pass it as argument to FORMS with ‘->’ (*note
|
|
|
|
|
->::). The RESULT of evaluating INIT is threaded through each of
|
|
|
|
|
FORMS individually using ‘->’ (*note ->::), which see. The return
|
|
|
|
|
value is RESULT, which FORMS may have modified by side effect.
|
|
|
|
|
|
|
|
|
|
(-doto (list 1 2 3) pop pop)
|
|
|
|
|
⇒ (3)
|
|
|
|
|
(-doto (cons 1 2) (setcar 3) (setcdr 4))
|
|
|
|
|
⇒ (3 . 4)
|
|
|
|
|
(gethash 'k (--doto (make-hash-table) (puthash 'k 'v it)))
|
|
|
|
|
⇒ v
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Binding, Next: Side effects, Prev: Threading macros, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.13 Binding
|
|
|
|
|
============
|
|
|
|
|
|
|
|
|
|
Macros that combine ‘let’ and ‘let*’ with destructuring and 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::).
|
|
|
|
|
|
|
|
|
|
(-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::).
|
|
|
|
|
|
|
|
|
|
(-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 a description of the 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 ([match-form val] ...)
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
(let (a) (-setq a 1) a)
|
|
|
|
|
⇒ 1
|
|
|
|
|
(let (a b) (-setq (a b) (list 1 2)) (list a b))
|
|
|
|
|
⇒ (1 2)
|
|
|
|
|
(let (c) (-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 on each element of LIST. Return ‘nil’; this function is
|
|
|
|
|
intended for side effects.
|
|
|
|
|
|
|
|
|
|
Its anaphoric counterpart is ‘--each’.
|
|
|
|
|
|
|
|
|
|
For access to the current element’s index in LIST, see
|
|
|
|
|
‘-each-indexed’ (*note -each-indexed::).
|
|
|
|
|
|
|
|
|
|
(let (l) (-each '(1 2 3) (lambda (x) (push x l))) l)
|
|
|
|
|
⇒ (3 2 1)
|
|
|
|
|
(let (l) (--each '(1 2 3) (push it l)) l)
|
|
|
|
|
⇒ (3 2 1)
|
|
|
|
|
(-each '(1 2 3) #'identity)
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
|
|
|
|
-- Function: -each-while (list pred fn)
|
|
|
|
|
Call FN on each ITEM in LIST, while (PRED ITEM) is non-‘nil’. Once
|
|
|
|
|
an ITEM is reached for which PRED returns ‘nil’, FN is no longer
|
|
|
|
|
called. Return ‘nil’; this function is intended for side effects.
|
|
|
|
|
|
|
|
|
|
Its anaphoric counterpart is ‘--each-while’.
|
|
|
|
|
|
|
|
|
|
(let (l) (-each-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
|
|
|
|
|
⇒ (4 2)
|
|
|
|
|
(let (l) (--each-while '(1 2 3 4) (< it 3) (push it l)) l)
|
|
|
|
|
⇒ (2 1)
|
|
|
|
|
(let ((s 0)) (--each-while '(1 3 4 5) (< it 5) (setq s (+ s it))) s)
|
|
|
|
|
⇒ 8
|
|
|
|
|
|
|
|
|
|
-- Function: -each-indexed (list fn)
|
|
|
|
|
Call FN on each index and element of LIST. For each ITEM at INDEX
|
|
|
|
|
in LIST, call (funcall FN INDEX ITEM). Return ‘nil’; this function
|
|
|
|
|
is intended for side effects.
|
|
|
|
|
|
|
|
|
|
See also: ‘-map-indexed’ (*note -map-indexed::).
|
|
|
|
|
|
|
|
|
|
(let (l) (-each-indexed '(a b c) (lambda (i x) (push (list x i) l))) l)
|
|
|
|
|
⇒ ((c 2) (b 1) (a 0))
|
|
|
|
|
(let (l) (--each-indexed '(a b c) (push (list it it-index) l)) l)
|
|
|
|
|
⇒ ((c 2) (b 1) (a 0))
|
|
|
|
|
(let (l) (--each-indexed () (push it l)) l)
|
|
|
|
|
⇒ ()
|
|
|
|
|
|
|
|
|
|
-- Function: -each-r (list fn)
|
|
|
|
|
Call FN on each element of LIST in reversed order. Return ‘nil’;
|
|
|
|
|
this function is intended for side effects.
|
|
|
|
|
|
|
|
|
|
Its anaphoric counterpart is ‘--each-r’.
|
|
|
|
|
|
|
|
|
|
(let (l) (-each-r '(1 2 3) (lambda (x) (push x l))) l)
|
|
|
|
|
⇒ (1 2 3)
|
|
|
|
|
(let (l) (--each-r '(1 2 3) (push it l)) l)
|
|
|
|
|
⇒ (1 2 3)
|
|
|
|
|
(-each-r '(1 2 3) #'identity)
|
|
|
|
|
⇒ nil
|
|
|
|
|
|
|
|
|
|
-- Function: -each-r-while (list pred fn)
|
|
|
|
|
Call FN on each ITEM in reversed LIST, while (PRED ITEM) is
|
|
|
|
|
non-‘nil’. Once an ITEM is reached for which PRED returns ‘nil’,
|
|
|
|
|
FN is no longer called. Return ‘nil’; this function is intended
|
|
|
|
|
for side effects.
|
|
|
|
|
|
|
|
|
|
Its anaphoric counterpart is ‘--each-r-while’.
|
|
|
|
|
|
|
|
|
|
(let (l) (-each-r-while '(2 4 5 6) #'even? (lambda (x) (push x l))) l)
|
|
|
|
|
⇒ (6)
|
|
|
|
|
(let (l) (--each-r-while '(1 2 3 4) (>= it 3) (push it l)) l)
|
|
|
|
|
⇒ (3 4)
|
|
|
|
|
(let ((s 0)) (--each-r-while '(1 2 3 5) (> it 1) (setq s (+ s it))) s)
|
|
|
|
|
⇒ 10
|
|
|
|
|
|
|
|
|
|
-- Function: -dotimes (num fn)
|
|
|
|
|
Call FN NUM times, presumably for side effects. FN is called with
|
|
|
|
|
a single argument on successive integers running from 0, inclusive,
|
|
|
|
|
to NUM, exclusive. FN is not called if NUM is less than 1.
|
|
|
|
|
|
|
|
|
|
This function’s anaphoric counterpart is ‘--dotimes’.
|
|
|
|
|
|
|
|
|
|
(let (s) (-dotimes 3 (lambda (n) (push n s))) s)
|
|
|
|
|
⇒ (2 1 0)
|
|
|
|
|
(let (s) (-dotimes 0 (lambda (n) (push n s))) s)
|
|
|
|
|
⇒ ()
|
|
|
|
|
(let (s) (--dotimes 5 (push it s)) s)
|
|
|
|
|
⇒ (4 3 2 1 0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Destructive operations, Next: Function combinators, Prev: Side effects, Up: Functions
|
|
|
|
|
|
|
|
|
|
2.15 Destructive operations
|
|
|
|
|
===========================
|
|
|
|
|
|
|
|
|
|
Macros that modify variables holding lists.
|
|
|
|
|
|
|
|
|
|
-- 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
|
|
|
|
|
=========================
|
|
|
|
|
|
|
|
|
|
Functions that manipulate and compose other functions.
|
|
|
|
|
|
|
|
|
|
-- Function: -partial (fun &rest args)
|
|
|
|
|
Return a function that is a partial application of FUN to ARGS.
|
|
|
|
|
ARGS is a list of the first N arguments to pass to FUN. The result
|
|
|
|
|
is a new function which does the same as FUN, except that the first
|
|
|
|
|
N arguments are fixed at the values with which this function was
|
|
|
|
|
called.
|
|
|
|
|
|
|
|
|
|
(funcall (-partial #'+ 5))
|
|
|
|
|
⇒ 5
|
|
|
|
|
(funcall (-partial #'- 5) 3)
|
|
|
|
|
⇒ 2
|
|
|
|
|
(funcall (-partial #'+ 5 2) 3)
|
|
|
|
|
⇒ 10
|
|
|
|
|
|
|
|
|
|
-- Function: -rpartial (fn &rest args)
|
|
|
|
|
Return a function that is a partial application of FN to ARGS.
|
|
|
|
|
ARGS is a list of the last N arguments to pass to FN. The result
|
|
|
|
|
is a new function which does the same as FN, except that the last N
|
|
|
|
|
arguments are fixed at the values with which this function was
|
|
|
|
|
called. This is like ‘-partial’ (*note -partial::), except the
|
|
|
|
|
arguments are fixed starting from the right rather than the left.
|
|
|
|
|
|
|
|
|
|
(funcall (-rpartial #'- 5))
|
|
|
|
|
⇒ -5
|
|
|
|
|
(funcall (-rpartial #'- 5) 8)
|
|
|
|
|
⇒ 3
|
|
|
|
|
(funcall (-rpartial #'- 5 2) 10)
|
|
|
|
|
⇒ 3
|
|
|
|
|
|
|
|
|
|
-- Function: -juxt (&rest fns)
|
|
|
|
|
Return a function that is the juxtaposition of FNS. The returned
|
|
|
|
|
function takes a variable number of ARGS, applies each of FNS in
|
|
|
|
|
turn to ARGS, and returns the list of results.
|
|
|
|
|
|
|
|
|
|
(funcall (-juxt) 1 2)
|
|
|
|
|
⇒ ()
|
|
|
|
|
(funcall (-juxt #'+ #'- #'* #'/) 7 5)
|
|
|
|
|
⇒ (12 2 35 1)
|
|
|
|
|
(mapcar (-juxt #'number-to-string #'1+) '(1 2))
|
|
|
|
|
⇒ (("1" 2) ("2" 3))
|
|
|
|
|
|
|
|
|
|
-- Function: -compose (&rest fns)
|
|
|
|
|
Compose FNS into a single composite function. Return a function
|
|
|
|
|
that takes a variable number of ARGS, applies the last function in
|
|
|
|
|
FNS to ARGS, and returns the result of calling each remaining
|
|
|
|
|
function on the result of the previous function, right-to-left. If
|
|
|
|
|
no FNS are given, return a variadic ‘identity’ function.
|
|
|
|
|
|
|
|
|
|
(funcall (-compose #'- #'1+ #'+) 1 2 3)
|
|
|
|
|
⇒ -7
|
|
|
|
|
(funcall (-compose #'identity #'1+) 3)
|
|
|
|
|
⇒ 4
|
|
|
|
|
(mapcar (-compose #'not #'stringp) '(nil ""))
|
|
|
|
|
⇒ (t nil)
|
|
|
|
|
|
|
|
|
|
-- Function: -applify (fn)
|
|
|
|
|
Return a function that applies FN to a single list of args. This
|
|
|
|
|
changes the arity of FN from taking N distinct arguments to taking
|
|
|
|
|
1 argument which is a list of N arguments.
|
|
|
|
|
|
|
|
|
|
(funcall (-applify #'+) nil)
|
|
|
|
|
⇒ 0
|
|
|
|
|
(mapcar (-applify #'+) '((1 1 1) (1 2 3) (5 5 5)))
|
|
|
|
|
⇒ (3 6 15)
|
|
|
|
|
(funcall (-applify #'<) '(3 6))
|
|
|
|
|
⇒ t
|
|
|
|
|
|
|
|
|
|
-- Function: -on (op trans)
|
|
|
|
|
Return a function that calls TRANS on each arg and OP on the
|
|
|
|
|
results. The returned function takes a variable number of
|
|
|
|
|
arguments, calls the function TRANS on each one in turn, and then
|
|
|
|
|
passes those results as the list of arguments to OP, in the same
|
|
|
|
|
order.
|
|
|
|
|
|
|
|
|
|
For example, the following pairs of expressions are morally
|
|
|
|
|
equivalent:
|
|
|
|
|
|
|
|
|
|
(funcall (-on #’+ #’1+) 1 2 3) = (+ (1+ 1) (1+ 2) (1+ 3)) (funcall
|
|
|
|
|
(-on #’+ #’1+)) = (+)
|
|
|
|
|
|
|
|
|
|
(-sort (-on #'< #'length) '((1 2 3) (1) (1 2)))
|
|
|
|
|
⇒ ((1) (1 2) (1 2 3))
|
|
|
|
|
(funcall (-on #'min #'string-to-number) "22" "2" "1" "12")
|
|
|
|
|
⇒ 1
|
|
|
|
|
(-min-by (-on #'> #'length) '((1 2 3) (4) (1 2)))
|
|
|
|
|
⇒ (4)
|
|
|
|
|
|
|
|
|
|
-- Function: -flip (fn)
|
|
|
|
|
Return a function that calls FN with its arguments reversed. The
|
|
|
|
|
returned function takes the same number of arguments as FN.
|
|
|
|
|
|
|
|
|
|
For example, the following two expressions are morally equivalent:
|
|
|
|
|
|
|
|
|
|
(funcall (-flip #’-) 1 2) = (- 2 1)
|
|
|
|
|
|
|
|
|
|
See also: ‘-rotate-args’ (*note -rotate-args::).
|
|
|
|
|
|
|
|
|
|
(-sort (-flip #'<) '(4 3 6 1))
|
|
|
|
|
⇒ (6 4 3 1)
|
|
|
|
|
(funcall (-flip #'-) 3 2 1 10)
|
|
|
|
|
⇒ 4
|
|
|
|
|
(funcall (-flip #'1+) 1)
|
|
|
|
|
⇒ 2
|
|
|
|
|
|
|
|
|
|
-- Function: -rotate-args (n fn)
|
|
|
|
|
Return a function that calls FN with args rotated N places to the
|
|
|
|
|
right. The returned function takes the same number of arguments as
|
|
|
|
|
FN, rotates the list of arguments N places to the right (left if N
|
|
|
|
|
is negative) just like ‘-rotate’ (*note -rotate::), and applies FN
|
|
|
|
|
to the result.
|
|
|
|
|
|
|
|
|
|
See also: ‘-flip’ (*note -flip::).
|
|
|
|
|
|
|
|
|
|
(funcall (-rotate-args -1 #'list) 1 2 3 4)
|
|
|
|
|
⇒ (2 3 4 1)
|
|
|
|
|
(funcall (-rotate-args 1 #'-) 1 10 100)
|
|
|
|
|
⇒ 89
|
|
|
|
|
(funcall (-rotate-args 2 #'list) 3 4 5 1 2)
|
|
|
|
|
⇒ (1 2 3 4 5)
|
|
|
|
|
|
|
|
|
|
-- 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
|
|
|
|
|
(mapcar (-const 1) '("a" "b" "c" "d"))
|
|
|
|
|
⇒ (1 1 1 1)
|
|
|
|
|
(-sum (mapcar (-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 vector string))
|
|
|
|
|
⇒ ((1 2 3) [1 2 3] "\1\2\3")
|
|
|
|
|
|
|
|
|
|
-- Function: -not (pred)
|
|
|
|
|
Return a predicate that negates the result of PRED. The returned
|
|
|
|
|
predicate passes its arguments to PRED. If PRED returns ‘nil’, the
|
|
|
|
|
result is non-‘nil’; otherwise the result is ‘nil’.
|
|
|
|
|
|
|
|
|
|
See also: ‘-andfn’ (*note -andfn::) and ‘-orfn’ (*note -orfn::).
|
|
|
|
|
|
|
|
|
|
(funcall (-not #'numberp) "5")
|
|
|
|
|
⇒ t
|
|
|
|
|
(-sort (-not #'<) '(5 2 1 0 6))
|
|
|
|
|
⇒ (6 5 2 1 0)
|
|
|
|
|
(-filter (-not (-partial #'< 4)) '(1 2 3 4 5 6 7 8))
|
|
|
|
|
⇒ (1 2 3 4)
|
|
|
|
|
|
|
|
|
|
-- Function: -orfn (&rest preds)
|
|
|
|
|
Return a predicate that returns the first non-‘nil’ result of
|
|
|
|
|
PREDS. The returned predicate takes a variable number of
|
|
|
|
|
arguments, passes them to each predicate in PREDS in turn until one
|
|
|
|
|
of them returns non-‘nil’, and returns that non-‘nil’ result
|
|
|
|
|
without calling the remaining PREDS. If all PREDS return ‘nil’, or
|
|
|
|
|
if no PREDS are given, the returned predicate returns ‘nil’.
|
|
|
|
|
|
|
|
|
|
See also: ‘-andfn’ (*note -andfn::) and ‘-not’ (*note -not::).
|
|
|
|
|
|
|
|
|
|
(-filter (-orfn #'natnump #'booleanp) '(1 nil "a" -4 b c t))
|
|
|
|
|
⇒ (1 nil t)
|
|
|
|
|
(funcall (-orfn #'symbolp (-cut string-match-p "x" <>)) "axe")
|
|
|
|
|
⇒ 1
|
|
|
|
|
(funcall (-orfn #'= #'+) 1 1)
|
|
|
|
|
⇒ t
|
|
|
|
|
|
|
|
|
|
-- Function: -andfn (&rest preds)
|
|
|
|
|
Return a predicate that returns non-‘nil’ if all PREDS do so. The
|
|
|
|
|
returned predicate P takes a variable number of arguments and
|
|
|
|
|
passes them to each predicate in PREDS in turn. If any one of
|
|
|
|
|
PREDS returns ‘nil’, P also returns ‘nil’ without calling the
|
|
|
|
|
remaining PREDS. If all PREDS return non-‘nil’, P returns the last
|
|
|
|
|
such value. If no PREDS are given, P always returns non-‘nil’.
|
|
|
|
|
|
|
|
|
|
See also: ‘-orfn’ (*note -orfn::) and ‘-not’ (*note -not::).
|
|
|
|
|
|
|
|
|
|
(-filter (-andfn #'numberp (-cut < <> 5)) '(a 1 b 6 c 2))
|
|
|
|
|
⇒ (1 2)
|
|
|
|
|
(mapcar (-andfn #'numberp #'1+) '(a 1 b 6))
|
|
|
|
|
⇒ (nil 2 nil 7)
|
|
|
|
|
(funcall (-andfn #'= #'+) 1 1)
|
|
|
|
|
⇒ 2
|
|
|
|
|
|
|
|
|
|
-- 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=) 0.7)
|
|
|
|
|
⇒ 0.7390851332151607
|
|
|
|
|
(funcall (-fixfn (lambda (x) (expt (+ x 10) 0.25))) 2.0)
|
|
|
|
|
⇒ 1.8555845286409378
|
|
|
|
|
(funcall (-fixfn #'sin #'approx=) 0.1)
|
|
|
|
|
⇒ (halted . t)
|
|
|
|
|
|
|
|
|
|
-- Function: -prodfn (&rest fns)
|
|
|
|
|
Return a function that applies each of FNS to each of a list of
|
|
|
|
|
arguments.
|
|
|
|
|
|
|
|
|
|
Takes a list of N functions and returns a function that takes a
|
|
|
|
|
list of length N, applying Ith function to Ith 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))
|
|
|
|
|
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(funcall (-prodfn #'1+ #'1- #'number-to-string) '(1 2 3))
|
2022-04-22 02:54:47 +00:00
|
|
|
|
⇒ (2 1 "3")
|
2023-03-22 11:44:34 +00:00
|
|
|
|
(-map (-prodfn #'1- #'1+) '((1 2) (3 4) (5 6)))
|
|
|
|
|
⇒ ((0 3) (2 5) (4 7))
|
|
|
|
|
(apply #'+ (funcall (-prodfn #'length #'string-to-number) '((t) "5")))
|
|
|
|
|
⇒ 6
|
2022-04-22 02:54:47 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Development, Next: FDL, Prev: Functions, Up: Top
|
|
|
|
|
|
|
|
|
|
3 Development
|
|
|
|
|
*************
|
|
|
|
|
|
|
|
|
|
The Dash repository is hosted on GitHub at
|
|
|
|
|
<https://github.com/magnars/dash.el>.
|
|
|
|
|
|
|
|
|
|
* Menu:
|
|
|
|
|
|
|
|
|
|
* Contribute:: How to contribute.
|
|
|
|
|
* Contributors:: List of contributors.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Contribute, Next: Contributors, Up: Development
|
|
|
|
|
|
|
|
|
|
3.1 Contribute
|
|
|
|
|
==============
|
|
|
|
|
|
|
|
|
|
Yes, please do. Pure functions in the list manipulation realm only,
|
|
|
|
|
please. There’s a suite of examples/tests in ‘dev/examples.el’, so
|
|
|
|
|
remember to add tests for your additions, or they may get broken later.
|
|
|
|
|
|
|
|
|
|
Run the tests with ‘make check’. Regenerate the docs with ‘make
|
|
|
|
|
docs’. Contributors are encouraged to install these commands as a Git
|
|
|
|
|
pre-commit hook, so that the tests are always running and the docs are
|
|
|
|
|
always in sync:
|
|
|
|
|
|
|
|
|
|
$ cp dev/pre-commit.sh .git/hooks/pre-commit
|
|
|
|
|
|
|
|
|
|
Oh, and don’t edit ‘README.md’ or ‘dash.texi’ directly, as they are
|
|
|
|
|
auto-generated. Instead, change their respective templates
|
|
|
|
|
‘readme-template.md’ or ‘dash-template.texi’.
|
|
|
|
|
|
|
|
|
|
To ensure that Dash can be distributed with GNU ELPA or Emacs, we
|
|
|
|
|
require that all contributors assign copyright to the Free Software
|
|
|
|
|
Foundation. For more on this, *note (emacs)Copyright Assignment::.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Contributors, Prev: Contribute, Up: Development
|
|
|
|
|
|
|
|
|
|
3.2 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 a variadic version of ‘-zip’.
|
|
|
|
|
• Fredrik Bergroth (https://github.com/fbergroth) made the ‘-if-let’
|
|
|
|
|
family use ‘-let’ destructuring and improved the script for
|
|
|
|
|
generating documentation.
|
|
|
|
|
• Mark Oteiza (https://github.com/holomorph) contributed ‘-iota’ and
|
|
|
|
|
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.
|
|
|
|
|
• Cam Saul (https://github.com/camsaul) contributed ‘-some->’,
|
|
|
|
|
‘-some->>’, and ‘-some-->’.
|
|
|
|
|
• Basil L. Contovounesios (https://github.com/basil-conto)
|
|
|
|
|
contributed ‘-common-prefix’, ‘-common-suffix’, and various other
|
|
|
|
|
improvements.
|
|
|
|
|
• Paul Pogonyshev (https://github.com/doublep) contributed ‘-each-r’
|
|
|
|
|
and ‘-each-r-while’.
|
|
|
|
|
|
|
|
|
|
Thanks!
|
|
|
|
|
|
|
|
|
|
New contributors are very welcome. *Note Contribute::.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: FDL, Next: GPL, Prev: Development, Up: Top
|
|
|
|
|
|
|
|
|
|
Appendix A GNU Free Documentation License
|
|
|
|
|
*****************************************
|
|
|
|
|
|
|
|
|
|
Version 1.3, 3 November 2008
|
|
|
|
|
|
|
|
|
|
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
|
|
|
|
|
<https://fsf.org/>
|
|
|
|
|
|
|
|
|
|
Everyone is permitted to copy and distribute verbatim copies
|
|
|
|
|
of this license document, but changing it is not allowed.
|
|
|
|
|
|
|
|
|
|
0. PREAMBLE
|
|
|
|
|
|
|
|
|
|
The purpose of this License is to make a manual, textbook, or other
|
|
|
|
|
functional and useful document “free” in the sense of freedom: to
|
|
|
|
|
assure everyone the effective freedom to copy and redistribute it,
|
|
|
|
|
with or without modifying it, either commercially or
|
|
|
|
|
noncommercially. Secondarily, this License preserves for the
|
|
|
|
|
author and publisher a way to get credit for their work, while not
|
|
|
|
|
being considered responsible for modifications made by others.
|
|
|
|
|
|
|
|
|
|
This License is a kind of “copyleft”, which means that derivative
|
|
|
|
|
works of the document must themselves be free in the same sense.
|
|
|
|
|
It complements the GNU General Public License, which is a copyleft
|
|
|
|
|
license designed for free software.
|
|
|
|
|
|
|
|
|
|
We have designed this License in order to use it for manuals for
|
|
|
|
|
free software, because free software needs free documentation: a
|
|
|
|
|
free program should come with manuals providing the same freedoms
|
|
|
|
|
that the software does. But this License is not limited to
|
|
|
|
|
software manuals; it can be used for any textual work, regardless
|
|
|
|
|
of subject matter or whether it is published as a printed book. We
|
|
|
|
|
recommend this License principally for works whose purpose is
|
|
|
|
|
instruction or reference.
|
|
|
|
|
|
|
|
|
|
1. APPLICABILITY AND DEFINITIONS
|
|
|
|
|
|
|
|
|
|
This License applies to any manual or other work, in any medium,
|
|
|
|
|
that contains a notice placed by the copyright holder saying it can
|
|
|
|
|
be distributed under the terms of this License. Such a notice
|
|
|
|
|
grants a world-wide, royalty-free license, unlimited in duration,
|
|
|
|
|
to use that work under the conditions stated herein. The
|
|
|
|
|
“Document”, below, refers to any such manual or work. Any member
|
|
|
|
|
of the public is a licensee, and is addressed as “you”. You accept
|
|
|
|
|
the license if you copy, modify or distribute the work in a way
|
|
|
|
|
requiring permission under copyright law.
|
|
|
|
|
|
|
|
|
|
A “Modified Version” of the Document means any work containing the
|
|
|
|
|
Document or a portion of it, either copied verbatim, or with
|
|
|
|
|
modifications and/or translated into another language.
|
|
|
|
|
|
|
|
|
|
A “Secondary Section” is a named appendix or a front-matter section
|
|
|
|
|
of the Document that deals exclusively with the relationship of the
|
|
|
|
|
publishers or authors of the Document to the Document’s overall
|
|
|
|
|
subject (or to related matters) and contains nothing that could
|
|
|
|
|
fall directly within that overall subject. (Thus, if the Document
|
|
|
|
|
is in part a textbook of mathematics, a Secondary Section may not
|
|
|
|
|
explain any mathematics.) The relationship could be a matter of
|
|
|
|
|
historical connection with the subject or with related matters, or
|
|
|
|
|
of legal, commercial, philosophical, ethical or political position
|
|
|
|
|
regarding them.
|
|
|
|
|
|
|
|
|
|
The “Invariant Sections” are certain Secondary Sections whose
|
|
|
|
|
titles are designated, as being those of Invariant Sections, in the
|
|
|
|
|
notice that says that the Document is released under this License.
|
|
|
|
|
If a section does not fit the above definition of Secondary then it
|
|
|
|
|
is not allowed to be designated as Invariant. The Document may
|
|
|
|
|
contain zero Invariant Sections. If the Document does not identify
|
|
|
|
|
any Invariant Sections then there are none.
|
|
|
|
|
|
|
|
|
|
The “Cover Texts” are certain short passages of text that are
|
|
|
|
|
listed, as Front-Cover Texts or Back-Cover Texts, in the notice
|
|
|
|
|
that says that the Document is released under this License. A
|
|
|
|
|
Front-Cover Text may be at most 5 words, and a Back-Cover Text may
|
|
|
|
|
be at most 25 words.
|
|
|
|
|
|
|
|
|
|
A “Transparent” copy of the Document means a machine-readable copy,
|
|
|
|
|
represented in a format whose specification is available to the
|
|
|
|
|
general public, that is suitable for revising the document
|
|
|
|
|
straightforwardly with generic text editors or (for images composed
|
|
|
|
|
of pixels) generic paint programs or (for drawings) some widely
|
|
|
|
|
available drawing editor, and that is suitable for input to text
|
|
|
|
|
formatters or for automatic translation to a variety of formats
|
|
|
|
|
suitable for input to text formatters. A copy made in an otherwise
|
|
|
|
|
Transparent file format whose markup, or absence of markup, has
|
|
|
|
|
been arranged to thwart or discourage subsequent modification by
|
|
|
|
|
readers is not Transparent. An image format is not Transparent if
|
|
|
|
|
used for any substantial amount of text. A copy that is not
|
|
|
|
|
“Transparent” is called “Opaque”.
|
|
|
|
|
|
|
|
|
|
Examples of suitable formats for Transparent copies include plain
|
|
|
|
|
ASCII without markup, Texinfo input format, LaTeX input format,
|
|
|
|
|
SGML or XML using a publicly available DTD, and standard-conforming
|
|
|
|
|
simple HTML, PostScript or PDF designed for human modification.
|
|
|
|
|
Examples of transparent image formats include PNG, XCF and JPG.
|
|
|
|
|
Opaque formats include proprietary formats that can be read and
|
|
|
|
|
edited only by proprietary word processors, SGML or XML for which
|
|
|
|
|
the DTD and/or processing tools are not generally available, and
|
|
|
|
|
the machine-generated HTML, PostScript or PDF produced by some word
|
|
|
|
|
processors for output purposes only.
|
|
|
|
|
|
|
|
|
|
The “Title Page” means, for a printed book, the title page itself,
|
|
|
|
|
plus such following pages as are needed to hold, legibly, the
|
|
|
|
|
material this License requires to appear in the title page. For
|
|
|
|
|
works in formats which do not have any title page as such, “Title
|
|
|
|
|
Page” means the text near the most prominent appearance of the
|
|
|
|
|
work’s title, preceding the beginning of the body of the text.
|
|
|
|
|
|
|
|
|
|
The “publisher” means any person or entity that distributes copies
|
|
|
|
|
of the Document to the public.
|
|
|
|
|
|
|
|
|
|
A section “Entitled XYZ” means a named subunit of the Document
|
|
|
|
|
whose title either is precisely XYZ or contains XYZ in parentheses
|
|
|
|
|
following text that translates XYZ in another language. (Here XYZ
|
|
|
|
|
stands for a specific section name mentioned below, such as
|
|
|
|
|
“Acknowledgements”, “Dedications”, “Endorsements”, or “History”.)
|
|
|
|
|
To “Preserve the Title” of such a section when you modify the
|
|
|
|
|
Document means that it remains a section “Entitled XYZ” according
|
|
|
|
|
to this definition.
|
|
|
|
|
|
|
|
|
|
The Document may include Warranty Disclaimers next to the notice
|
|
|
|
|
which states that this License applies to the Document. These
|
|
|
|
|
Warranty Disclaimers are considered to be included by reference in
|
|
|
|
|
this License, but only as regards disclaiming warranties: any other
|
|
|
|
|
implication that these Warranty Disclaimers may have is void and
|
|
|
|
|
has no effect on the meaning of this License.
|
|
|
|
|
|
|
|
|
|
2. VERBATIM COPYING
|
|
|
|
|
|
|
|
|
|
You may copy and distribute the Document in any medium, either
|
|
|
|
|
commercially or noncommercially, provided that this License, the
|
|
|
|
|
copyright notices, and the license notice saying this License
|
|
|
|
|
applies to the Document are reproduced in all copies, and that you
|
|
|
|
|
add no other conditions whatsoever to those of this License. You
|
|
|
|
|
may not use technical measures to obstruct or control the reading
|
|
|
|
|
or further copying of the copies you make or distribute. However,
|
|
|
|
|
you may accept compensation in exchange for copies. If you
|
|
|
|
|
distribute a large enough number of copies you must also follow the
|
|
|
|
|
conditions in section 3.
|
|
|
|
|
|
|
|
|
|
You may also lend copies, under the same conditions stated above,
|
|
|
|
|
and you may publicly display copies.
|
|
|
|
|
|
|
|
|
|
3. COPYING IN QUANTITY
|
|
|
|
|
|
|
|
|
|
If you publish printed copies (or copies in media that commonly
|
|
|
|
|
have printed covers) of the Document, numbering more than 100, and
|
|
|
|
|
the Document’s license notice requires Cover Texts, you must
|
|
|
|
|
enclose the copies in covers that carry, clearly and legibly, all
|
|
|
|
|
these Cover Texts: Front-Cover Texts on the front cover, and
|
|
|
|
|
Back-Cover Texts on the back cover. Both covers must also clearly
|
|
|
|
|
and legibly identify you as the publisher of these copies. The
|
|
|
|
|
front cover must present the full title with all words of the title
|
|
|
|
|
equally prominent and visible. You may add other material on the
|
|
|
|
|
covers in addition. Copying with changes limited to the covers, as
|
|
|
|
|
long as they preserve the title of the Document and satisfy these
|
|
|
|
|
conditions, can be treated as verbatim copying in other respects.
|
|
|
|
|
|
|
|
|
|
If the required texts for either cover are too voluminous to fit
|
|
|
|
|
legibly, you should put the first ones listed (as many as fit
|
|
|
|
|
reasonably) on the actual cover, and continue the rest onto
|
|
|
|
|
adjacent pages.
|
|
|
|
|
|
|
|
|
|
If you publish or distribute Opaque copies of the Document
|
|
|
|
|
numbering more than 100, you must either include a machine-readable
|
|
|
|
|
Transparent copy along with each Opaque copy, or state in or with
|
|
|
|
|
each Opaque copy a computer-network location from which the general
|
|
|
|
|
network-using public has access to download using public-standard
|
|
|
|
|
network protocols a complete Transparent copy of the Document, free
|
|
|
|
|
of added material. If you use the latter option, you must take
|
|
|
|
|
reasonably prudent steps, when you begin distribution of Opaque
|
|
|
|
|
copies in quantity, to ensure that this Transparent copy will
|
|
|
|
|
remain thus accessible at the stated location until at least one
|
|
|
|
|
year after the last time you distribute an Opaque copy (directly or
|
|
|
|
|
through your agents or retailers) of that edition to the public.
|
|
|
|
|
|
|
|
|
|
It is requested, but not required, that you contact the authors of
|
|
|
|
|
the Document well before redistributing any large number of copies,
|
|
|
|
|
to give them a chance to provide you with an updated version of the
|
|
|
|
|
Document.
|
|
|
|
|
|
|
|
|
|
4. MODIFICATIONS
|
|
|
|
|
|
|
|
|
|
You may copy and distribute a Modified Version of the Document
|
|
|
|
|
under the conditions of sections 2 and 3 above, provided that you
|
|
|
|
|
release the Modified Version under precisely this License, with the
|
|
|
|
|
Modified Version filling the role of the Document, thus licensing
|
|
|
|
|
distribution and modification of the Modified Version to whoever
|
|
|
|
|
possesses a copy of it. In addition, you must do these things in
|
|
|
|
|
the Modified Version:
|
|
|
|
|
|
|
|
|
|
A. Use in the Title Page (and on the covers, if any) a title
|
|
|
|
|
distinct from that of the Document, and from those of previous
|
|
|
|
|
versions (which should, if there were any, be listed in the
|
|
|
|
|
History section of the Document). You may use the same title
|
|
|
|
|
as a previous version if the original publisher of that
|
|
|
|
|
version gives permission.
|
|
|
|
|
|
|
|
|
|
B. List on the Title Page, as authors, one or more persons or
|
|
|
|
|
entities responsible for authorship of the modifications in
|
|
|
|
|
the Modified Version, together with at least five of the
|
|
|
|
|
principal authors of the Document (all of its principal
|
|
|
|
|
authors, if it has fewer than five), unless they release you
|
|
|
|
|
from this requirement.
|
|
|
|
|
|
|
|
|
|
C. State on the Title page the name of the publisher of the
|
|
|
|
|
Modified Version, as the publisher.
|
|
|
|
|
|
|
|
|
|
D. Preserve all the copyright notices of the Document.
|
|
|
|
|
|
|
|
|
|
E. Add an appropriate copyright notice for your modifications
|
|
|
|
|
adjacent to the other copyright notices.
|
|
|
|
|
|
|
|
|
|
F. Include, immediately after the copyright notices, a license
|
|
|
|
|
notice giving the public permission to use the Modified
|
|
|
|
|
Version under the terms of this License, in the form shown in
|
|
|
|
|
the Addendum below.
|
|
|
|
|
|
|
|
|
|
G. Preserve in that license notice the full lists of Invariant
|
|
|
|
|
Sections and required Cover Texts given in the Document’s
|
|
|
|
|
license notice.
|
|
|
|
|
|
|
|
|
|
H. Include an unaltered copy of this License.
|
|
|
|
|
|
|
|
|
|
I. Preserve the section Entitled “History”, Preserve its Title,
|
|
|
|
|
and add to it an item stating at least the title, year, new
|
|
|
|
|
authors, and publisher of the Modified Version as given on the
|
|
|
|
|
Title Page. If there is no section Entitled “History” in the
|
|
|
|
|
Document, create one stating the title, year, authors, and
|
|
|
|
|
publisher of the Document as given on its Title Page, then add
|
|
|
|
|
an item describing the Modified Version as stated in the
|
|
|
|
|
previous sentence.
|
|
|
|
|
|
|
|
|
|
J. Preserve the network location, if any, given in the Document
|
|
|
|
|
for public access to a Transparent copy of the Document, and
|
|
|
|
|
likewise the network locations given in the Document for
|
|
|
|
|
previous versions it was based on. These may be placed in the
|
|
|
|
|
“History” section. You may omit a network location for a work
|
|
|
|
|
that was published at least four years before the Document
|
|
|
|
|
itself, or if the original publisher of the version it refers
|
|
|
|
|
to gives permission.
|
|
|
|
|
|
|
|
|
|
K. For any section Entitled “Acknowledgements” or “Dedications”,
|
|
|
|
|
Preserve the Title of the section, and preserve in the section
|
|
|
|
|
all the substance and tone of each of the contributor
|
|
|
|
|
acknowledgements and/or dedications given therein.
|
|
|
|
|
|
|
|
|
|
L. Preserve all the Invariant Sections of the Document, unaltered
|
|
|
|
|
in their text and in their titles. Section numbers or the
|
|
|
|
|
equivalent are not considered part of the section titles.
|
|
|
|
|
|
|
|
|
|
M. Delete any section Entitled “Endorsements”. Such a section
|
|
|
|
|
may not be included in the Modified Version.
|
|
|
|
|
|
|
|
|
|
N. Do not retitle any existing section to be Entitled
|
|
|
|
|
“Endorsements” or to conflict in title with any Invariant
|
|
|
|
|
Section.
|
|
|
|
|
|
|
|
|
|
O. Preserve any Warranty Disclaimers.
|
|
|
|
|
|
|
|
|
|
If the Modified Version includes new front-matter sections or
|
|
|
|
|
appendices that qualify as Secondary Sections and contain no
|
|
|
|
|
material copied from the Document, you may at your option designate
|
|
|
|
|
some or all of these sections as invariant. To do this, add their
|
|
|
|
|
titles to the list of Invariant Sections in the Modified Version’s
|
|
|
|
|
license notice. These titles must be distinct from any other
|
|
|
|
|
section titles.
|
|
|
|
|
|
|
|
|
|
You may add a section Entitled “Endorsements”, provided it contains
|
|
|
|
|
nothing but endorsements of your Modified Version by various
|
|
|
|
|
parties—for example, statements of peer review or that the text has
|
|
|
|
|
been approved by an organization as the authoritative definition of
|
|
|
|
|
a standard.
|
|
|
|
|
|
|
|
|
|
You may add a passage of up to five words as a Front-Cover Text,
|
|
|
|
|
and a passage of up to 25 words as a Back-Cover Text, to the end of
|
|
|
|
|
the list of Cover Texts in the Modified Version. Only one passage
|
|
|
|
|
of Front-Cover Text and one of Back-Cover Text may be added by (or
|
|
|
|
|
through arrangements made by) any one entity. If the Document
|
|
|
|
|
already includes a cover text for the same cover, previously added
|
|
|
|
|
by you or by arrangement made by the same entity you are acting on
|
|
|
|
|
behalf of, you may not add another; but you may replace the old
|
|
|
|
|
one, on explicit permission from the previous publisher that added
|
|
|
|
|
the old one.
|
|
|
|
|
|
|
|
|
|
The author(s) and publisher(s) of the Document do not by this
|
|
|
|
|
License give permission to use their names for publicity for or to
|
|
|
|
|
assert or imply endorsement of any Modified Version.
|
|
|
|
|
|
|
|
|
|
5. COMBINING DOCUMENTS
|
|
|
|
|
|
|
|
|
|
You may combine the Document with other documents released under
|
|
|
|
|
this License, under the terms defined in section 4 above for
|
|
|
|
|
modified versions, provided that you include in the combination all
|
|
|
|
|
of the Invariant Sections of all of the original documents,
|
|
|
|
|
unmodified, and list them all as Invariant Sections of your
|
|
|
|
|
combined work in its license notice, and that you preserve all
|
|
|
|
|
their Warranty Disclaimers.
|
|
|
|
|
|
|
|
|
|
The combined work need only contain one copy of this License, and
|
|
|
|
|
multiple identical Invariant Sections may be replaced with a single
|
|
|
|
|
copy. If there are multiple Invariant Sections with the same name
|
|
|
|
|
but different contents, make the title of each such section unique
|
|
|
|
|
by adding at the end of it, in parentheses, the name of the
|
|
|
|
|
original author or publisher of that section if known, or else a
|
|
|
|
|
unique number. Make the same adjustment to the section titles in
|
|
|
|
|
the list of Invariant Sections in the license notice of the
|
|
|
|
|
combined work.
|
|
|
|
|
|
|
|
|
|
In the combination, you must combine any sections Entitled
|
|
|
|
|
“History” in the various original documents, forming one section
|
|
|
|
|
Entitled “History”; likewise combine any sections Entitled
|
|
|
|
|
“Acknowledgements”, and any sections Entitled “Dedications”. You
|
|
|
|
|
must delete all sections Entitled “Endorsements.”
|
|
|
|
|
|
|
|
|
|
6. COLLECTIONS OF DOCUMENTS
|
|
|
|
|
|
|
|
|
|
You may make a collection consisting of the Document and other
|
|
|
|
|
documents released under this License, and replace the individual
|
|
|
|
|
copies of this License in the various documents with a single copy
|
|
|
|
|
that is included in the collection, provided that you follow the
|
|
|
|
|
rules of this License for verbatim copying of each of the documents
|
|
|
|
|
in all other respects.
|
|
|
|
|
|
|
|
|
|
You may extract a single document from such a collection, and
|
|
|
|
|
distribute it individually under this License, provided you insert
|
|
|
|
|
a copy of this License into the extracted document, and follow this
|
|
|
|
|
License in all other respects regarding verbatim copying of that
|
|
|
|
|
document.
|
|
|
|
|
|
|
|
|
|
7. AGGREGATION WITH INDEPENDENT WORKS
|
|
|
|
|
|
|
|
|
|
A compilation of the Document or its derivatives with other
|
|
|
|
|
separate and independent documents or works, in or on a volume of a
|
|
|
|
|
storage or distribution medium, is called an “aggregate” if the
|
|
|
|
|
copyright resulting from the compilation is not used to limit the
|
|
|
|
|
legal rights of the compilation’s users beyond what the individual
|
|
|
|
|
works permit. When the Document is included in an aggregate, this
|
|
|
|
|
License does not apply to the other works in the aggregate which
|
|
|
|
|
are not themselves derivative works of the Document.
|
|
|
|
|
|
|
|
|
|
If the Cover Text requirement of section 3 is applicable to these
|
|
|
|
|
copies of the Document, then if the Document is less than one half
|
|
|
|
|
of the entire aggregate, the Document’s Cover Texts may be placed
|
|
|
|
|
on covers that bracket the Document within the aggregate, or the
|
|
|
|
|
electronic equivalent of covers if the Document is in electronic
|
|
|
|
|
form. Otherwise they must appear on printed covers that bracket
|
|
|
|
|
the whole aggregate.
|
|
|
|
|
|
|
|
|
|
8. TRANSLATION
|
|
|
|
|
|
|
|
|
|
Translation is considered a kind of modification, so you may
|
|
|
|
|
distribute translations of the Document under the terms of section
|
|
|
|
|
4. Replacing Invariant Sections with translations requires special
|
|
|
|
|
permission from their copyright holders, but you may include
|
|
|
|
|
translations of some or all Invariant Sections in addition to the
|
|
|
|
|
original versions of these Invariant Sections. You may include a
|
|
|
|
|
translation of this License, and all the license notices in the
|
|
|
|
|
Document, and any Warranty Disclaimers, provided that you also
|
|
|
|
|
include the original English version of this License and the
|
|
|
|
|
original versions of those notices and disclaimers. In case of a
|
|
|
|
|
disagreement between the translation and the original version of
|
|
|
|
|
this License or a notice or disclaimer, the original version will
|
|
|
|
|
prevail.
|
|
|
|
|
|
|
|
|
|
If a section in the Document is Entitled “Acknowledgements”,
|
|
|
|
|
“Dedications”, or “History”, the requirement (section 4) to
|
|
|
|
|
Preserve its Title (section 1) will typically require changing the
|
|
|
|
|
actual title.
|
|
|
|
|
|
|
|
|
|
9. TERMINATION
|
|
|
|
|
|
|
|
|
|
You may not copy, modify, sublicense, or distribute the Document
|
|
|
|
|
except as expressly provided under this License. Any attempt
|
|
|
|
|
otherwise to copy, modify, sublicense, or distribute it is void,
|
|
|
|
|
and will automatically terminate your rights under this License.
|
|
|
|
|
|
|
|
|
|
However, if you cease all violation of this License, then your
|
|
|
|
|
license from a particular copyright holder is reinstated (a)
|
|
|
|
|
provisionally, unless and until the copyright holder explicitly and
|
|
|
|
|
finally terminates your license, and (b) permanently, if the
|
|
|
|
|
copyright holder fails to notify you of the violation by some
|
|
|
|
|
reasonable means prior to 60 days after the cessation.
|
|
|
|
|
|
|
|
|
|
Moreover, your license from a particular copyright holder is
|
|
|
|
|
reinstated permanently if the copyright holder notifies you of the
|
|
|
|
|
violation by some reasonable means, this is the first time you have
|
|
|
|
|
received notice of violation of this License (for any work) from
|
|
|
|
|
that copyright holder, and you cure the violation prior to 30 days
|
|
|
|
|
after your receipt of the notice.
|
|
|
|
|
|
|
|
|
|
Termination of your rights under this section does not terminate
|
|
|
|
|
the licenses of parties who have received copies or rights from you
|
|
|
|
|
under this License. If your rights have been terminated and not
|
|
|
|
|
permanently reinstated, receipt of a copy of some or all of the
|
|
|
|
|
same material does not give you any rights to use it.
|
|
|
|
|
|
|
|
|
|
10. FUTURE REVISIONS OF THIS LICENSE
|
|
|
|
|
|
|
|
|
|
The Free Software Foundation may publish new, revised versions of
|
|
|
|
|
the GNU Free Documentation License from time to time. Such new
|
|
|
|
|
versions will be similar in spirit to the present version, but may
|
|
|
|
|
differ in detail to address new problems or concerns. See
|
|
|
|
|
<https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
Each version of the License is given a distinguishing version
|
|
|
|
|
number. If the Document specifies that a particular numbered
|
|
|
|
|
version of this License “or any later version” applies to it, you
|
|
|
|
|
have the option of following the terms and conditions either of
|
|
|
|
|
that specified version or of any later version that has been
|
|
|
|
|
published (not as a draft) by the Free Software Foundation. If the
|
|
|
|
|
Document does not specify a version number of this License, you may
|
|
|
|
|
choose any version ever published (not as a draft) by the Free
|
|
|
|
|
Software Foundation. If the Document specifies that a proxy can
|
|
|
|
|
decide which future versions of this License can be used, that
|
|
|
|
|
proxy’s public statement of acceptance of a version permanently
|
|
|
|
|
authorizes you to choose that version for the Document.
|
|
|
|
|
|
|
|
|
|
11. RELICENSING
|
|
|
|
|
|
|
|
|
|
“Massive Multiauthor Collaboration Site” (or “MMC Site”) means any
|
|
|
|
|
World Wide Web server that publishes copyrightable works and also
|
|
|
|
|
provides prominent facilities for anybody to edit those works. A
|
|
|
|
|
public wiki that anybody can edit is an example of such a server.
|
|
|
|
|
A “Massive Multiauthor Collaboration” (or “MMC”) contained in the
|
|
|
|
|
site means any set of copyrightable works thus published on the MMC
|
|
|
|
|
site.
|
|
|
|
|
|
|
|
|
|
“CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0
|
|
|
|
|
license published by Creative Commons Corporation, a not-for-profit
|
|
|
|
|
corporation with a principal place of business in San Francisco,
|
|
|
|
|
California, as well as future copyleft versions of that license
|
|
|
|
|
published by that same organization.
|
|
|
|
|
|
|
|
|
|
“Incorporate” means to publish or republish a Document, in whole or
|
|
|
|
|
in part, as part of another Document.
|
|
|
|
|
|
|
|
|
|
An MMC is “eligible for relicensing” if it is licensed under this
|
|
|
|
|
License, and if all works that were first published under this
|
|
|
|
|
License somewhere other than this MMC, and subsequently
|
|
|
|
|
incorporated in whole or in part into the MMC, (1) had no cover
|
|
|
|
|
texts or invariant sections, and (2) were thus incorporated prior
|
|
|
|
|
to November 1, 2008.
|
|
|
|
|
|
|
|
|
|
The operator of an MMC Site may republish an MMC contained in the
|
|
|
|
|
site under CC-BY-SA on the same site at any time before August 1,
|
|
|
|
|
2009, provided the MMC is eligible for relicensing.
|
|
|
|
|
|
|
|
|
|
ADDENDUM: How to use this License for your documents
|
|
|
|
|
====================================================
|
|
|
|
|
|
|
|
|
|
To use this License in a document you have written, include a copy of
|
|
|
|
|
the License in the document and put the following copyright and license
|
|
|
|
|
notices just after the title page:
|
|
|
|
|
|
|
|
|
|
Copyright (C) YEAR YOUR NAME.
|
|
|
|
|
Permission is granted to copy, distribute and/or modify this document
|
|
|
|
|
under the terms of the GNU Free Documentation License, Version 1.3
|
|
|
|
|
or any later version published by the Free Software Foundation;
|
|
|
|
|
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
|
|
|
|
|
Texts. A copy of the license is included in the section entitled ``GNU
|
|
|
|
|
Free Documentation License''.
|
|
|
|
|
|
|
|
|
|
If you have Invariant Sections, Front-Cover Texts and Back-Cover
|
|
|
|
|
Texts, replace the “with...Texts.” line with this:
|
|
|
|
|
|
|
|
|
|
with the Invariant Sections being LIST THEIR TITLES, with
|
|
|
|
|
the Front-Cover Texts being LIST, and with the Back-Cover Texts
|
|
|
|
|
being LIST.
|
|
|
|
|
|
|
|
|
|
If you have Invariant Sections without Cover Texts, or some other
|
|
|
|
|
combination of the three, merge those two alternatives to suit the
|
|
|
|
|
situation.
|
|
|
|
|
|
|
|
|
|
If your document contains nontrivial examples of program code, we
|
|
|
|
|
recommend releasing these examples in parallel under your choice of free
|
|
|
|
|
software license, such as the GNU General Public License, to permit
|
|
|
|
|
their use in free software.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: GPL, Next: Index, Prev: FDL, Up: Top
|
|
|
|
|
|
|
|
|
|
Appendix B GNU General Public License
|
|
|
|
|
*************************************
|
|
|
|
|
|
|
|
|
|
Version 3, 29 June 2007
|
|
|
|
|
|
|
|
|
|
Copyright © 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
|
|
|
|
|
|
|
|
Everyone is permitted to copy and distribute verbatim copies of this
|
|
|
|
|
license document, but changing it is not allowed.
|
|
|
|
|
|
|
|
|
|
Preamble
|
|
|
|
|
========
|
|
|
|
|
|
|
|
|
|
The GNU General Public License is a free, copyleft license for software
|
|
|
|
|
and other kinds of works.
|
|
|
|
|
|
|
|
|
|
The licenses for most software and other practical works are designed
|
|
|
|
|
to take away your freedom to share and change the works. By contrast,
|
|
|
|
|
the GNU General Public License is intended to guarantee your freedom to
|
|
|
|
|
share and change all versions of a program—to make sure it remains free
|
|
|
|
|
software for all its users. We, the Free Software Foundation, use the
|
|
|
|
|
GNU General Public License for most of our software; it applies also to
|
|
|
|
|
any other work released this way by its authors. You can apply it to
|
|
|
|
|
your programs, too.
|
|
|
|
|
|
|
|
|
|
When we speak of free software, we are referring to freedom, not
|
|
|
|
|
price. Our General Public Licenses are designed to make sure that you
|
|
|
|
|
have the freedom to distribute copies of free software (and charge for
|
|
|
|
|
them if you wish), that you receive source code or can get it if you
|
|
|
|
|
want it, that you can change the software or use pieces of it in new
|
|
|
|
|
free programs, and that you know you can do these things.
|
|
|
|
|
|
|
|
|
|
To protect your rights, we need to prevent others from denying you
|
|
|
|
|
these rights or asking you to surrender the rights. Therefore, you have
|
|
|
|
|
certain responsibilities if you distribute copies of the software, or if
|
|
|
|
|
you modify it: responsibilities to respect the freedom of others.
|
|
|
|
|
|
|
|
|
|
For example, if you distribute copies of such a program, whether
|
|
|
|
|
gratis or for a fee, you must pass on to the recipients the same
|
|
|
|
|
freedoms that you received. You must make sure that they, too, receive
|
|
|
|
|
or can get the source code. And you must show them these terms so they
|
|
|
|
|
know their rights.
|
|
|
|
|
|
|
|
|
|
Developers that use the GNU GPL protect your rights with two steps:
|
|
|
|
|
(1) assert copyright on the software, and (2) offer you this License
|
|
|
|
|
giving you legal permission to copy, distribute and/or modify it.
|
|
|
|
|
|
|
|
|
|
For the developers’ and authors’ protection, the GPL clearly explains
|
|
|
|
|
that there is no warranty for this free software. For both users’ and
|
|
|
|
|
authors’ sake, the GPL requires that modified versions be marked as
|
|
|
|
|
changed, so that their problems will not be attributed erroneously to
|
|
|
|
|
authors of previous versions.
|
|
|
|
|
|
|
|
|
|
Some devices are designed to deny users access to install or run
|
|
|
|
|
modified versions of the software inside them, although the manufacturer
|
|
|
|
|
can do so. This is fundamentally incompatible with the aim of
|
|
|
|
|
protecting users’ freedom to change the software. The systematic
|
|
|
|
|
pattern of such abuse occurs in the area of products for individuals to
|
|
|
|
|
use, which is precisely where it is most unacceptable. Therefore, we
|
|
|
|
|
have designed this version of the GPL to prohibit the practice for those
|
|
|
|
|
products. If such problems arise substantially in other domains, we
|
|
|
|
|
stand ready to extend this provision to those domains in future versions
|
|
|
|
|
of the GPL, as needed to protect the freedom of users.
|
|
|
|
|
|
|
|
|
|
Finally, every program is threatened constantly by software patents.
|
|
|
|
|
States should not allow patents to restrict development and use of
|
|
|
|
|
software on general-purpose computers, but in those that do, we wish to
|
|
|
|
|
avoid the special danger that patents applied to a free program could
|
|
|
|
|
make it effectively proprietary. To prevent this, the GPL assures that
|
|
|
|
|
patents cannot be used to render the program non-free.
|
|
|
|
|
|
|
|
|
|
The precise terms and conditions for copying, distribution and
|
|
|
|
|
modification follow.
|
|
|
|
|
|
|
|
|
|
TERMS AND CONDITIONS
|
|
|
|
|
====================
|
|
|
|
|
|
|
|
|
|
0. Definitions.
|
|
|
|
|
|
|
|
|
|
“This License” refers to version 3 of the GNU General Public
|
|
|
|
|
License.
|
|
|
|
|
|
|
|
|
|
“Copyright” also means copyright-like laws that apply to other
|
|
|
|
|
kinds of works, such as semiconductor masks.
|
|
|
|
|
|
|
|
|
|
“The Program” refers to any copyrightable work licensed under this
|
|
|
|
|
License. Each licensee is addressed as “you”. “Licensees” and
|
|
|
|
|
“recipients” may be individuals or organizations.
|
|
|
|
|
|
|
|
|
|
To “modify” a work means to copy from or adapt all or part of the
|
|
|
|
|
work in a fashion requiring copyright permission, other than the
|
|
|
|
|
making of an exact copy. The resulting work is called a “modified
|
|
|
|
|
version” of the earlier work or a work “based on” the earlier work.
|
|
|
|
|
|
|
|
|
|
A “covered work” means either the unmodified Program or a work
|
|
|
|
|
based on the Program.
|
|
|
|
|
|
|
|
|
|
To “propagate” a work means to do anything with it that, without
|
|
|
|
|
permission, would make you directly or secondarily liable for
|
|
|
|
|
infringement under applicable copyright law, except executing it on
|
|
|
|
|
a computer or modifying a private copy. Propagation includes
|
|
|
|
|
copying, distribution (with or without modification), making
|
|
|
|
|
available to the public, and in some countries other activities as
|
|
|
|
|
well.
|
|
|
|
|
|
|
|
|
|
To “convey” a work means any kind of propagation that enables other
|
|
|
|
|
parties to make or receive copies. Mere interaction with a user
|
|
|
|
|
through a computer network, with no transfer of a copy, is not
|
|
|
|
|
conveying.
|
|
|
|
|
|
|
|
|
|
An interactive user interface displays “Appropriate Legal Notices”
|
|
|
|
|
to the extent that it includes a convenient and prominently visible
|
|
|
|
|
feature that (1) displays an appropriate copyright notice, and (2)
|
|
|
|
|
tells the user that there is no warranty for the work (except to
|
|
|
|
|
the extent that warranties are provided), that licensees may convey
|
|
|
|
|
the work under this License, and how to view a copy of this
|
|
|
|
|
License. If the interface presents a list of user commands or
|
|
|
|
|
options, such as a menu, a prominent item in the list meets this
|
|
|
|
|
criterion.
|
|
|
|
|
|
|
|
|
|
1. Source Code.
|
|
|
|
|
|
|
|
|
|
The “source code” for a work means the preferred form of the work
|
|
|
|
|
for making modifications to it. “Object code” means any non-source
|
|
|
|
|
form of a work.
|
|
|
|
|
|
|
|
|
|
A “Standard Interface” means an interface that either is an
|
|
|
|
|
official standard defined by a recognized standards body, or, in
|
|
|
|
|
the case of interfaces specified for a particular programming
|
|
|
|
|
language, one that is widely used among developers working in that
|
|
|
|
|
language.
|
|
|
|
|
|
|
|
|
|
The “System Libraries” of an executable work include anything,
|
|
|
|
|
other than the work as a whole, that (a) is included in the normal
|
|
|
|
|
form of packaging a Major Component, but which is not part of that
|
|
|
|
|
Major Component, and (b) serves only to enable use of the work with
|
|
|
|
|
that Major Component, or to implement a Standard Interface for
|
|
|
|
|
which an implementation is available to the public in source code
|
|
|
|
|
form. A “Major Component”, in this context, means a major
|
|
|
|
|
essential component (kernel, window system, and so on) of the
|
|
|
|
|
specific operating system (if any) on which the executable work
|
|
|
|
|
runs, or a compiler used to produce the work, or an object code
|
|
|
|
|
interpreter used to run it.
|
|
|
|
|
|
|
|
|
|
The “Corresponding Source” for a work in object code form means all
|
|
|
|
|
the source code needed to generate, install, and (for an executable
|
|
|
|
|
work) run the object code and to modify the work, including scripts
|
|
|
|
|
to control those activities. However, it does not include the
|
|
|
|
|
work’s System Libraries, or general-purpose tools or generally
|
|
|
|
|
available free programs which are used unmodified in performing
|
|
|
|
|
those activities but which are not part of the work. For example,
|
|
|
|
|
Corresponding Source includes interface definition files associated
|
|
|
|
|
with source files for the work, and the source code for shared
|
|
|
|
|
libraries and dynamically linked subprograms that the work is
|
|
|
|
|
specifically designed to require, such as by intimate data
|
|
|
|
|
communication or control flow between those subprograms and other
|
|
|
|
|
parts of the work.
|
|
|
|
|
|
|
|
|
|
The Corresponding Source need not include anything that users can
|
|
|
|
|
regenerate automatically from other parts of the Corresponding
|
|
|
|
|
Source.
|
|
|
|
|
|
|
|
|
|
The Corresponding Source for a work in source code form is that
|
|
|
|
|
same work.
|
|
|
|
|
|
|
|
|
|
2. Basic Permissions.
|
|
|
|
|
|
|
|
|
|
All rights granted under this License are granted for the term of
|
|
|
|
|
copyright on the Program, and are irrevocable provided the stated
|
|
|
|
|
conditions are met. This License explicitly affirms your unlimited
|
|
|
|
|
permission to run the unmodified Program. The output from running
|
|
|
|
|
a covered work is covered by this License only if the output, given
|
|
|
|
|
its content, constitutes a covered work. This License acknowledges
|
|
|
|
|
your rights of fair use or other equivalent, as provided by
|
|
|
|
|
copyright law.
|
|
|
|
|
|
|
|
|
|
You may make, run and propagate covered works that you do not
|
|
|
|
|
convey, without conditions so long as your license otherwise
|
|
|
|
|
remains in force. You may convey covered works to others for the
|
|
|
|
|
sole purpose of having them make modifications exclusively for you,
|
|
|
|
|
or provide you with facilities for running those works, provided
|
|
|
|
|
that you comply with the terms of this License in conveying all
|
|
|
|
|
material for which you do not control copyright. Those thus making
|
|
|
|
|
or running the covered works for you must do so exclusively on your
|
|
|
|
|
behalf, under your direction and control, on terms that prohibit
|
|
|
|
|
them from making any copies of your copyrighted material outside
|
|
|
|
|
their relationship with you.
|
|
|
|
|
|
|
|
|
|
Conveying under any other circumstances is permitted solely under
|
|
|
|
|
the conditions stated below. Sublicensing is not allowed; section
|
|
|
|
|
10 makes it unnecessary.
|
|
|
|
|
|
|
|
|
|
3. Protecting Users’ Legal Rights From Anti-Circumvention Law.
|
|
|
|
|
|
|
|
|
|
No covered work shall be deemed part of an effective technological
|
|
|
|
|
measure under any applicable law fulfilling obligations under
|
|
|
|
|
article 11 of the WIPO copyright treaty adopted on 20 December
|
|
|
|
|
1996, or similar laws prohibiting or restricting circumvention of
|
|
|
|
|
such measures.
|
|
|
|
|
|
|
|
|
|
When you convey a covered work, you waive any legal power to forbid
|
|
|
|
|
circumvention of technological measures to the extent such
|
|
|
|
|
circumvention is effected by exercising rights under this License
|
|
|
|
|
with respect to the covered work, and you disclaim any intention to
|
|
|
|
|
limit operation or modification of the work as a means of
|
|
|
|
|
enforcing, against the work’s users, your or third parties’ legal
|
|
|
|
|
rights to forbid circumvention of technological measures.
|
|
|
|
|
|
|
|
|
|
4. Conveying Verbatim Copies.
|
|
|
|
|
|
|
|
|
|
You may convey verbatim copies of the Program’s source code as you
|
|
|
|
|
receive it, in any medium, provided that you conspicuously and
|
|
|
|
|
appropriately publish on each copy an appropriate copyright notice;
|
|
|
|
|
keep intact all notices stating that this License and any
|
|
|
|
|
non-permissive terms added in accord with section 7 apply to the
|
|
|
|
|
code; keep intact all notices of the absence of any warranty; and
|
|
|
|
|
give all recipients a copy of this License along with the Program.
|
|
|
|
|
|
|
|
|
|
You may charge any price or no price for each copy that you convey,
|
|
|
|
|
and you may offer support or warranty protection for a fee.
|
|
|
|
|
|
|
|
|
|
5. Conveying Modified Source Versions.
|
|
|
|
|
|
|
|
|
|
You may convey a work based on the Program, or the modifications to
|
|
|
|
|
produce it from the Program, in the form of source code under the
|
|
|
|
|
terms of section 4, provided that you also meet all of these
|
|
|
|
|
conditions:
|
|
|
|
|
|
|
|
|
|
a. The work must carry prominent notices stating that you
|
|
|
|
|
modified it, and giving a relevant date.
|
|
|
|
|
|
|
|
|
|
b. The work must carry prominent notices stating that it is
|
|
|
|
|
released under this License and any conditions added under
|
|
|
|
|
section 7. This requirement modifies the requirement in
|
|
|
|
|
section 4 to “keep intact all notices”.
|
|
|
|
|
|
|
|
|
|
c. You must license the entire work, as a whole, under this
|
|
|
|
|
License to anyone who comes into possession of a copy. This
|
|
|
|
|
License will therefore apply, along with any applicable
|
|
|
|
|
section 7 additional terms, to the whole of the work, and all
|
|
|
|
|
its parts, regardless of how they are packaged. This License
|
|
|
|
|
gives no permission to license the work in any other way, but
|
|
|
|
|
it does not invalidate such permission if you have separately
|
|
|
|
|
received it.
|
|
|
|
|
|
|
|
|
|
d. If the work has interactive user interfaces, each must display
|
|
|
|
|
Appropriate Legal Notices; however, if the Program has
|
|
|
|
|
interactive interfaces that do not display Appropriate Legal
|
|
|
|
|
Notices, your work need not make them do so.
|
|
|
|
|
|
|
|
|
|
A compilation of a covered work with other separate and independent
|
|
|
|
|
works, which are not by their nature extensions of the covered
|
|
|
|
|
work, and which are not combined with it such as to form a larger
|
|
|
|
|
program, in or on a volume of a storage or distribution medium, is
|
|
|
|
|
called an “aggregate” if the compilation and its resulting
|
|
|
|
|
copyright are not used to limit the access or legal rights of the
|
|
|
|
|
compilation’s users beyond what the individual works permit.
|
|
|
|
|
Inclusion of a covered work in an aggregate does not cause this
|
|
|
|
|
License to apply to the other parts of the aggregate.
|
|
|
|
|
|
|
|
|
|
6. Conveying Non-Source Forms.
|
|
|
|
|
|
|
|
|
|
You may convey a covered work in object code form under the terms
|
|
|
|
|
of sections 4 and 5, provided that you also convey the
|
|
|
|
|
machine-readable Corresponding Source under the terms of this
|
|
|
|
|
License, in one of these ways:
|
|
|
|
|
|
|
|
|
|
a. Convey the object code in, or embodied in, a physical product
|
|
|
|
|
(including a physical distribution medium), accompanied by the
|
|
|
|
|
Corresponding Source fixed on a durable physical medium
|
|
|
|
|
customarily used for software interchange.
|
|
|
|
|
|
|
|
|
|
b. Convey the object code in, or embodied in, a physical product
|
|
|
|
|
(including a physical distribution medium), accompanied by a
|
|
|
|
|
written offer, valid for at least three years and valid for as
|
|
|
|
|
long as you offer spare parts or customer support for that
|
|
|
|
|
product model, to give anyone who possesses the object code
|
|
|
|
|
either (1) a copy of the Corresponding Source for all the
|
|
|
|
|
software in the product that is covered by this License, on a
|
|
|
|
|
durable physical medium customarily used for software
|
|
|
|
|
interchange, for a price no more than your reasonable cost of
|
|
|
|
|
physically performing this conveying of source, or (2) access
|
|
|
|
|
to copy the Corresponding Source from a network server at no
|
|
|
|
|
charge.
|
|
|
|
|
|
|
|
|
|
c. Convey individual copies of the object code with a copy of the
|
|
|
|
|
written offer to provide the Corresponding Source. This
|
|
|
|
|
alternative is allowed only occasionally and noncommercially,
|
|
|
|
|
and only if you received the object code with such an offer,
|
|
|
|
|
in accord with subsection 6b.
|
|
|
|
|
|
|
|
|
|
d. Convey the object code by offering access from a designated
|
|
|
|
|
place (gratis or for a charge), and offer equivalent access to
|
|
|
|
|
the Corresponding Source in the same way through the same
|
|
|
|
|
place at no further charge. You need not require recipients
|
|
|
|
|
to copy the Corresponding Source along with the object code.
|
|
|
|
|
If the place to copy the object code is a network server, the
|
|
|
|
|
Corresponding Source may be on a different server (operated by
|
|
|
|
|
you or a third party) that supports equivalent copying
|
|
|
|
|
facilities, provided you maintain clear directions next to the
|
|
|
|
|
object code saying where to find the Corresponding Source.
|
|
|
|
|
Regardless of what server hosts the Corresponding Source, you
|
|
|
|
|
remain obligated to ensure that it is available for as long as
|
|
|
|
|
needed to satisfy these requirements.
|
|
|
|
|
|
|
|
|
|
e. Convey the object code using peer-to-peer transmission,
|
|
|
|
|
provided you inform other peers where the object code and
|
|
|
|
|
Corresponding Source of the work are being offered to the
|
|
|
|
|
general public at no charge under subsection 6d.
|
|
|
|
|
|
|
|
|
|
A separable portion of the object code, whose source code is
|
|
|
|
|
excluded from the Corresponding Source as a System Library, need
|
|
|
|
|
not be included in conveying the object code work.
|
|
|
|
|
|
|
|
|
|
A “User Product” is either (1) a “consumer product”, which means
|
|
|
|
|
any tangible personal property which is normally used for personal,
|
|
|
|
|
family, or household purposes, or (2) anything designed or sold for
|
|
|
|
|
incorporation into a dwelling. In determining whether a product is
|
|
|
|
|
a consumer product, doubtful cases shall be resolved in favor of
|
|
|
|
|
coverage. For a particular product received by a particular user,
|
|
|
|
|
“normally used” refers to a typical or common use of that class of
|
|
|
|
|
product, regardless of the status of the particular user or of the
|
|
|
|
|
way in which the particular user actually uses, or expects or is
|
|
|
|
|
expected to use, the product. A product is a consumer product
|
|
|
|
|
regardless of whether the product has substantial commercial,
|
|
|
|
|
industrial or non-consumer uses, unless such uses represent the
|
|
|
|
|
only significant mode of use of the product.
|
|
|
|
|
|
|
|
|
|
“Installation Information” for a User Product means any methods,
|
|
|
|
|
procedures, authorization keys, or other information required to
|
|
|
|
|
install and execute modified versions of a covered work in that
|
|
|
|
|
User Product from a modified version of its Corresponding Source.
|
|
|
|
|
The information must suffice to ensure that the continued
|
|
|
|
|
functioning of the modified object code is in no case prevented or
|
|
|
|
|
interfered with solely because modification has been made.
|
|
|
|
|
|
|
|
|
|
If you convey an object code work under this section in, or with,
|
|
|
|
|
or specifically for use in, a User Product, and the conveying
|
|
|
|
|
occurs as part of a transaction in which the right of possession
|
|
|
|
|
and use of the User Product is transferred to the recipient in
|
|
|
|
|
perpetuity or for a fixed term (regardless of how the transaction
|
|
|
|
|
is characterized), the Corresponding Source conveyed under this
|
|
|
|
|
section must be accompanied by the Installation Information. But
|
|
|
|
|
this requirement does not apply if neither you nor any third party
|
|
|
|
|
retains the ability to install modified object code on the User
|
|
|
|
|
Product (for example, the work has been installed in ROM).
|
|
|
|
|
|
|
|
|
|
The requirement to provide Installation Information does not
|
|
|
|
|
include a requirement to continue to provide support service,
|
|
|
|
|
warranty, or updates for a work that has been modified or installed
|
|
|
|
|
by the recipient, or for the User Product in which it has been
|
|
|
|
|
modified or installed. Access to a network may be denied when the
|
|
|
|
|
modification itself materially and adversely affects the operation
|
|
|
|
|
of the network or violates the rules and protocols for
|
|
|
|
|
communication across the network.
|
|
|
|
|
|
|
|
|
|
Corresponding Source conveyed, and Installation Information
|
|
|
|
|
provided, in accord with this section must be in a format that is
|
|
|
|
|
publicly documented (and with an implementation available to the
|
|
|
|
|
public in source code form), and must require no special password
|
|
|
|
|
or key for unpacking, reading or copying.
|
|
|
|
|
|
|
|
|
|
7. Additional Terms.
|
|
|
|
|
|
|
|
|
|
“Additional permissions” are terms that supplement the terms of
|
|
|
|
|
this License by making exceptions from one or more of its
|
|
|
|
|
conditions. Additional permissions that are applicable to the
|
|
|
|
|
entire Program shall be treated as though they were included in
|
|
|
|
|
this License, to the extent that they are valid under applicable
|
|
|
|
|
law. If additional permissions apply only to part of the Program,
|
|
|
|
|
that part may be used separately under those permissions, but the
|
|
|
|
|
entire Program remains governed by this License without regard to
|
|
|
|
|
the additional permissions.
|
|
|
|
|
|
|
|
|
|
When you convey a copy of a covered work, you may at your option
|
|
|
|
|
remove any additional permissions from that copy, or from any part
|
|
|
|
|
of it. (Additional permissions may be written to require their own
|
|
|
|
|
removal in certain cases when you modify the work.) You may place
|
|
|
|
|
additional permissions on material, added by you to a covered work,
|
|
|
|
|
for which you have or can give appropriate copyright permission.
|
|
|
|
|
|
|
|
|
|
Notwithstanding any other provision of this License, for material
|
|
|
|
|
you add to a covered work, you may (if authorized by the copyright
|
|
|
|
|
holders of that material) supplement the terms of this License with
|
|
|
|
|
terms:
|
|
|
|
|
|
|
|
|
|
a. Disclaiming warranty or limiting liability differently from
|
|
|
|
|
the terms of sections 15 and 16 of this License; or
|
|
|
|
|
|
|
|
|
|
b. Requiring preservation of specified reasonable legal notices
|
|
|
|
|
or author attributions in that material or in the Appropriate
|
|
|
|
|
Legal Notices displayed by works containing it; or
|
|
|
|
|
|
|
|
|
|
c. Prohibiting misrepresentation of the origin of that material,
|
|
|
|
|
or requiring that modified versions of such material be marked
|
|
|
|
|
in reasonable ways as different from the original version; or
|
|
|
|
|
|
|
|
|
|
d. Limiting the use for publicity purposes of names of licensors
|
|
|
|
|
or authors of the material; or
|
|
|
|
|
|
|
|
|
|
e. Declining to grant rights under trademark law for use of some
|
|
|
|
|
trade names, trademarks, or service marks; or
|
|
|
|
|
|
|
|
|
|
f. Requiring indemnification of licensors and authors of that
|
|
|
|
|
material by anyone who conveys the material (or modified
|
|
|
|
|
versions of it) with contractual assumptions of liability to
|
|
|
|
|
the recipient, for any liability that these contractual
|
|
|
|
|
assumptions directly impose on those licensors and authors.
|
|
|
|
|
|
|
|
|
|
All other non-permissive additional terms are considered “further
|
|
|
|
|
restrictions” within the meaning of section 10. If the Program as
|
|
|
|
|
you received it, or any part of it, contains a notice stating that
|
|
|
|
|
it is governed by this License along with a term that is a further
|
|
|
|
|
restriction, you may remove that term. If a license document
|
|
|
|
|
contains a further restriction but permits relicensing or conveying
|
|
|
|
|
under this License, you may add to a covered work material governed
|
|
|
|
|
by the terms of that license document, provided that the further
|
|
|
|
|
restriction does not survive such relicensing or conveying.
|
|
|
|
|
|
|
|
|
|
If you add terms to a covered work in accord with this section, you
|
|
|
|
|
must place, in the relevant source files, a statement of the
|
|
|
|
|
additional terms that apply to those files, or a notice indicating
|
|
|
|
|
where to find the applicable terms.
|
|
|
|
|
|
|
|
|
|
Additional terms, permissive or non-permissive, may be stated in
|
|
|
|
|
the form of a separately written license, or stated as exceptions;
|
|
|
|
|
the above requirements apply either way.
|
|
|
|
|
|
|
|
|
|
8. Termination.
|
|
|
|
|
|
|
|
|
|
You may not propagate or modify a covered work except as expressly
|
|
|
|
|
provided under this License. Any attempt otherwise to propagate or
|
|
|
|
|
modify it is void, and will automatically terminate your rights
|
|
|
|
|
under this License (including any patent licenses granted under the
|
|
|
|
|
third paragraph of section 11).
|
|
|
|
|
|
|
|
|
|
However, if you cease all violation of this License, then your
|
|
|
|
|
license from a particular copyright holder is reinstated (a)
|
|
|
|
|
provisionally, unless and until the copyright holder explicitly and
|
|
|
|
|
finally terminates your license, and (b) permanently, if the
|
|
|
|
|
copyright holder fails to notify you of the violation by some
|
|
|
|
|
reasonable means prior to 60 days after the cessation.
|
|
|
|
|
|
|
|
|
|
Moreover, your license from a particular copyright holder is
|
|
|
|
|
reinstated permanently if the copyright holder notifies you of the
|
|
|
|
|
violation by some reasonable means, this is the first time you have
|
|
|
|
|
received notice of violation of this License (for any work) from
|
|
|
|
|
that copyright holder, and you cure the violation prior to 30 days
|
|
|
|
|
after your receipt of the notice.
|
|
|
|
|
|
|
|
|
|
Termination of your rights under this section does not terminate
|
|
|
|
|
the licenses of parties who have received copies or rights from you
|
|
|
|
|
under this License. If your rights have been terminated and not
|
|
|
|
|
permanently reinstated, you do not qualify to receive new licenses
|
|
|
|
|
for the same material under section 10.
|
|
|
|
|
|
|
|
|
|
9. Acceptance Not Required for Having Copies.
|
|
|
|
|
|
|
|
|
|
You are not required to accept this License in order to receive or
|
|
|
|
|
run a copy of the Program. Ancillary propagation of a covered work
|
|
|
|
|
occurring solely as a consequence of using peer-to-peer
|
|
|
|
|
transmission to receive a copy likewise does not require
|
|
|
|
|
acceptance. However, nothing other than this License grants you
|
|
|
|
|
permission to propagate or modify any covered work. These actions
|
|
|
|
|
infringe copyright if you do not accept this License. Therefore,
|
|
|
|
|
by modifying or propagating a covered work, you indicate your
|
|
|
|
|
acceptance of this License to do so.
|
|
|
|
|
|
|
|
|
|
10. Automatic Licensing of Downstream Recipients.
|
|
|
|
|
|
|
|
|
|
Each time you convey a covered work, the recipient automatically
|
|
|
|
|
receives a license from the original licensors, to run, modify and
|
|
|
|
|
propagate that work, subject to this License. You are not
|
|
|
|
|
responsible for enforcing compliance by third parties with this
|
|
|
|
|
License.
|
|
|
|
|
|
|
|
|
|
An “entity transaction” is a transaction transferring control of an
|
|
|
|
|
organization, or substantially all assets of one, or subdividing an
|
|
|
|
|
organization, or merging organizations. If propagation of a
|
|
|
|
|
covered work results from an entity transaction, each party to that
|
|
|
|
|
transaction who receives a copy of the work also receives whatever
|
|
|
|
|
licenses to the work the party’s predecessor in interest had or
|
|
|
|
|
could give under the previous paragraph, plus a right to possession
|
|
|
|
|
of the Corresponding Source of the work from the predecessor in
|
|
|
|
|
interest, if the predecessor has it or can get it with reasonable
|
|
|
|
|
efforts.
|
|
|
|
|
|
|
|
|
|
You may not impose any further restrictions on the exercise of the
|
|
|
|
|
rights granted or affirmed under this License. For example, you
|
|
|
|
|
may not impose a license fee, royalty, or other charge for exercise
|
|
|
|
|
of rights granted under this License, and you may not initiate
|
|
|
|
|
litigation (including a cross-claim or counterclaim in a lawsuit)
|
|
|
|
|
alleging that any patent claim is infringed by making, using,
|
|
|
|
|
selling, offering for sale, or importing the Program or any portion
|
|
|
|
|
of it.
|
|
|
|
|
|
|
|
|
|
11. Patents.
|
|
|
|
|
|
|
|
|
|
A “contributor” is a copyright holder who authorizes use under this
|
|
|
|
|
License of the Program or a work on which the Program is based.
|
|
|
|
|
The work thus licensed is called the contributor’s “contributor
|
|
|
|
|
version”.
|
|
|
|
|
|
|
|
|
|
A contributor’s “essential patent claims” are all patent claims
|
|
|
|
|
owned or controlled by the contributor, whether already acquired or
|
|
|
|
|
hereafter acquired, that would be infringed by some manner,
|
|
|
|
|
permitted by this License, of making, using, or selling its
|
|
|
|
|
contributor version, but do not include claims that would be
|
|
|
|
|
infringed only as a consequence of further modification of the
|
|
|
|
|
contributor version. For purposes of this definition, “control”
|
|
|
|
|
includes the right to grant patent sublicenses in a manner
|
|
|
|
|
consistent with the requirements of this License.
|
|
|
|
|
|
|
|
|
|
Each contributor grants you a non-exclusive, worldwide,
|
|
|
|
|
royalty-free patent license under the contributor’s essential
|
|
|
|
|
patent claims, to make, use, sell, offer for sale, import and
|
|
|
|
|
otherwise run, modify and propagate the contents of its contributor
|
|
|
|
|
version.
|
|
|
|
|
|
|
|
|
|
In the following three paragraphs, a “patent license” is any
|
|
|
|
|
express agreement or commitment, however denominated, not to
|
|
|
|
|
enforce a patent (such as an express permission to practice a
|
|
|
|
|
patent or covenant not to sue for patent infringement). To “grant”
|
|
|
|
|
such a patent license to a party means to make such an agreement or
|
|
|
|
|
commitment not to enforce a patent against the party.
|
|
|
|
|
|
|
|
|
|
If you convey a covered work, knowingly relying on a patent
|
|
|
|
|
license, and the Corresponding Source of the work is not available
|
|
|
|
|
for anyone to copy, free of charge and under the terms of this
|
|
|
|
|
License, through a publicly available network server or other
|
|
|
|
|
readily accessible means, then you must either (1) cause the
|
|
|
|
|
Corresponding Source to be so available, or (2) arrange to deprive
|
|
|
|
|
yourself of the benefit of the patent license for this particular
|
|
|
|
|
work, or (3) arrange, in a manner consistent with the requirements
|
|
|
|
|
of this License, to extend the patent license to downstream
|
|
|
|
|
recipients. “Knowingly relying” means you have actual knowledge
|
|
|
|
|
that, but for the patent license, your conveying the covered work
|
|
|
|
|
in a country, or your recipient’s use of the covered work in a
|
|
|
|
|
country, would infringe one or more identifiable patents in that
|
|
|
|
|
country that you have reason to believe are valid.
|
|
|
|
|
|
|
|
|
|
If, pursuant to or in connection with a single transaction or
|
|
|
|
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
|
|
|
covered work, and grant a patent license to some of the parties
|
|
|
|
|
receiving the covered work authorizing them to use, propagate,
|
|
|
|
|
modify or convey a specific copy of the covered work, then the
|
|
|
|
|
patent license you grant is automatically extended to all
|
|
|
|
|
recipients of the covered work and works based on it.
|
|
|
|
|
|
|
|
|
|
A patent license is “discriminatory” if it does not include within
|
|
|
|
|
the scope of its coverage, prohibits the exercise of, or is
|
|
|
|
|
conditioned on the non-exercise of one or more of the rights that
|
|
|
|
|
are specifically granted under this License. You may not convey a
|
|
|
|
|
covered work if you are a party to an arrangement with a third
|
|
|
|
|
party that is in the business of distributing software, under which
|
|
|
|
|
you make payment to the third party based on the extent of your
|
|
|
|
|
activity of conveying the work, and under which the third party
|
|
|
|
|
grants, to any of the parties who would receive the covered work
|
|
|
|
|
from you, a discriminatory patent license (a) in connection with
|
|
|
|
|
copies of the covered work conveyed by you (or copies made from
|
|
|
|
|
those copies), or (b) primarily for and in connection with specific
|
|
|
|
|
products or compilations that contain the covered work, unless you
|
|
|
|
|
entered into that arrangement, or that patent license was granted,
|
|
|
|
|
prior to 28 March 2007.
|
|
|
|
|
|
|
|
|
|
Nothing in this License shall be construed as excluding or limiting
|
|
|
|
|
any implied license or other defenses to infringement that may
|
|
|
|
|
otherwise be available to you under applicable patent law.
|
|
|
|
|
|
|
|
|
|
12. No Surrender of Others’ Freedom.
|
|
|
|
|
|
|
|
|
|
If conditions are imposed on you (whether by court order, agreement
|
|
|
|
|
or otherwise) that contradict the conditions of this License, they
|
|
|
|
|
do not excuse you from the conditions of this License. If you
|
|
|
|
|
cannot convey a covered work so as to satisfy simultaneously your
|
|
|
|
|
obligations under this License and any other pertinent obligations,
|
|
|
|
|
then as a consequence you may not convey it at all. For example,
|
|
|
|
|
if you agree to terms that obligate you to collect a royalty for
|
|
|
|
|
further conveying from those to whom you convey the Program, the
|
|
|
|
|
only way you could satisfy both those terms and this License would
|
|
|
|
|
be to refrain entirely from conveying the Program.
|
|
|
|
|
|
|
|
|
|
13. Use with the GNU Affero General Public License.
|
|
|
|
|
|
|
|
|
|
Notwithstanding any other provision of this License, you have
|
|
|
|
|
permission to link or combine any covered work with a work licensed
|
|
|
|
|
under version 3 of the GNU Affero General Public License into a
|
|
|
|
|
single combined work, and to convey the resulting work. The terms
|
|
|
|
|
of this License will continue to apply to the part which is the
|
|
|
|
|
covered work, but the special requirements of the GNU Affero
|
|
|
|
|
General Public License, section 13, concerning interaction through
|
|
|
|
|
a network will apply to the combination as such.
|
|
|
|
|
|
|
|
|
|
14. Revised Versions of this License.
|
|
|
|
|
|
|
|
|
|
The Free Software Foundation may publish revised and/or new
|
|
|
|
|
versions of the GNU General Public License from time to time. Such
|
|
|
|
|
new versions will be similar in spirit to the present version, but
|
|
|
|
|
may differ in detail to address new problems or concerns.
|
|
|
|
|
|
|
|
|
|
Each version is given a distinguishing version number. If the
|
|
|
|
|
Program specifies that a certain numbered version of the GNU
|
|
|
|
|
General Public License “or any later version” applies to it, you
|
|
|
|
|
have the option of following the terms and conditions either of
|
|
|
|
|
that numbered version or of any later version published by the Free
|
|
|
|
|
Software Foundation. If the Program does not specify a version
|
|
|
|
|
number of the GNU General Public License, you may choose any
|
|
|
|
|
version ever published by the Free Software Foundation.
|
|
|
|
|
|
|
|
|
|
If the Program specifies that a proxy can decide which future
|
|
|
|
|
versions of the GNU General Public License can be used, that
|
|
|
|
|
proxy’s public statement of acceptance of a version permanently
|
|
|
|
|
authorizes you to choose that version for the Program.
|
|
|
|
|
|
|
|
|
|
Later license versions may give you additional or different
|
|
|
|
|
permissions. However, no additional obligations are imposed on any
|
|
|
|
|
author or copyright holder as a result of your choosing to follow a
|
|
|
|
|
later version.
|
|
|
|
|
|
|
|
|
|
15. Disclaimer of Warranty.
|
|
|
|
|
|
|
|
|
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
|
|
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
|
|
|
|
|
COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM “AS IS”
|
|
|
|
|
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,
|
|
|
|
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
|
|
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE
|
|
|
|
|
RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.
|
|
|
|
|
SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL
|
|
|
|
|
NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
|
|
|
|
|
|
|
|
16. Limitation of Liability.
|
|
|
|
|
|
|
|
|
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
|
|
|
|
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES
|
|
|
|
|
AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR
|
|
|
|
|
DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
|
|
|
|
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE
|
|
|
|
|
THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
|
|
|
|
|
BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
|
|
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
|
|
|
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF
|
|
|
|
|
THE POSSIBILITY OF SUCH DAMAGES.
|
|
|
|
|
|
|
|
|
|
17. Interpretation of Sections 15 and 16.
|
|
|
|
|
|
|
|
|
|
If the disclaimer of warranty and limitation of liability provided
|
|
|
|
|
above cannot be given local legal effect according to their terms,
|
|
|
|
|
reviewing courts shall apply local law that most closely
|
|
|
|
|
approximates an absolute waiver of all civil liability in
|
|
|
|
|
connection with the Program, unless a warranty or assumption of
|
|
|
|
|
liability accompanies a copy of the Program in return for a fee.
|
|
|
|
|
|
|
|
|
|
END OF TERMS AND CONDITIONS
|
|
|
|
|
===========================
|
|
|
|
|
|
|
|
|
|
How to Apply These Terms to Your New Programs
|
|
|
|
|
=============================================
|
|
|
|
|
|
|
|
|
|
If you develop a new program, and you want it to be of the greatest
|
|
|
|
|
possible use to the public, the best way to achieve this is to make it
|
|
|
|
|
free software which everyone can redistribute and change under these
|
|
|
|
|
terms.
|
|
|
|
|
|
|
|
|
|
To do so, attach the following notices to the program. It is safest
|
|
|
|
|
to attach them to the start of each source file to most effectively
|
|
|
|
|
state the exclusion of warranty; and each file should have at least the
|
|
|
|
|
“copyright” line and a pointer to where the full notice is found.
|
|
|
|
|
|
|
|
|
|
ONE LINE TO GIVE THE PROGRAM'S NAME AND A BRIEF IDEA OF WHAT IT DOES.
|
|
|
|
|
Copyright (C) YEAR NAME OF AUTHOR
|
|
|
|
|
|
|
|
|
|
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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
Also add information on how to contact you by electronic and paper
|
|
|
|
|
mail.
|
|
|
|
|
|
|
|
|
|
If the program does terminal interaction, make it output a short
|
|
|
|
|
notice like this when it starts in an interactive mode:
|
|
|
|
|
|
|
|
|
|
PROGRAM Copyright (C) YEAR NAME OF AUTHOR
|
|
|
|
|
This program comes with ABSOLUTELY NO WARRANTY; for details type ‘show w’.
|
|
|
|
|
This is free software, and you are welcome to redistribute it
|
|
|
|
|
under certain conditions; type ‘show c’ for details.
|
|
|
|
|
|
|
|
|
|
The hypothetical commands ‘show w’ and ‘show c’ should show the
|
|
|
|
|
appropriate parts of the General Public License. Of course, your
|
|
|
|
|
program’s commands might be different; for a GUI interface, you would
|
|
|
|
|
use an “about box”.
|
|
|
|
|
|
|
|
|
|
You should also get your employer (if you work as a programmer) or
|
|
|
|
|
school, if any, to sign a “copyright disclaimer” for the program, if
|
|
|
|
|
necessary. For more information on this, and how to apply and follow
|
|
|
|
|
the GNU GPL, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
|
|
The GNU General Public License does not permit incorporating your
|
|
|
|
|
program into proprietary programs. If your program is a subroutine
|
|
|
|
|
library, you may consider it more useful to permit linking proprietary
|
|
|
|
|
applications with the library. If this is what you want to do, use the
|
|
|
|
|
GNU Lesser General Public License instead of this License. But first,
|
|
|
|
|
please read <https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
File: dash.info, Node: Index, Prev: GPL, Up: Top
|
|
|
|
|
|
|
|
|
|
Index
|
|
|
|
|
*****
|
|
|
|
|
|
|
|
|
|
|