all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Gdobbins <gdobbins@protonmail.com>
To: Gdobbins <gdobbins@protonmail.com>
Cc: "Clément Pit-Claudel" <cpitclaudel@gmail.com>, emacs-devel@gnu.org
Subject: Re: [PATCH] Add new lisp function length= with bytecode support
Date: Mon, 06 Mar 2017 19:29:00 -0500	[thread overview]
Message-ID: <4pTgtp7P0udVYhXvmkdE96q4eNHNWW6ZQ1o7woPbQTJbXd5scmDTlaLrg4BtjD_YzTTX5qHyHhXUg3gX0jW5yenj-a2gnT0m8QiFQETB284=@protonmail.com> (raw)
In-Reply-To: <0mz3T7gRvLpYGD7MDAZGZjxUi5QdLAkXtZ7y8UX4a3tDMKu1KvlRZ2IYKRUlQh01TvDsPfG1Fl_l4MIlmBWtHW9A_nQ9liIx6Mz6vcT6lGw=@protonmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 502 bytes --]

Attached is a new patch which implements length= and the <, >, <=, >= variants in lisp. They aren't as efficient as the length= from the previous patch, especially in cases like (length= list1 list2). Since these functions can't share a bytecode with their non-length counterparts I don't know whether the trade off of a compiler macro for them is worth it. With the lisp functions the resulting bytecode would be both larger, and if none of the sequences are lists, slower as well.


-- Graham Dobbins

[-- Attachment #1.2: Type: text/html, Size: 655 bytes --]

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Add-new-lisp-functions-length-and-related.patch --]
[-- Type: text/x-patch; name="0001-Add-new-lisp-functions-length-and-related.patch", Size: 3580 bytes --]

From 93d18bb9a66d2a8c07552daadab62dc5b7885fb9 Mon Sep 17 00:00:00 2001
From: Graham Dobbins <gdobbins@protonmail.com>
Date: Mon, 6 Mar 2017 19:13:12 -0500
Subject: [PATCH] Add new lisp functions length= and related

* lisp/subr.el (length=, length<, length>, length<=, length>=): define new
functions.
---
 etc/NEWS     |  4 ++++
 lisp/subr.el | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 8f7356f3e0..33873cc076 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -997,6 +997,10 @@ that does not exist.
 operating recursively and when some other process deletes the directory
 or its files before 'delete-directory' gets to them.
 
+---
+** The new functions 'length=', 'length<', 'length>', 'length<=', and
+'length>=' allow for comparison of sequence lengths with numbers.
+
 ** Changes in Frame- and Window- Handling
 
 +++
diff --git a/lisp/subr.el b/lisp/subr.el
index 6b0403890c..0dd293bb7b 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -533,6 +533,57 @@ nbutlast
 	   (if (> n 0) (setcdr (nthcdr (- (1- m) n) list) nil))
 	   list))))
 
+(defmacro internal--length-compare (comparison tail-compare-or-swap
+                                    &optional tail-adjust)
+  `(defun ,(intern (concat "length" (symbol-name comparison)))
+       (&rest sequences)
+     ,(concat "Compare the lengths of sequences with numbers.
+Return t if the length of each sequence or number is `"
+              (symbol-name comparison)
+              "' to all\nfollowing sequences or numbers, otherwise nil.
+
+This function is more efficient if its "
+              (if (symbolp tail-compare-or-swap) "last" "first")
+              " argument is a non-list.")
+     ,(if (symbolp tail-compare-or-swap)
+          `(apply #',(intern (concat "length" (symbol-name tail-compare-or-swap)))
+                (nreverse sequences))
+        `(let* ((val (pop sequences))
+                (val (if (numberp val)
+                         val
+                       (length val)))
+                (res t)
+                ,@(when tail-adjust
+                    '((num (length sequences)))))
+           (dolist (seq sequences res)
+             (when res
+               ,@(when tail-adjust
+                   '((setq num (1- num))))
+               (setq res
+                     (cond
+                       ((numberp seq)
+                        (prog1 (,comparison val seq)
+                          (setq val seq)))
+                       ((consp seq)
+                        (let ((tail (nthcdr (1- val) seq)))
+                          ,(if tail-adjust
+                               `(prog1
+                                    ,tail-compare-or-swap
+                                  (when (> num 0)
+                                    ,tail-adjust))
+                             tail-compare-or-swap)))
+                       (t (let ((len (length seq)))
+                            (prog1 (,comparison val len)
+                              (setq val len))))))))))))
+
+(internal--length-compare = (and (consp tail) (not (cdr tail))))
+(internal--length-compare < (and (consp tail) (consp (cdr tail)))
+                          (setq val (+ val (1- (length tail)))))
+(internal--length-compare > <)
+(internal--length-compare <= (consp tail)
+                          (setq val (+ val (1- (length tail)))))
+(internal--length-compare >= <=)
+
 (defun zerop (number)
   "Return t if NUMBER is zero."
   ;; Used to be in C, but it's pointless since (= 0 n) is faster anyway because
-- 
2.12.0


  reply	other threads:[~2017-03-07  0:29 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-26 22:04 [PATCH] Add new lisp function length= with bytecode support Gdobbins
2017-02-27 16:14 ` Eli Zaretskii
2017-02-27 18:43   ` Gdobbins
2017-02-27 23:06     ` Paul Eggert
2017-02-28  0:35       ` Gdobbins
2017-02-28  9:24 ` Andreas Schwab
2017-03-06  1:59   ` Gdobbins
2017-03-06  6:13     ` Elias Mårtenson
2017-03-06  7:43       ` John Wiegley
2017-03-06 18:00         ` Richard Stallman
2017-03-06 20:36           ` Gdobbins
2017-03-06 20:45             ` Clément Pit-Claudel
2017-03-06 21:03               ` Gdobbins
2017-03-07  0:29                 ` Gdobbins [this message]
2017-03-10 10:20                   ` Ken Raeburn
2017-03-10 22:25                     ` Gdobbins
2017-03-13  2:51                       ` Gdobbins
2017-03-13  3:20                         ` Stefan Monnier
2017-03-14  6:06                           ` Gdobbins
  -- strict thread matches above, loose matches on Subject: below --
2017-03-07 13:52 Constantin Kulikov
2017-03-08  2:00 ` Gdobbins
2017-03-08  2:46   ` Stefan Monnier
2017-03-08  3:31     ` Gdobbins
2017-03-08  4:13       ` Stefan Monnier
2017-03-08  7:01         ` Gdobbins
2017-03-08 16:47           ` Stefan Monnier

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='4pTgtp7P0udVYhXvmkdE96q4eNHNWW6ZQ1o7woPbQTJbXd5scmDTlaLrg4BtjD_YzTTX5qHyHhXUg3gX0jW5yenj-a2gnT0m8QiFQETB284=@protonmail.com' \
    --to=gdobbins@protonmail.com \
    --cc=cpitclaudel@gmail.com \
    --cc=emacs-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.