emacs-devel
[Top][All Lists]
Advanced

[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.

Attachment: README.org
Description: Lotus Organizer

Attachment: loopy-doc.org
Description: Lotus Organizer


reply via email to

[Prev in Thread] Current Thread [Next in Thread]