Skip to content

Commit

Permalink
Absorb dash-functional into dash
Browse files Browse the repository at this point in the history
This prepares for the release of dash 2.18.0 and the final obsolete
version 1.3.0 of dash-functional.

* NEWS.md (2.18): Announce obsoletion of dash-functional.el.

* dash-functional.el: Mention obsoletion in package Commentary, and
emit a warning when byte-compiled or loaded.
(-rpartial, -juxt, -compose, -applify, -on, -flip, -const, -cut)
(-not, -orfn, -andfn, -iteratefn, -counter, -fixfn-max-iterations)
(-fixfn, -prodfn): Move from here...
* dash.el: ...to here.
(-partial): Move definition under "Combinators".

* Makefile (ELS, dash-functional.elc):
* dev/dash-defs.el (dash--make-md, dash--make-texi):
* dev/examples.el:
(Function combinators):
* dash-template.texi:
(Installation, Using in a package):
* readme-template.md (Installation, Using in a package): Remove all
uses and mentions of dash-functional.

* README.md:
* dash.texi: Regenerate docs.

Closes #356.
  • Loading branch information
basil-conto committed Feb 10, 2021
1 parent be4e939 commit 5eea156
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 257 deletions.
4 changes: 1 addition & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

EMACS ?= emacs
BATCH := $(EMACS) -Q -batch -L .
ELS := dash.el dash-functional.el dev/dash-defs.el
ELS := dash.el dev/dash-defs.el
ELCS := $(addsuffix c,$(ELS))
DOCS := README.md dash.texi
TMPLS := readme-template.md dash-template.texi $(wildcard doc/*.texi)
Expand Down Expand Up @@ -68,7 +68,5 @@ maintainer-clean: clean
%.elc: %.el
$(BATCH) -eval $(WERROR) -f batch-byte-compile $<

dash-functional.elc dev/dash-defs.elc: dash.elc

$(DOCS) &: dev/examples.el $(ELCS) $(TMPLS)
$(BATCH) -l $< -f dash-make-docs
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ See the end of the file for license conditions.

### From 2.17 to 2.18

This release absorbs the now obsolete `dash-functional` version
`1.3.0` into `dash`, and brings the very old version of `dash` on GNU
ELPA up to date.

Package maintainers should replace all uses of `dash-functional`,
which will eventually be deleted, with `dash` version `2.18.0`. For
more information on this, see:
https://github.com/magnars/dash.el/wiki/Obsoletion-of-dash-functional.el

- New function `-iota` for generating arithmetic sequences
(@holomorph, #215).

Expand Down
32 changes: 14 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,27 +37,27 @@ See the [`NEWS.md`](NEWS.md) file.

## Installation

It's available on [GNU ELPA](https://elpa.gnu.org/) and
[MELPA](https://melpa.org/):
Dash is available on [GNU ELPA](https://elpa.gnu.org/) and
[MELPA](https://melpa.org/), and can be installed with the standard
command `package-install`:

M-x package-install dash
M-x package-install RET dash RET

Or you can just dump `dash.el` in your `load-path` somewhere.
See [`(info "(emacs) Package
Installation")`](https://gnu.org/software/emacs/manual/html_node/emacs/Package-Installation.html).

If you want the function combinators, then also:

M-x package-install dash-functional
Alternatively, you can just dump `dash.el` in your `load-path`
somewhere. See [`(info "(emacs) Lisp
Libraries")`](https://gnu.org/software/emacs/manual/html_node/emacs/Lisp-Libraries.html).

### Using in a package

Add something like this to the [library's
headers](https://gnu.org/software/emacs/manual/html_node/elisp/Library-Headers.html):
Add something like this to the library's headers:

;; Package-Requires: ((dash "2.17.0"))

To get function combinators:

;; Package-Requires: ((dash "2.17.0") (dash-functional "1.2.0"))
See [`(info "(elisp) Library
Headers")`](https://gnu.org/software/emacs/manual/html_node/elisp/Library-Headers.html).

### Fontification of special variables

Expand Down Expand Up @@ -363,9 +363,7 @@ Macros that modify variables holding lists.

### Function combinators

Functions that manipulate and compose other functions. They
are currently offered in the separate package `dash-functional`
for historical reasons, and will soon be absorbed by `dash`.
Functions that manipulate and compose other functions.

* [`-partial`](#-partial-fn-rest-args) `(fn &rest args)`
* [`-rpartial`](#-rpartial-fn-rest-args) `(fn &rest args)`
Expand Down Expand Up @@ -2793,9 +2791,7 @@ Destructive: Set `list` to the cdr of `list`.

## Function combinators

Functions that manipulate and compose other functions. They
are currently offered in the separate package `dash-functional`
for historical reasons, and will soon be absorbed by `dash`.
Functions that manipulate and compose other functions.

#### -partial `(fn &rest args)`

Expand Down
195 changes: 17 additions & 178 deletions dash-functional.el
Original file line number Diff line number Diff line change
Expand Up @@ -24,190 +24,29 @@

;;; Commentary:

;; Collection of useful combinators for Emacs Lisp.
;; *N.B.:* This package has been absorbed, and is therefore made
;; obsolete, by the `dash' package, version 2.18.0.
;;
;; See their overview at https://github.com/magnars/dash.el#functions.
;; If you maintain a package that depends on `dash-functional', then
;; you should change that to instead depend on `dash' version 2.18.0,
;; and remove all references to `dash-functional'.
;;
;; If you use any packages that depend on `dash-functional', either
;; directly or indirectly, then you will have to wait until all of
;; them have transitioned away from it before you can remove it.
;;
;; For more information on this, see the following URL:
;; `https://github.com/magnars/dash.el/wiki/Obsoletion-of-dash-functional.el'

;;; Code:

(require 'dash)

(defun -rpartial (fn &rest args)
"Takes a function FN and fewer than the normal arguments to FN,
and returns a fn that takes a variable number of additional ARGS.
When called, the returned function calls FN with the additional
args first and then ARGS."
(lambda (&rest args-before) (apply fn (append args-before args))))

(defun -juxt (&rest fns)
"Takes a list of functions and returns a fn that is the
juxtaposition of those fns. The returned fn takes a variable
number of args, and returns a list containing the result of
applying each fn to the args (left-to-right)."
(lambda (&rest args) (mapcar (lambda (x) (apply x args)) fns)))

(defun -compose (&rest fns)
"Takes a list of functions and returns a fn that is the
composition of those fns. The returned fn takes a variable
number of arguments, and returns the result of applying
each fn to the result of applying the previous fn to
the arguments (right-to-left)."
(lambda (&rest args)
(car (-reduce-r-from (lambda (fn xs) (list (apply fn xs)))
args fns))))

(defun -applify (fn)
"Changes an n-arity function FN to a 1-arity function that
expects a list with n items as arguments"
(apply-partially 'apply fn))

(defun -on (operator transformer)
"Return a function of two arguments that first applies
TRANSFORMER to each of them and then applies OPERATOR on the
results (in the same order).
In types: (b -> b -> c) -> (a -> b) -> a -> a -> c"
(lambda (x y) (funcall operator (funcall transformer x) (funcall transformer y))))

(defun -flip (func)
"Swap the order of arguments for binary function FUNC.
In types: (a -> b -> c) -> b -> a -> c"
(lambda (x y) (funcall func y x)))

(defun -const (c)
"Return a function that returns C ignoring any additional arguments.
In types: a -> b -> a"
(lambda (&rest _) c))

(defmacro -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."
(let* ((i 0)
(args (--keep (when (eq it '<>)
(setq i (1+ i))
(make-symbol (format "D%d" i)))
params)))
`(lambda ,args
,(let ((body (--map (if (eq it '<>) (pop args) it) params)))
(if (eq (car params) '<>)
(cons 'funcall body)
body)))))

(defun -not (pred)
"Take a unary predicate PRED and return a unary predicate
that returns t if PRED returns nil and nil if PRED returns
non-nil."
(lambda (x) (not (funcall pred x))))

(defun -orfn (&rest preds)
"Take list of unary predicates PREDS and return a unary
predicate with argument x that returns non-nil if at least one of
the PREDS returns non-nil on x.
In types: [a -> Bool] -> a -> Bool"
(lambda (x) (-any? (-cut funcall <> x) preds)))

(defun -andfn (&rest preds)
"Take list of unary predicates PREDS and return a unary
predicate with argument x that returns non-nil if all of the
PREDS returns non-nil on x.
In types: [a -> Bool] -> a -> Bool"
(lambda (x) (-all? (-cut funcall <> x) preds)))

(defun -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' 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)))."
(lambda (x) (--dotimes n (setq x (funcall fn x))) x))

(defun -counter (&optional beg end inc)
"Return a closure that counts from BEG to END, with increment INC.
The closure will return the next value in the counting sequence
each time it is called, and nil after END is reached. BEG
defaults to 0, INC defaults to 1, and if END is nil, the counter
will increment indefinitely.
The closure accepts any number of arguments, which are discarded."
(let ((inc (or inc 1))
(n (or beg 0)))
(lambda (&rest _)
(when (or (not end) (< n end))
(prog1 n
(setq n (+ n inc)))))))

(defvar -fixfn-max-iterations 1000
"The default maximum number of iterations performed by `-fixfn'
unless otherwise specified.")

(defun -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."
(let ((eqfn (or equal-test 'equal))
(haltfn (or halt-test
(-not
(-counter 0 -fixfn-max-iterations)))))
(lambda (x)
(let ((re (funcall fn x))
(halt? (funcall haltfn x)))
(while (and (not halt?) (not (funcall eqfn x re)))
(setq x re
re (funcall fn re)
halt? (funcall haltfn re)))
(if halt? (cons 'halted halt?)
re)))))

(defun -prodfn (&rest fns)
"Take a list of n functions and return a function that takes a
list of length n, applying i-th function to i-th element of the
input list. Returns a list of length n.
In types (for n=2): ((a -> b), (c -> d)) -> (a, c) -> (b, d)
This function satisfies the following laws:
(-compose (-prodfn f g ...) (-prodfn f\\=' g\\=' ...)) = (-prodfn (-compose f f\\=') (-compose g g\\=') ...)
(-prodfn f g ...) = (-juxt (-compose f (-partial \\='nth 0)) (-compose g (-partial \\='nth 1)) ...)
(-compose (-prodfn f g ...) (-juxt f\\=' g\\=' ...)) = (-juxt (-compose f f\\=') (-compose g g\\=') ...)
(-compose (-partial \\='nth n) (-prod f1 f2 ...)) = (-compose fn (-partial \\='nth n))"
(lambda (x) (-zip-with 'funcall fns x)))
(eval-and-compile
(let ((msg "Package dash-functional is obsolete; use dash 2.18.0 instead"))
(if (and noninteractive (fboundp 'byte-compile-warn))
(byte-compile-warn msg)
(message "%s" msg))))

(provide 'dash-functional)

Expand Down
16 changes: 3 additions & 13 deletions dash-template.texi
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@c %**start of header
@setfilename dash.info
@set DASHVER @c [[ dash-version ]]
@set DASHFNVER @c [[ dash-functional-version ]]
@settitle Dash: A modern list library for GNU Emacs.
@documentencoding UTF-8
@documentlanguage en
Expand Down Expand Up @@ -88,13 +87,11 @@ Installation,,, emacs, The GNU Emacs Manual}).
@table @kbd
@item M-x package-install @key{RET} dash @key{RET}
Install the Dash library.

@item M-x package-install @key{RET} dash-functional @key{RET}
Install an optional library of additional function combinators.
@end table

Alternatively, you can just dump @file{dash.el} or
@file{dash-functional.el} in your load path somewhere.
Alternatively, you can just dump @file{dash.el} in your
@code{load-path} somewhere (@pxref{Lisp Libraries,,, emacs, The GNU
Emacs Manual}).

@menu
* Using in a package:: Listing Dash as a package dependency.
Expand All @@ -113,13 +110,6 @@ Headers,,, elisp, The Emacs Lisp Reference Manual}).
;; Package-Requires: ((dash "@value{DASHVER}"))
@end lisp

The same goes for the @file{dash-functional.el} library of function
combinators:

@lisp
;; Package-Requires: ((dash "@value{DASHVER}") (dash-functional "@value{DASHFNVER}"))
@end lisp

@node Fontification of special variables
@section Fontification of special variables

Expand Down
Loading

0 comments on commit 5eea156

Please sign in to comment.