[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Adding package "Loopy" to Non-GNU Devel?
From: |
Okamsn |
Subject: |
Adding package "Loopy" to Non-GNU Devel? |
Date: |
Tue, 20 Feb 2024 02:15:16 +0000 |
Hello,
I am the author of the package "loopy", which provides macros similar to
~cl-loop~ and Common Lisp's =iterate=. It is located here:
https://github.com/okamsn/loopy
For those not willing to browse GitHub, I have copied the main points
from the
README.org file. I have attached the README and the Org documentation file.
Visually, Loopy differs by using parentheses instead of keywords like
~cl-loop~.
For example,
#+begin_src emacs-lisp
;; A use of `cl-loop':
(cl-loop for i from 1 to 10
if (cl-evenp i) collect i into evens
else collect i into odds
end ; This `end' keyword is optional here.
finally return (list odds evens))
;; How it could be done using `loopy':
(loopy (numbers i :from 1 :to 10)
(if (cl-evenp i)
(collect evens i)
(collect odds i))
(finally-return odds evens))
#+end_src
Non-visually, these are I think the main improvements:
- Better destructuring than =cl-lib=, in that it can destructure arrays and
supports destructuring in accumulations (like ~collect~) as well as in
iteration. I recently added a Pcase pattern for this outside of the
~loopy~ macro.
#+begin_src emacs-lisp
;; => (8 10 12 14 16 18)
(loopy (list list-elem '(([1 2 3] [4 5 6])
([7 8 9] [10 11 12])))
(sum ([sum1 sum2 sum3] [sum4 sum5 sum6])
list-elem)
(finally-return sum1 sum2 sum3 sum4 sum5 sum6))
#+end_src
- Better control over accumulations, in that one can declare that an
accumulation is "optimized" (for example, using the ~push~-~nreverse~
pattern
instead of the ~append~-~list~ pattern) for named variables, allowing to
efficiently accumulate for multiple values and to declare beforehand
whether
adding to the front or the end of the list should be preferred.
The below expands into two instances of the ~push~-~nreverse~ pattern:
#+begin_src emacs-lisp
;; Separate the elements of sub-list:
;; => ((1 3) (2 4))
(loopy (accum-opt elem1 elem2)
(list i '((1 2) (3 4)))
(collect (elem1 elem2) i)
(finally-return elem1 elem2))
#+end_src
- A way to embed the looping constructs in arbitrary code like in Common
Lisp's
Iterate:
#+begin_src emacs-lisp
(require 'loopy-iter)
;; Things to note:
;; => ((-9 -8 -7 -6 -5 -4 -3 -2 -1)
;; (0)
;; (1 2 3 4 5 6 7 8 9 10 11))
(loopy-iter (accum-opt positives negatives zeroes)
(numbering i :from -10 :to 10)
;; Normal `let' and `pcase', not Loopy constructs:
(let ((var (1+ i)))
(pcase var
((pred cl-plusp) (collecting positives var))
((pred cl-minusp) (collecting negatives var))
((pred zerop) (collecting zeroes var))))
(finally-return negatives zeroes positives))
#+end_src
- An =at= feature to manipulate containing loops, such as moving to the next
iteration step or accumulating into a variable:
#+begin_src emacs-lisp
(loopy outer
(array i [(1 2) (3 4) (5 6)])
(loopy (with (sum (apply #'+ i)))
(list j i)
(at outer (collect (+ sum j)))))
#+end_src
- It should be easy to add new looping features. The documentation has
examples of this.
The package and an extension package (to use Dash's destructuring instead of
that of Loopy, Pcase, or Seq) has been available on MELPA for a few
years now.
I am asking about Non-GNU Devel instead of just the normal Non-GNU archive
because I am still making breaking changes to the package as I reduce
duplication and improve on the ideas, but those changes are coming less
frequently now.
Is it possible to add this package and the extension package to the archive?
I keep the extension package in the same GitHub repo as the main package for
testing purposes. The Dash functionality was requested by a user, but
Dash is
not used by the rest of the package. Because of that, I put the Dash
functionality in a small separate package.
Thank you.
README.org
Description: Lotus Organizer
loopy-doc.org
Description: Lotus Organizer
- Adding package "Loopy" to Non-GNU Devel?,
Okamsn <=