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
next prev parent 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.