From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Mathieu Lirzin Newsgroups: gmane.lisp.guile.bugs Subject: bug#30237: Generalizing =?UTF-8?Q?=E2=80=98and=3D>=E2=80=99?= Date: Wed, 31 Jan 2018 15:23:43 +0100 Message-ID: <87shamm7io.fsf@gnu.org> References: <877es731ar.fsf@gnu.org> <877es7ti5j.fsf@netris.org> <87y3kn10li.fsf@gnu.org> <87shamvebr.fsf@netris.org> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Trace: blaine.gmane.org 1517408555 16257 195.159.176.226 (31 Jan 2018 14:22:35 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Wed, 31 Jan 2018 14:22:35 +0000 (UTC) User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/25.3 (gnu/linux) Cc: 30237@debbugs.gnu.org To: Mark H Weaver Original-X-From: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Wed Jan 31 15:22:30 2018 Return-path: Envelope-to: guile-bugs@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by blaine.gmane.org with esmtp (Exim 4.84_2) (envelope-from ) id 1egtH9-0002ym-34 for guile-bugs@m.gmane.org; Wed, 31 Jan 2018 15:22:11 +0100 Original-Received: from localhost ([::1]:35501 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egtJA-0008Qy-1d for guile-bugs@m.gmane.org; Wed, 31 Jan 2018 09:24:16 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:44950) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egtJ2-0008Q3-31 for bug-guile@gnu.org; Wed, 31 Jan 2018 09:24:09 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egtIx-0003mr-QC for bug-guile@gnu.org; Wed, 31 Jan 2018 09:24:08 -0500 Original-Received: from debbugs.gnu.org ([208.118.235.43]:42536) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1egtIx-0003mj-KQ for bug-guile@gnu.org; Wed, 31 Jan 2018 09:24:03 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1egtIx-0003kD-CF for bug-guile@gnu.org; Wed, 31 Jan 2018 09:24:03 -0500 X-Loop: help-debbugs@gnu.org Resent-From: Mathieu Lirzin Original-Sender: "Debbugs-submit" Resent-CC: bug-guile@gnu.org Resent-Date: Wed, 31 Jan 2018 14:24:03 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 30237 X-GNU-PR-Package: guile X-GNU-PR-Keywords: Original-Received: via spool by 30237-submit@debbugs.gnu.org id=B30237.151740863614380 (code B ref 30237); Wed, 31 Jan 2018 14:24:03 +0000 Original-Received: (at 30237) by debbugs.gnu.org; 31 Jan 2018 14:23:56 +0000 Original-Received: from localhost ([127.0.0.1]:50433 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1egtIp-0003js-TQ for submit@debbugs.gnu.org; Wed, 31 Jan 2018 09:23:56 -0500 Original-Received: from eggs.gnu.org ([208.118.235.92]:53897) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1egtIn-0003jY-Bi for 30237@debbugs.gnu.org; Wed, 31 Jan 2018 09:23:54 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1egtIg-0003cc-U6 for 30237@debbugs.gnu.org; Wed, 31 Jan 2018 09:23:48 -0500 Original-Received: from fencepost.gnu.org ([2001:4830:134:3::e]:53017) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1egtIg-0003cW-QP; Wed, 31 Jan 2018 09:23:46 -0500 Original-Received: from [2a01:e35:2ec2:e580:7d5f:f616:fc6f:3970] (port=39932 helo=godel) by fencepost.gnu.org with esmtpsa (TLS1.2:RSA_AES_256_CBC_SHA1:256) (Exim 4.82) (envelope-from ) id 1egtIg-0006Uz-3Z; Wed, 31 Jan 2018 09:23:46 -0500 In-Reply-To: <87shamvebr.fsf@netris.org> (Mark H. Weaver's message of "Tue, 30 Jan 2018 23:31:52 -0500") X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 208.118.235.43 X-BeenThere: bug-guile@gnu.org List-Id: "Bug reports for GUILE, GNU's Ubiquitous Extension Language" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-guile-bounces+guile-bugs=m.gmane.org@gnu.org Original-Sender: "bug-guile" Xref: news.gmane.org gmane.lisp.guile.bugs:8994 Archived-At: Mark H Weaver writes: > This generalization will inevitably slow it down, and it's not clear > that this is useful in practice. It's also not particularly natural, > because these return value(s) somehow need to be interpreted as a > boolean. There are multiple ways to do that, and it's not clear which > is the best way. > > I think we should resist the temptation to make simple things more > complicated without good reason. Making things more complicated always > has a cost. I'm a big believer in keeping things simple, especially the > widely used primitive operations. Generalizing the arity of things tends to make them more =E2=80=9Csimple=E2= =80=9D for example thinking of =E2=80=98+=E2=80=99 as an arbitrary arity function inst= ead of a binary operator is simpler. I am realizing that In this case, the semantics are indeed unclear for multiple values. For example if multiple values were to be handled then =E2=80=98(and=3D> (values 1 2) list)=E2=80=99 should work in the first plac= e. Moreover as you pointed what should be done regarding the truthiness of multiple values is not clear either. As a consequence I withdraw my proposition to generalize =E2=80=98and=3D>=E2=80=99 to multiple values. Having said that I think the implementation you previously proposed (without the arity 0 case) keep things simple: (define and=3D> (case-lambda ((val proc) (and val (proc val))) ((val . procs) (let loop ((val val) (procs procs)) (if (null? procs) val (and val (loop ((car procs) val) (cdr procs)))))))) > Finally, there still some question in my mind whether this > generalization would be useful in practice. Have you found a > real-world use case where this generalized 'and=3D>' makes life easier? I took some time to think about a pseudo-realistic use case. Consider some configuration variables that are set from the process environment. We want to check and transform what the user provides with some slight variations for each variable: ;;; Higher-order utilities. (define (ensure pred) (lambda (val) (and (pred val) val))) (define (check pred msg) (lambda (val) (unless (pred val) (display msg)) val)) ;;; Process and check variables (unrealistic but give an idea). (define (split-path str) (string-split str #\:)) (define (no-empty-strings? lst) (not (any (lambda (str) (string=3D? "" str)) lst))) (define (keep-existing-files lst) (filter file-exists? lst)) (define (warn-deprecated-path lst) (when (any (lambda (string-suffix? "/old-bar"))) (display "Please don't refer to \"old-bar\" for XYZ reason"))) ;;; Global variables. (define %foo ;; Apply procedures in a pipeline fashion... (and=3D> (and=3D> (and=3D> (and=3D> (getenv "FOO") split-path) (ensure no-empty-strings?)) keep-existing-files) (ensure pair?))) (define %bar ;; ...or with more idiomatic procedure calls. (let ((lst (split-path (or (getenv "BAR") "/etc/bar:/usr/share/bar")))) (when (no-empty-strings? lst) (warn-deprecated-path lst) lst))) Handling arbitrary arities would allow rewriting those variables in a more elegant way: (define %foo (and=3D> (getenv "FOO") split-path (ensure no-empty-strings?) keep-existing-files (ensure pair?))) (define (no-deprecated-dirs? lst) (not (any (lambda (str) (string-suffix? "/old-bar" str)) lst))) (define %bar (and=3D> (or (getenv "BAR") "/etc/bar:/usr/share/bar") split-path (ensure no-empty-strings?) (check no-deprecated-dirs? "Please don't refer to \"old-bar\" for XYZ reason"))) =E2=80=98and-let*=E2=80=99 would be a reasonable alternative but the benefi= t of this form is that it favours the use of higher-order procedures in place of special syntax. WDYT? --=20 Mathieu Lirzin GPG: F2A3 8D7E EB2B 6640 5761 070D 0ADE E100 9460 4D37