From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: daanturo Newsgroups: gmane.emacs.bugs Subject: bug#49316: Add apply-partially's right version Date: Fri, 2 Jul 2021 11:39:03 +0700 Message-ID: <5a08f089-3a19-d747-5098-4751c92a5b79@gmail.com> References: <2315db79-00cf-b2f0-b5df-93cd53392292@gmail.com> <87r1ghr7d1.fsf@web.de> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------88E6D1A450B33722F674C365" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="34070"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 Cc: Michael Heerdegen To: 49316@debbugs.gnu.org Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Fri Jul 02 06:47:50 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lzB5i-0008k8-Fw for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 02 Jul 2021 06:47:50 +0200 Original-Received: from localhost ([::1]:50936 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1lzB5h-0003Xh-IC for geb-bug-gnu-emacs@m.gmane-mx.org; Fri, 02 Jul 2021 00:47:49 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:51980) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1lzAyA-0000l2-W9 for bug-gnu-emacs@gnu.org; Fri, 02 Jul 2021 00:40:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:50622) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1lzAyA-0004WZ-Nl for bug-gnu-emacs@gnu.org; Fri, 02 Jul 2021 00:40:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1lzAyA-0008A0-Ft for bug-gnu-emacs@gnu.org; Fri, 02 Jul 2021 00:40:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: daanturo Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Fri, 02 Jul 2021 04:40:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 49316 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 49316-submit@debbugs.gnu.org id=B49316.162520075431308 (code B ref 49316); Fri, 02 Jul 2021 04:40:02 +0000 Original-Received: (at 49316) by debbugs.gnu.org; 2 Jul 2021 04:39:14 +0000 Original-Received: from localhost ([127.0.0.1]:33935 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lzAxO-00088u-4T for submit@debbugs.gnu.org; Fri, 02 Jul 2021 00:39:14 -0400 Original-Received: from mail-pl1-f172.google.com ([209.85.214.172]:43741) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1lzAxL-00088g-Uy for 49316@debbugs.gnu.org; Fri, 02 Jul 2021 00:39:13 -0400 Original-Received: by mail-pl1-f172.google.com with SMTP id i13so4908969plb.10 for <49316@debbugs.gnu.org>; Thu, 01 Jul 2021 21:39:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language; bh=ZGd8Ci5HdaW6v/TMxm7h6uSvzP4EAwplyTjBox/fuNo=; b=PoUpX0xwbUBnNfo7XU9gfHEq11NDSaXI3t7Ztp+oHN9VPMG+K1UEr/EkIq27M9tdfn GdEt0JW6XNnN8UrjguklRvFMX/9Td2t07xtAWCzDSE4wg0HE8yzTiYQmadUOBPUg8AWi gwL7Yl4weiEgNYL6uAuPzDf3KyaYRFy3yhfoHcmkl3GtgiDEZfnSMPPZb+bYu4v/Oz0Y MxQhPkdiQoTV14we8MOmhU7abv3qEmOcX2jdVdU4AjbGBAdWRZvjPFitWWTmb4mcwQwM Vcl8R/6vOfeNRCLOfe9DrY5l89G3yt58U80j9/QD1bo7OfQTd5e5q4/P20S3mj4A+vEd 9acw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=ZGd8Ci5HdaW6v/TMxm7h6uSvzP4EAwplyTjBox/fuNo=; b=ekZwUoXmwH0HTxamjmfC9P37yIg0bL4Xvc4f3220+ZKAA3MRLurdLv13bQeAySEONP px80+7jKMxRrI9JDViSbZRkzg+JbZnjq4nP0ZITLyNa3wervo3ByaTNz5xCIJ/p4Zb9Z 5EbBLp85g+SZhiR/7QahFdA2TgZaqmAhL/xb/X8K8uitHuOE9+8vg/+wOZCP2PVbdcUh TYcp991grS2kuCwISXWd/bsGeUNO7pc1GRhhrgCscZ7cFoV8pZZZVQBpAMJWQngjfMuA IbXRtjJS7/f5S02bdPkOh9+MlYFNWb9JwsKLpdeIA2rJa9ntYT0jMxsuwDbmJMwiAESy /LWg== X-Gm-Message-State: AOAM531m3S56Ct6zCXW9ZAMt971IzOlvUfGD1tVP6dpjkRg+buFgWnNZ ObcpARv0JUSbFDMuPo5d0Nw= X-Google-Smtp-Source: ABdhPJxAbf45kMV9QB+xry0IRCE640+zQlPTKZmO5lYfbqvM+lEFIpoukm2VdWB6IjIXaxa0ZhzLag== X-Received: by 2002:a17:90b:4ac8:: with SMTP id mh8mr3075811pjb.84.1625200746093; Thu, 01 Jul 2021 21:39:06 -0700 (PDT) Original-Received: from ?IPv6:2402:800:630f:53b:ee3a:5256:1634:1e03? ([2402:800:630f:53b:ee3a:5256:1634:1e03]) by smtp.gmail.com with ESMTPSA id d127sm1668960pfc.50.2021.07.01.21.39.04 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 01 Jul 2021 21:39:05 -0700 (PDT) In-Reply-To: <87r1ghr7d1.fsf@web.de> Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:209297 Archived-At: This is a multi-part message in MIME format. --------------88E6D1A450B33722F674C365 Content-Type: multipart/alternative; boundary="------------10EC503E83421FDEA3A2A9BB" --------------10EC503E83421FDEA3A2A9BB Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit --=-=-= 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 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 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. --------------10EC503E83421FDEA3A2A9BB Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: 7bit
--=-=-=
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.
--------------10EC503E83421FDEA3A2A9BB-- --------------88E6D1A450B33722F674C365 Content-Type: text/x-patch; charset=UTF-8; name="0005-b-Define-apply-mid-partially.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="0005-b-Define-apply-mid-partially.patch" >From 88522f33b497a6463ee73c4ba9479e853291035a Mon Sep 17 00:00:00 2001 From: Daanturo 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 --------------88E6D1A450B33722F674C365--