Skip to content

Commit

Permalink
(GitHub Action) Review evaluation of keyword arguments during expansi…
Browse files Browse the repository at this point in the history
…on and run time. (#211)

This commit was copied from the master branch.

Commit: 7d76cee
Author: okamsn <[email protected]>
Date: 2024-09-14 14:45:00 +0000

Review evaluation of keyword arguments during expansion and run time. (#211)

- Make `close` in `iter` evaluable.  Make it evaluated at the beginning.

- Make `on-failure` in `find` evaluated at the beginning.

Closes issue #210.  See this PR #211.
  • Loading branch information
github-actions[bot] committed Sep 14, 2024
1 parent 8d7e94a commit 1fdb5d8
Show file tree
Hide file tree
Showing 6 changed files with 198 additions and 60 deletions.
14 changes: 11 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,15 @@ This document describes the user-facing changes to Loopy.

- Make `sequence-index` the default name and `seq-index` an alias ([#126, #206]).

- Allow the `unique` keyword argument of the commands `map` and `map-ref` to be
evaluable at run time, instead of just checked at compile time ([#209]).
- Review when the values of keyword arguments are taken and used ([#210]):
- Make the `close` keyword argument of the `iter` command able to be evaluated
during run time ([#211]). It was previously only used during macro expansion.
- Make the `close` keyword argument of the `iter` command evaluated at the
start of the loop to be consistent with other commands ([#211]).
- Make the `on-failure` keyword argument of the `find` command evaluated at the
start of the loop to be consistent with other commands ([#211]).
- Allow the `unique` keyword argument of the commands `map` and `map-ref` to be
evaluable at run time, instead of just checked at compile time ([#209]).

### Improvements

Expand All @@ -60,7 +67,8 @@ This document describes the user-facing changes to Loopy.
[#206]: https://github.com/okamsn/loopy/pull/206
[#207]: https://github.com/okamsn/loopy/pull/207
[#209]: https://github.com/okamsn/loopy/pull/209

[#210]: https://github.com/okamsn/loopy/issues/210
[#211]: https://github.com/okamsn/loopy/pull/211

## 0.13.0

Expand Down
11 changes: 9 additions & 2 deletions README.org
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,15 @@ please let me know.
list of built-in aliases in the future. They can still be added to the
list of known aliases using ~loopy-defalias~. See the changelog for more
information.
- The =:unique= keyword argument of the =map= and =map-ref= commands can now
be evaluable at run time, similar to most other keyword arguments.
- Improved consistency of some keyword arguments:
- The =:unique= keyword argument of the =map= and =map-ref= commands can now
be evaluable at run time.
- The =:close= argument of the =iter= command is now evaluable, instead of
only being used during macro expansion.
- The =:close= argument of the =iter= command is now evaluated at the
beginning of the loop.
- The =:on-failure= argument of the =find= command is now evaluated at the
beginning of the loop.
- Version 0.13.0:
- The deprecated =:init= keyword argument has been removed. Use the =with=
special macro argument instead.
Expand Down
43 changes: 37 additions & 6 deletions doc/loopy-doc.org
Original file line number Diff line number Diff line change
Expand Up @@ -1507,13 +1507,17 @@ loop. This restriction allows for producing more efficient code.
holds the value yielded by the iterator. The loop ends when the iterator
finishes.

=close= is whether the generator should be closed via ~iter-close~ after the
loop ends. The default is ~t~. Note that Emacs will eventually close
un-closed, un-reachable generators during garbage collection. To be
consistent with other commands, =close= is evaluated at the start of the loop,
even though it's value is only used after the loop finishes.

=yield-result= is the optional second argument to the function ~iter-next~,
which is the value of ~iter-yield~ in the iterator (not to be confused with
the value yielded by calling ~iter-next~).

=close= is whether the generator should be closed via ~iter-close~ after the
loop ends. The default is ~t~. Note that Emacs will eventually close
un-closed, un-reachable generators during garbage collection.
the value yielded by calling ~iter-next~). Unlike =close=, which is evaluated
once, =yield-result= is an expression which is substituted into the loop body.
Therefore, =yield-result= can be used to repeatedly call functions.

For efficiency, when possible, =VAR= is bound to the yielded value before each
step of the loop, which is used to detect whether the iterator signals that it
Expand All @@ -1526,6 +1530,7 @@ loop. This restriction allows for producing more efficient code.

#+begin_src emacs-lisp
;; With var:
;;
;; => ((1 . 4) (2 . 5) (3 . 6))
(loopy (with (iter-maker (iter-lambda (x)
(while x
Expand All @@ -1535,6 +1540,7 @@ loop. This restriction allows for producing more efficient code.
(collect (cons i j)))

;; Without var:
;;
;; => (1 2 3)
(loopy (iter (funcall (iter-lambda ()
;; These yielded values are all ignored.
Expand All @@ -1543,6 +1549,21 @@ loop. This restriction allows for producing more efficient code.
(iter-yield 'third-yield))))
(set i 1 (1+ i))
(collect i))

;; Using `yield-result':
;;
;; => (3 2 1)
(loopy (with (yield-results nil))
(set i 1 (1+ i))
(iter (funcall (iter-lambda ()
;; The value from the expression specified by
;; `:yield-result' is `push'-ed:
(push (iter-yield 'first-yield) yield-results)
(push (iter-yield 'second-yield) yield-results)
(push (iter-yield 'third-yield) yield-results)))
;; Note that the value of `i' evaluated each time:
:yield-result i)
(finally-return yield-results))
#+end_src

#+ATTR_TEXINFO: :tag Warning
Expand Down Expand Up @@ -2124,7 +2145,7 @@ source sequences.
=EXPR=. If =by= is non-nil (default: 1), then move to the next n-th element
during each iteration. This command is a special case of the =substream=
command (described below), setting =VAR= to the first element of each
substream. For more information, see the command =substream=.
substream. For more information on streams, see the command =substream=.

This command also has the alias =streaming=.

Expand Down Expand Up @@ -3397,6 +3418,9 @@ Sequence accumulation commands are used to join lists (such as =union= and
normal failure and =VAR= will be set to the value of =ON-FAILURE=, if
provided.

To be consistent with other commands, =ON-FAILURE= is evaluated at the
start of the loop, even though that is not necessarily where it is used.

#+BEGIN_SRC emacs-lisp
;; => (13 (1 2))
(loopy (list i '(1 2 3 4 5 6 7 8))
Expand All @@ -3420,6 +3444,13 @@ Sequence accumulation commands are used to join lists (such as =union= and
;; => nil
(loopy (list i '(1 2 3 4 5 6))
(find nil (> i 3) :on-failure 27))

;; Value of `:on-failure' gotten at the start of the loop:
;; => 27
(loopy (with (on-fail 27))
(list i '(1 2 3))
(set on-fail 33)
(find i (> i 4) :on-failure on-fail))
#+END_SRC

*** Optimizing Accumulations
Expand Down
51 changes: 41 additions & 10 deletions doc/loopy.texi
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ You should keep in mind that commands are evaluated in order. This means that
attempting something like the below example might not do what you expect, as @samp{i}
is assigned a value from the list after collecting @samp{i} into @samp{coll}.

@float Listing,orgfa9540f
@float Listing,orgcd9d132
@lisp
;; => (nil 1 2)
(loopy (collect coll i)
Expand Down Expand Up @@ -887,7 +887,7 @@ the flag @samp{dash} provided by the package @samp{loopy-dash}.

Below are two examples of destructuring in @code{cl-loop} and @code{loopy}.

@float Listing,orgb706e77
@float Listing,orgf148300
@lisp
;; => (1 2 3 4)
(cl-loop for (i . j) in '((1 . 2) (3 . 4))
Expand All @@ -902,7 +902,7 @@ Below are two examples of destructuring in @code{cl-loop} and @code{loopy}.
@caption{Destructuring values in a list.}
@end float

@float Listing,orgcc60e47
@float Listing,orgff97ac8
@lisp
;; => (1 2 3 4)
(cl-loop for elem in '((1 . 2) (3 . 4))
Expand Down Expand Up @@ -1668,13 +1668,17 @@ iterator object produced by a calling a generator function. If given, @samp{VAR
holds the value yielded by the iterator. The loop ends when the iterator
finishes.

@samp{close} is whether the generator should be closed via @code{iter-close} after the
loop ends. The default is @code{t}. Note that Emacs will eventually close
un-closed, un-reachable generators during garbage collection. To be
consistent with other commands, @samp{close} is evaluated at the start of the loop,
even though it's value is only used after the loop finishes.

@samp{yield-result} is the optional second argument to the function @code{iter-next},
which is the value of @code{iter-yield} in the iterator (not to be confused with
the value yielded by calling @code{iter-next}).

@samp{close} is whether the generator should be closed via @code{iter-close} after the
loop ends. The default is @code{t}. Note that Emacs will eventually close
un-closed, un-reachable generators during garbage collection.
the value yielded by calling @code{iter-next}). Unlike @samp{close}, which is evaluated
once, @samp{yield-result} is an expression which is substituted into the loop body.
Therefore, @samp{yield-result} can be used to repeatedly call functions.

For efficiency, when possible, @samp{VAR} is bound to the yielded value before each
step of the loop, which is used to detect whether the iterator signals that it
Expand All @@ -1687,6 +1691,7 @@ This command also has the name @samp{iterating}.

@lisp
;; With var:
;;
;; => ((1 . 4) (2 . 5) (3 . 6))
(loopy (with (iter-maker (iter-lambda (x)
(while x
Expand All @@ -1696,6 +1701,7 @@ This command also has the name @samp{iterating}.
(collect (cons i j)))
;; Without var:
;;
;; => (1 2 3)
(loopy (iter (funcall (iter-lambda ()
;; These yielded values are all ignored.
Expand All @@ -1704,6 +1710,21 @@ This command also has the name @samp{iterating}.
(iter-yield 'third-yield))))
(set i 1 (1+ i))
(collect i))
;; Using `yield-result':
;;
;; => (3 2 1)
(loopy (with (yield-results nil))
(set i 1 (1+ i))
(iter (funcall (iter-lambda ()
;; The value from the expression specified by
;; `:yield-result' is `push'-ed:
(push (iter-yield 'first-yield) yield-results)
(push (iter-yield 'second-yield) yield-results)
(push (iter-yield 'third-yield) yield-results)))
;; Note that the value of `i' evaluated each time:
:yield-result i)
(finally-return yield-results))
@end lisp

@quotation Warning
Expand Down Expand Up @@ -2306,7 +2327,7 @@ Iterate through the elements for the stream
@samp{EXPR}. If @samp{by} is non-nil (default: 1), then move to the next n-th element
during each iteration. This command is a special case of the @samp{substream}
command (described below), setting @samp{VAR} to the first element of each
substream. For more information, see the command @samp{substream}.
substream. For more information on streams, see the command @samp{substream}.

This command also has the alias @samp{streaming}.

Expand Down Expand Up @@ -3678,6 +3699,9 @@ If the loop is left early and @samp{TEST} was never non-nil, this is the same as
normal failure and @samp{VAR} will be set to the value of @samp{ON-FAILURE}, if
provided.

To be consistent with other commands, @samp{ON-FAILURE} is evaluated at the
start of the loop, even though that is not necessarily where it is used.

@lisp
;; => (13 (1 2))
(loopy (list i '(1 2 3 4 5 6 7 8))
Expand All @@ -3701,6 +3725,13 @@ provided.
;; => nil
(loopy (list i '(1 2 3 4 5 6))
(find nil (> i 3) :on-failure 27))
;; Value of `:on-failure' gotten at the start of the loop:
;; => 27
(loopy (with (on-fail 27))
(list i '(1 2 3))
(set on-fail 33)
(find i (> i 4) :on-failure on-fail))
@end lisp
@end table

Expand Down Expand Up @@ -4654,7 +4685,7 @@ using the @code{let*} special form.
This method recognizes all commands and their aliases in the user option
@code{loopy-aliases}.

@float Listing,orgab882ee
@float Listing,org7411b6a
@lisp
;; => ((1 2 3) (-3 -2 -1) (0))
(loopy-iter (arg accum-opt positives negatives other)
Expand Down
Loading

0 comments on commit 1fdb5d8

Please sign in to comment.