unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: daanturo <daanturo@gmail.com>
To: 49316@debbugs.gnu.org
Cc: Michael Heerdegen <michael_heerdegen@web.de>
Subject: bug#49316: Add apply-partially's right version
Date: Fri, 2 Jul 2021 11:39:03 +0700	[thread overview]
Message-ID: <5a08f089-3a19-d747-5098-4751c92a5b79@gmail.com> (raw)
In-Reply-To: <87r1ghr7d1.fsf@web.de>


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


--=-=-=
Content-Type: text/plain

Tags: patch


 > Could we instead
 > provide something that allows partial application of arbitrary
 > arguments, e.g. one of the arguments in the middle?

I have tried implementing, but it's really hard to provide a practical
example for documenting.

Also, most of the time after specifying a position, we would insert to
left of that. If 0 is for regular `apply-partially`, then -1 is
certainly not possible for `apply-rpartially`.

To pass ARGS at the last, should the following condition be OK?:

"If POSITION is not an integer or is >= the length of the function
application's arguments in the future."

(funcall (apply-mid-partially #'append 0 '(0 1 2 3)) '(4) '(5)) ; 
Equivalent to `apply-partially'`
=> (0 1 2 3 4 5)

(funcall (apply-mid-partially #'append 1 '(1 2 3)) '(0) '(4))
=> (0 1 2 3 4)

(funcall (apply-mid-partially #'append -1 '(1 2 3)) '(-2 -1) '(4 5) '(6 7))
=> (-2 -1 4 5 1 2 3 6 7)

; apply-rpartially
(funcall (apply-mid-partially #'append most-positive-fixnum '(1 2 3)) 
'(-2 -1) '(4 5) '(6 7))
=> (-2 -1 4 5 6 7 1 2 3)

(funcall (apply-mid-partially #'append 'foo '(1 2 3)) '(-2 -1) '(4 5) 
'(6 7))
=> (-2 -1 4 5 6 7 1 2 3)


--=-=-=
Content-Type: text/patch
Content-Disposition: attachment;
filename=0005-b-Define-apply-mid-partially.patch

 From 88522f33b497a6463ee73c4ba9479e853291035a Mon Sep 17 00:00:00 2001
From: Daanturo <daanturo@gmail.com>
Date: Fri, 2 Jul 2021 11:22:11 +0700
Subject: [PATCH] Define apply-mid-partially

* lisp/subr.el (apply-mid-partially): Currying functions with arbitrary
arguments position.
---
lisp/subr.el | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)

diff --git a/lisp/subr.el b/lisp/subr.el
index 5965655d48..2c25343a76 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -474,6 +474,33 @@ function was called."
(lambda (&rest args1)
(apply fun (append args1 args))))

+(defun apply-mid-partially (fun position &rest args)
+ "Return a function that is a partial application of FUN to ARGS at 
POSITION.
+
+ARGS is a list of N arguments to pass to FUN, starting at
+POSITION (integer).
+
+The result is a new function which does the same as FUN, except
+that N arguments starting from POSITION (inclusive) are fixed at the
+values with which this function was called.
+
+If POSITION is not an integer or is >= the length of the function
+application's arguments in the future, ARGS will be at the last.
+
+Else if POSITION is non-negative integer, count from the left.
+
+Else (POSITION is a negative integer), count from the right."
+ (lambda (&rest other-args)
+ (let* ((right-partially (or (not (integerp position))
+ (<= (length other-args) position)))
+ (first-args (seq-subseq other-args
+ 0
+ (if right-partially nil position)))
+ (last-args (if right-partially
+ nil
+ (seq-subseq other-args position))))
+ (apply fun (append first-args args last-args)))))
+
(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.32.0


--=-=-=--



On 7/2/21 5:34 AM, Michael Heerdegen wrote:
> daanturo <daanturo@gmail.com> writes:
>
> | +(defun apply-rpartially (fun &rest args)
> | + "Return a function that is a partial application of FUN to ARGS to the
> | right.
> | +ARGS is a list of the last N arguments to pass to FUN.
>
> I wonder: If we leave syntax aside for a moment - this suggestion seems
> to provide a solution for a quite special case: is this useful more
> often than partial application of arbitrary arguments?  Could we instead
> provide something that allows partial application of arbitrary
> arguments, e.g. one of the arguments in the middle?
>
>
> Michael.

-- 
Daanturo.


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

[-- Attachment #2: 0005-b-Define-apply-mid-partially.patch --]
[-- Type: text/x-patch, Size: 1913 bytes --]

From 88522f33b497a6463ee73c4ba9479e853291035a Mon Sep 17 00:00:00 2001
From: Daanturo <daanturo@gmail.com>
Date: Fri, 2 Jul 2021 11:22:11 +0700
Subject: [PATCH] Define apply-mid-partially

* lisp/subr.el (apply-mid-partially): Currying functions with arbitrary
arguments position.
---
 lisp/subr.el | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/lisp/subr.el b/lisp/subr.el
index 5965655d48..2c25343a76 100644
--- a/lisp/subr.el
+++ b/lisp/subr.el
@@ -474,6 +474,33 @@ function was called."
   (lambda (&rest args1)
     (apply fun (append args1 args))))
 
+(defun apply-mid-partially (fun position &rest args)
+  "Return a function that is a partial application of FUN to ARGS at POSITION.
+
+ARGS is a list of N arguments to pass to FUN, starting at
+POSITION (integer).
+
+The result is a new function which does the same as FUN, except
+that N arguments starting from POSITION (inclusive) are fixed at the
+values with which this function was called.
+
+If POSITION is not an integer or is >= the length of the function
+application's arguments in the future, ARGS will be at the last.
+
+Else if POSITION is non-negative integer, count from the left.
+
+Else (POSITION is a negative integer), count from the right."
+  (lambda (&rest other-args)
+    (let* ((right-partially (or (not (integerp position))
+                                (<= (length other-args) position)))
+           (first-args (seq-subseq other-args
+                                   0
+                                   (if right-partially nil position)))
+           (last-args (if right-partially
+                          nil
+                        (seq-subseq other-args position))))
+      (apply fun (append first-args args last-args)))))
+
 (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.32.0


  reply	other threads:[~2021-07-02  4:39 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-01 12:40 bug#49316: Add apply-partially's right version daanturo
2021-07-01 13:11 ` Basil L. Contovounesios
2021-07-01 16:24   ` daanturo
2021-07-01 17:06     ` daanturo
2021-07-01 17:16       ` daanturo
2021-07-01 18:45       ` Eli Zaretskii
2021-07-02  2:49         ` daanturo
2021-07-03  7:03           ` Eli Zaretskii
2021-10-24  6:55             ` Stefan Kangas
2021-10-24 10:49               ` daanturo
2021-10-24 11:18                 ` Stefan Kangas
2021-10-24 12:13                   ` Eli Zaretskii
2021-10-24 13:47                     ` Lars Ingebrigtsen
2021-10-24 14:10                       ` Stefan Kangas
2021-10-24 14:28                       ` Stefan Monnier via Bug reports for GNU Emacs, the Swiss army knife of text editors
2021-10-25 12:50                         ` Lars Ingebrigtsen
2021-10-24 13:38               ` Lars Ingebrigtsen
2021-07-02 16:32         ` daanturo
2021-07-03  7:03           ` Eli Zaretskii
2021-07-01 22:34 ` Michael Heerdegen
2021-07-02  4:39   ` daanturo [this message]
2021-07-03  3:06     ` Michael Heerdegen
2021-07-03  6:17       ` daanturo
2021-07-03 14:13       ` Phil Sainty
2021-07-05  4:29         ` daanturo
2021-07-05 12:02           ` Phil Sainty
2021-07-06  4:33           ` Michael Heerdegen
2021-07-07 16:30             ` daanturo

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=5a08f089-3a19-d747-5098-4751c92a5b79@gmail.com \
    --to=daanturo@gmail.com \
    --cc=49316@debbugs.gnu.org \
    --cc=michael_heerdegen@web.de \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).