Skip to content

Commit

Permalink
Improve destructuring and re-implement in pcase. (#182)
Browse files Browse the repository at this point in the history
# Basic Changes

- Update README and CHANGELOG.
- Add destructuring features
- Re-implement destructuring using `pcase`.

# More Details

## All Constructs

- Re-implement destructuring of normal values using `pcase`, reducing the
  maintenance burden and making further improvements easier.
  - Make it so that the existing destructuring features will signal
    an error if the `pcase` pattern doesn't match, instead of failing silently
    as in `pcase`.
- Support full forms being vectors as well as lists.

## `&key`

- Improve `&key`:
  - Make `&key` signal an error when there are unmatched keys in the property
    list.
  - Add `&allow-other-keys`.
  - Support the full form `((KEY VAR) DEFAULT SUPPLIED)`.

## `&map`

- Add `&map` as `(KEY VAR DEFAULT SUPPLIED)`.

## `&optional`

- Add `&optional` form `(VAR DEFAULT SUPPLIED)`.

## New Files

- Move some destructuring features from `loopy-misc.el` to
  `loopy-destructure.el`.
- Move some instruction features from `loopy-misc.el` to
  `loopy-instr.el`

## Test Changes

- Add many tests for the `pcase` pattern.
- Update tests in ways that make sense for the new implementation.
- Update the `Makefile`.
- Only test the most recent minor version of each major version in the GitHub Actions.

## Removed Features

- Remove alias:
  - `loopy--destructure-generalized-variables` for 
    `loopy--destructure-generalized-sequence`
  - `loopy--basic-builtin-destructuring` for
    `loopy--destructure-for-iteration-command`

- Remove the following functions:
  - `loopy--every-other`
  - `loopy--split-list-before`
  - `loopy--split-off-last-var`
  - `loopy--destructure-sequence`
  - `loopy--destructure-list`
  - `loopy--destructure-array`
  - `loopy--generate-inc-idx-instructions`

## Added Features

- Add the following functions:
  - `loopy-seq--make-pcase-pattern`
  - `loopy--get-var-groups`
  - `loopy--get-&key-spec`
  - `loopy--get-&map-spec`
  - `loopy--get-&aux-spec`
  - `loopy--get-var-pattern`
  - `loopy--pcase-pat-positional-list-pattern`
  - `loopy--pcase-pat-positional-array-pattern`
  - `loopy--pcase-pat-&key-pattern`
  - `loopy--pcase-pat-&map-pattern`
  - `loopy--pcase-pat-&aux-pattern`
  - `loopy--pcase-destructure-for-iteration`
  - `loopy--pcase-destructure-for-with-vars`
  - `loopy--pcase-parse-for-destructuring-accumulation-command`

## Renamed Features

- Rename `loopy--parse-destructuring-accumulation-command`
  to `loopy--parse-destructuring-accumulation-command-default`
  • Loading branch information
okamsn authored Feb 19, 2024
1 parent 5af0db0 commit 4888299
Show file tree
Hide file tree
Showing 23 changed files with 3,436 additions and 1,713 deletions.
12 changes: 8 additions & 4 deletions .github/workflows/emacs-matrix-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ jobs:
strategy:
matrix:
emacs-version:
- '27.1'
# - '27.1'
- '27.2'
- '28.1'
# - '28.1'
- '28.2'
- '29.2'
- 'release-snapshot'
# - 'snapshot'
steps:
Expand All @@ -38,8 +39,11 @@ jobs:
- name: Make folder for base package.
run: |
mkdir 'test-install'
cp loopy-commands.el loopy.el loopy-vars.el loopy-misc.el loopy-pkg.el test-install
cp loopy-iter.el loopy-pcase.el loopy-seq.el test-install
# Match all files of "loopy*.el" except for "loopy-dash.el".
echo Shell is $SHELL
shopt -s extglob
cp loopy!(-dash).el test-install
shopt -u extglob
- name: Install packages
run: emacs -batch -l tests/install-script.el
- name: Basic tests
Expand Down
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ This document describes the user-facing changes to Loopy.
(collecting (10+ j))))))
```

- The documentation describes Loopy's default destructuring style as a super-set
of that of `cl-lib`. `&key` now behaves more like it does in `cl-lib`,
signaling an error when appropriate ([#182]) and supporting the full form
`((KEY VAR) DEFAULT SUPPLIED)`.

### Breaking Changes

- Fix how the first accumulated value is used in `reduce`. See [#164] and the
Expand All @@ -89,6 +94,14 @@ This document describes the user-facing changes to Loopy.
TESTED-ITEM)`, similar to `seq-contains-p`. The argument order was previously
undocumented and not guaranteed. See [#170] and [#177].

- Like in `cl-lib`, destructuring with `&key` will now signal an error if there
are unmatched keys and `&allow-other-keys` was not given or
`:allow-other-keys` is not present in the property list with a non-nil value
([#182]).

- The default destructuring style now uses `pcase` underneath ([#182]). To
accomodate this, some of the defined errors and error detections have changed.

#### Removals

- The deprecated flag `split` was removed ([#165], [#131], [#124]). Instead,
Expand Down Expand Up @@ -203,12 +216,28 @@ This document describes the user-facing changes to Loopy.
uses the constant value directly, which Emacs can optimize to avoid some uses
of `funcall`.

### Destructuring Improvements

- A `loopy` `pcase` pattern has been added ([#182]). Destructuring is now based
on `pcase`.
- A `&map` construct was added for destructuring, analogous to `&key` but using
`map-elt` and the `map` `pcase` pattern ([#182]). Extending the `map`
pattern, `&map` also has a `SUPPLIED` parameter, as in `(KEY VAR DEFAULT
SUPPLIED)`.
- An `&optional` construct was added, like in `cl-lib` ([#182]).
- `&key` now works like it does in `cl-lib`, including the `DEFAULT`,
`SUPPLIED`, and `KEY` values in the full form and signaling an error
when appropriate ([#182]).

### Other Changes

- Add `loopy--other-vars`, given the more explicit restriction on
`loopy--iteration-vars` ([#144]). For example, these are the variables bound
by the `set` command, which are allowed to occur in more than one command.

- To reduce the maintenance burden, destructuring was re-implemented using
`pcase` ([#182]).

[#144]: https://github.com/okamsn/loopy/issue/142
[#144]: https://github.com/okamsn/loopy/pull/144
[#145]: https://github.com/okamsn/loopy/issue/145
Expand All @@ -227,6 +256,7 @@ This document describes the user-facing changes to Loopy.
[#176]: https://github.com/okamsn/loopy/issues/176
[#177]: https://github.com/okamsn/loopy/pull/177
[#180]: https://github.com/okamsn/loopy/pull/180
[#182]: https://github.com/okamsn/loopy/pull/182

## 0.11.2

Expand Down
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
EMACS ?= emacs

.PHONY: tests

tests:
emacs -Q -batch -l ert -l tests/load-path.el -l tests/tests.el -f ert-run-tests-batch-and-exit
$(EMACS) -Q -batch -l ert -l tests/load-path.el -l tests/tests.el -f ert-run-tests-batch-and-exit

.PHONY: iter-tests

iter-tests:
emacs -Q -batch -l ert -l tests/load-path.el -l tests/iter-tests.el -f ert-run-tests-batch-and-exit
$(EMACS) -Q -batch -l ert -l tests/load-path.el -l tests/iter-tests.el -f ert-run-tests-batch-and-exit

.PHONY: misc-tests

misc-tests:
$(EMACS) -Q -batch -l ert -l tests/load-path.el -l tests/misc-tests.el -f ert-run-tests-batch-and-exit
13 changes: 8 additions & 5 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ overview.

-----
#+begin_center
*NOTE*: Loopy is still in its middle stages.\\
*NOTE*: Loopy is still in its latter middle stages.\\
Constructive criticism is welcome. If you see a place for improvement,
please let me know.
#+end_center
Expand Down Expand Up @@ -63,6 +63,8 @@ please let me know.
- Change the argument order of =test= to be (1) the sequence element then (2)
the tested value, like in ~seq-contains-p~ and _unlike_ in ~cl-member~, and
explicitly state this order in the documentation.
- =&key= now signals an error when there are unmatched keys in the plist, as
in =cl-lib=. =&allow-other-keys= has been added.
- See the [[https://github.com/okamsn/loopy/blob/master/CHANGELOG.md][change log]] for less recent changes.

# This auto-generated by toc-org.
Expand Down Expand Up @@ -171,7 +173,7 @@ iteration.
* Similar Libraries

Loopy is not the only Lisp library that uses parenthetical expressions instead of
keyword clauses (like in ~cl-loop~). [[https://common-lisp.net/project/iterate/][Iterate]] and [[https://github.com/Shinmera/for/][For]] are two examples from
keyword clauses (as in ~cl-loop~). [[https://common-lisp.net/project/iterate/][Iterate]] and [[https://github.com/Shinmera/for/][For]] are two examples from
Common Lisp.

#+begin_src emacs-lisp
Expand Down Expand Up @@ -256,9 +258,10 @@ Commands in Arbitrary Code]]), use
The default destructuring system is a super-set of what =cl-lib= provides
and is described in the section [[https://github.com/okamsn/loopy/blob/master/doc/loopy-doc.org#basic-destructuring][Basic Destructuring]] in the documentation.

~loopy~ can optionally use destructuring provided by ~pcase-let~, ~seq-let~, the
=dash= library, as well as its own kind. This provides greater flexibility and
allows you to use destructuring patterns that you're already familiar with.
In addition to the built-in destructuring style, ~loopy~ can optionally use
destructuring provided by ~pcase-let~, ~seq-let~, the =dash= library. This
provides greater flexibility and allows you to use destructuring patterns that
you're already familiar with.

These features can be enabled with "flags", described in the section [[https://github.com/okamsn/loopy/blob/master/doc/loopy-doc.org#using-flags][Using Flags]]
in the documentation.
Expand Down
Loading

0 comments on commit 4888299

Please sign in to comment.