From unknown Sat Aug 16 10:43:30 2025 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Mailer: MIME-tools 5.509 (Entity 5.509) Content-Type: text/plain; charset=utf-8 From: bug#9776 <9776@debbugs.gnu.org> To: bug#9776 <9776@debbugs.gnu.org> Subject: Status: case-lambda should accept zero clauses Reply-To: bug#9776 <9776@debbugs.gnu.org> Date: Sat, 16 Aug 2025 17:43:30 +0000 retitle 9776 case-lambda should accept zero clauses reassign 9776 guile submitter 9776 G=C3=B6ran Weinholt severity 9776 normal thanks From debbugs-submit-bounces@debbugs.gnu.org Mon Oct 17 12:18:37 2011 Received: (at submit) by debbugs.gnu.org; 17 Oct 2011 16:18:38 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RFptd-00047h-0V for submit@debbugs.gnu.org; Mon, 17 Oct 2011 12:18:37 -0400 Received: from eggs.gnu.org ([140.186.70.92]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RFkFs-0002ec-Qv for submit@debbugs.gnu.org; Mon, 17 Oct 2011 06:17:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RFkEy-0006GT-7o for submit@debbugs.gnu.org; Mon, 17 Oct 2011 06:16:17 -0400 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on eggs.gnu.org X-Spam-Level: X-Spam-Status: No, score=-2.4 required=5.0 tests=BAYES_00,RP_MATCHES_RCVD, T_DKIM_INVALID autolearn=unavailable version=3.3.1 Received: from lists.gnu.org ([140.186.70.17]:51189) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFkEy-0006GP-1b for submit@debbugs.gnu.org; Mon, 17 Oct 2011 06:16:16 -0400 Received: from eggs.gnu.org ([140.186.70.92]:50944) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFkEs-0001PI-GS for bug-guile@gnu.org; Mon, 17 Oct 2011 06:16:15 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RFkEr-0006FW-0v for bug-guile@gnu.org; Mon, 17 Oct 2011 06:16:10 -0400 Received: from gula.weinholt.se ([95.80.32.2]:56300 helo=mail.weinholt.se) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RFkEq-0006Er-Fy for bug-guile@gnu.org; Mon, 17 Oct 2011 06:16:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=weinholt.se; s=gula2011; h=Content-Transfer-Encoding:Content-Type:MIME-Version:Message-ID:Date:Subject:To:From; bh=OLw+l2UWn1qe4UkkCO1ePE7CerPsMsv86CTRQ7UNI5s=; b=n9dl0cIM8xYcdPUSB03uctMBZUX2eNvELg4kOTTfOnnR2dk1aErMle5ZZrPV2RYXrwSdPm+WA3qKOwPqkGENfnbQ/AkmXINWsyT6TgaqhF6ZG6FuFfd6OE08h0PM9ADMzI15IO2VStoyXMbkCYwsyJlFK+z3kbKsXgVvw1mEfZccw4oC72o1IBKRB8HuHgoAnNAG8toRHO2YOR1n7C5nk+4gkAyPuaQNojiq3muqCuMV2GEyClMp9lfgmvfaH2zJ; Received: from uucp by mail.weinholt.se with local-bsmtp (Exim 4.72) (envelope-from ) id 1RFkEg-0004xc-Bs; Mon, 17 Oct 2011 12:15:58 +0200 Received: from weinholt by localhost with local (Exim 4.72) (envelope-from ) id 1RFkEP-0000ii-8n; Mon, 17 Oct 2011 12:15:41 +0200 From: =?utf-8?Q?G=C3=B6ran?= Weinholt To: bug-guile@gnu.org Subject: case-lambda should accept zero clauses Date: Mon, 17 Oct 2011 12:15:40 +0200 Message-ID: <87ty77c4ab.fsf@weinholt.se> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3) X-Received-From: 140.186.70.17 X-Spam-Score: -6.6 (------) X-Debbugs-Envelope-To: submit X-Mailman-Approved-At: Mon, 17 Oct 2011 12:18:36 -0400 X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -6.6 (------) Hello guilers, the case-lambda form is specified in r6rs-lib as accepting any number of clauses, including zero. So this should not give an error: scheme@(guile-user)> (case-lambda) While compiling expression: ERROR: Syntax error: standard input:1:0: case-lambda: bad case-lambda in form (case-lambda) Instead it should return a procedure that never gets the right number of arguments. Regards, --=20 G=C3=B6ran Weinholt From debbugs-submit-bounces@debbugs.gnu.org Thu Jan 05 17:10:33 2012 Received: (at 9776) by debbugs.gnu.org; 5 Jan 2012 22:10:34 +0000 Received: from localhost ([127.0.0.1] helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RivW5-0006PS-ES for submit@debbugs.gnu.org; Thu, 05 Jan 2012 17:10:33 -0500 Received: from mail1-relais-roc.national.inria.fr ([192.134.164.82]) by debbugs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1RivW1-0006PJ-Uf for 9776@debbugs.gnu.org; Thu, 05 Jan 2012 17:10:31 -0500 X-IronPort-AV: E=Sophos;i="4.71,464,1320620400"; d="scan'208";a="138048127" Received: from reverse-83.fdn.fr (HELO pluto) ([80.67.176.83]) by mail1-relais-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES128-SHA; 05 Jan 2012 23:06:55 +0100 From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) To: =?iso-8859-1?Q?G=F6ran?= Weinholt Subject: Re: bug#9776: case-lambda should accept zero clauses In-Reply-To: <87ty77c4ab.fsf@weinholt.se> (=?iso-8859-1?Q?=22G=F6ran?= Weinholt"'s message of "Mon, 17 Oct 2011 12:15:40 +0200") References: <87ty77c4ab.fsf@weinholt.se> User-Agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.90 (gnu/linux) X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 16 =?iso-8859-1?Q?Niv=F4se?= an 220 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 83C4 F8E5 10A3 3B4C 5BEA D15D 77DD 95E2 EA52 ECF4 X-OS: x86_64-unknown-linux-gnu Date: Thu, 05 Jan 2012 23:06:54 +0100 Message-ID: <87fwftu7lt.fsf@gnu.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -9.4 (---------) X-Debbugs-Envelope-To: 9776 Cc: 9776@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -9.4 (---------) Hi G=C3=B6ran, Sorry for the delay. G=C3=B6ran Weinholt skribis: > the case-lambda form is specified in r6rs-lib as accepting any number of > clauses, including zero. So this should not give an error: My interpretation of the =E2=80=98case-lambda=E2=80=99 implementation on p.= 15 of r6rs-lib.pdf is that =E2=80=98case-lambda-help=E2=80=99 raises an assertion= violation when =E2=80=98case-lambda=E2=80=99 is called with zero clauses. The text itself doesn=E2=80=99t explicitly mention that zero clauses are supported. What makes you think otherwise? Thanks, Ludo=E2=80=99. From debbugs-submit-bounces@debbugs.gnu.org Sat Jan 07 23:51:38 2012 Received: (at 9776) by debbugs.gnu.org; 8 Jan 2012 04:51:38 +0000 Received: from localhost ([127.0.0.1]:49337 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RjkjJ-0004He-VD for submit@debbugs.gnu.org; Sat, 07 Jan 2012 23:51:38 -0500 Received: from mail-wi0-f172.google.com ([209.85.212.172]:43117) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RjkjH-0004HQ-0e for 9776@debbugs.gnu.org; Sat, 07 Jan 2012 23:51:35 -0500 Received: by wibhj6 with SMTP id hj6so2174672wib.3 for <9776@debbugs.gnu.org>; Sat, 07 Jan 2012 20:51:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=googlemail.com; s=gamma; h=from:to:cc:subject:references:date:in-reply-to:message-id :user-agent:mime-version:content-type:content-transfer-encoding; bh=jiTuLcy2OTrV9lGsRrFnZpmEUu1yGH41w4u3XCU/038=; b=vd0qa0sK1UlvlCVVwUCDZ2fMqYA/yZY840R/mEugNNBvHvmiQ+hjNVONIgQSY5Uesp 956VC11Nf5UcAJA2I6Mnty/u4o5MyhgEHwoHms4XAUJzBIuG7xm3hhHb0W3SH+lxAFbk SS4i8PtUq2lEAlLAeHWkioEokcVEuETVtV1SY= Received: by 10.180.88.169 with SMTP id bh9mr5835448wib.20.1325998283093; Sat, 07 Jan 2012 20:51:23 -0800 (PST) Received: from Kagami.home (host86-171-77-216.range86-171.btcentralplus.com. [86.171.77.216]) by mx.google.com with ESMTPS id g26sm47871075wbo.16.2012.01.07.20.51.21 (version=TLSv1/SSLv3 cipher=OTHER); Sat, 07 Jan 2012 20:51:22 -0800 (PST) From: Ian Price To: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> Date: Sun, 08 Jan 2012 04:45:45 +0000 In-Reply-To: <87fwftu7lt.fsf@gnu.org> ("Ludovic =?utf-8?Q?Court=C3=A8s=22'?= =?utf-8?Q?s?= message of "Thu, 05 Jan 2012 23:06:54 +0100") Message-ID: <87ehvals3q.fsf@Kagami.home> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable X-Spam-Score: -2.3 (--) X-Debbugs-Envelope-To: 9776 Cc: 9776@debbugs.gnu.org, =?utf-8?Q?G=C3=B6ran?= Weinholt X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.3 (--) ludo@gnu.org (Ludovic Court=C3=A8s) writes: > Hi G=C3=B6ran, > > Sorry for the delay. > > G=C3=B6ran Weinholt skribis: > >> the case-lambda form is specified in r6rs-lib as accepting any number of >> clauses, including zero. So this should not give an error: > > My interpretation of the =E2=80=98case-lambda=E2=80=99 implementation on = p. 15 of > r6rs-lib.pdf is that =E2=80=98case-lambda-help=E2=80=99 raises an asserti= on violation > when =E2=80=98case-lambda=E2=80=99 is called with zero clauses. The case-lambda-help macro is expanded from within (lambda args (let ((n (length args))) (case-lambda-help args n (fmls b1 b2 ...) ...))) So, the full expansion is (lambda args (let ((n (length args))) (assertion-violation #f "unexpected number of arguments"))) and thus a procedure that always returns an assertion violation. > > The text itself doesn=E2=80=99t explicitly mention that zero clauses are > supported. I would disagree with this. Even without looking at the implementation, you see the specification of case-lambda as (case-lambda ...) The traditional meaning of ..., as seen in syntax-rules, and elsewhere in the r6rs, is 0 or more. Therefore a (case-lambda) form seems allowed to me. Oh, and an existence proof for good measure :) scheme@(guile=E2=88=92user)> (import (rnrs)) scheme@(guile=E2=88=92user)> (define-syntax case-lambda (syntax-rules () ((_ (fmls b1 b2 ...)) (lambda fmls b1 b2 ...)) ((_ (fmls b1 b2 ...) ...) (lambda args (let ((n (length args))) (case-lambda-help args n (fmls b1 b2 ...) ...)))))) scheme@(guile=E2=88=92user)> (define-syntax case-lambda-help (syntax-rules () ((_ args n) (assertion-violation #f "unexpected number of argume= nts")) ((_ args n ((x ...) b1 b2 ...) more ...) (if (=3D n (length =E2=80=99(x ...))) (apply (lambda (x ...) b1 b2 ...) args) (case-lambda-help args n more ...))) ((_ args n ((x1 x2 ... . r) b1 b2 ...) more ...) (if (>=3D n (length =E2=80=99(x1 x2 ...))) (apply (lambda (x1 x2 ... . r) b1 b2 ...) args) (case-lambda-help args n more ...))) ((_ args n (r b1 b2 ...) more ...) (apply (lambda r b1 b2 ...) args)))) scheme@(guile=E2=88=92user)> (case-lambda) $22 =3D #:734:0 args> scheme@(guile=E2=88=92user)> ($22) ERROR: ERROR: R6RS exception: 1. &assertion 2. &message: "unexpected number of arguments" 3. &irritants: () Entering a new prompt. Type `,bt' for a backtrace or `,q' to continue. scheme@(guile=E2=88=92user) [1]> ,q scheme@(guile=E2=88=92user)>=20 --=20 Ian Price "Programming is like pinball. The reward for doing it well is the opportunity to do it again" - from "The Wizardy Compiled" From debbugs-submit-bounces@debbugs.gnu.org Tue Jan 31 17:55:48 2012 Received: (at 9776) by debbugs.gnu.org; 31 Jan 2012 22:55:48 +0000 Received: from localhost ([127.0.0.1]:47767 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RsMc7-0008VN-Mp for submit@debbugs.gnu.org; Tue, 31 Jan 2012 17:55:48 -0500 Received: from xanadu.aquilenet.fr ([88.191.123.111]:46220) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RsMc4-0008VF-OX for 9776@debbugs.gnu.org; Tue, 31 Jan 2012 17:55:46 -0500 Received: from localhost (xanadu.aquilenet.fr [127.0.0.1]) by xanadu.aquilenet.fr (Postfix) with ESMTP id 331786E14; Tue, 31 Jan 2012 23:55:25 +0100 (CET) Received: from xanadu.aquilenet.fr ([127.0.0.1]) by localhost (xanadu.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id PWghhlI6ZXNf; Tue, 31 Jan 2012 23:55:25 +0100 (CET) Received: from pluto (reverse-83.fdn.fr [80.67.176.83]) by xanadu.aquilenet.fr (Postfix) with ESMTPSA id E2563EF0; Tue, 31 Jan 2012 23:55:23 +0100 (CET) From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) To: Ian Price Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> <87ehvals3q.fsf@Kagami.home> Date: Tue, 31 Jan 2012 23:55:23 +0100 In-Reply-To: <87ehvals3q.fsf@Kagami.home> (Ian Price's message of "Sun, 08 Jan 2012 04:45:45 +0000") Message-ID: <87k447bhyc.fsf@gnu.org> User-Agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.93 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -1.2 (-) X-Debbugs-Envelope-To: 9776 Cc: 9776@debbugs.gnu.org, =?iso-8859-1?Q?G=F6ran?= Weinholt X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -1.2 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Ian, Sorry for the late reply. Ian Price skribis: > ludo@gnu.org (Ludovic Court=C3=A8s) writes: > >> Hi G=C3=B6ran, >> >> Sorry for the delay. >> >> G=C3=B6ran Weinholt skribis: >> >>> the case-lambda form is specified in r6rs-lib as accepting any number of >>> clauses, including zero. So this should not give an error: >> >> My interpretation of the =E2=80=98case-lambda=E2=80=99 implementation on= p. 15 of >> r6rs-lib.pdf is that =E2=80=98case-lambda-help=E2=80=99 raises an assert= ion violation >> when =E2=80=98case-lambda=E2=80=99 is called with zero clauses. > The case-lambda-help macro is expanded from within > (lambda args > (let ((n (length args))) > (case-lambda-help args n > (fmls b1 b2 ...) ...))) > > So, the full expansion is > (lambda args > (let ((n (length args))) > (assertion-violation #f "unexpected number of arguments"))) > > and thus a procedure that always returns an assertion violation. Indeed, thanks for the correction (I was thinking of =E2=80=98assertion-violation=E2=80=99 as a compile-time assertion.) So, here=E2=80=99s a tentative patch for review: --=-=-= Content-Type: text/x-patch Content-Disposition: inline Modified module/ice-9/psyntax.scm diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index 728ab12..c3aa6d8 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -1778,7 +1778,19 @@ r* w* mod))))) (syntax-case clauses () - (() (values '() #f)) + (() ; zero clauses + (values + '() + (build-lambda-case s '() '() 'rest #f '() + (list (build-lexical-var s 'rest)) + (build-application s + (make-toplevel-ref s 'throw) + (list + (build-data + s 'wrong-number-of-args) + (build-data + s "Wrong number of arguments"))) + #f))) (((args e1 e2 ...) (args* e1* e2* ...) ...) (call-with-values (lambda () (get-formals #'args)) (lambda (req opt rest kw) @@ -2092,12 +2104,12 @@ (global-extend 'core 'case-lambda (lambda (e r w s mod) (syntax-case e () - ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) + ((_ (args e1 e2 ...) ...) (call-with-values (lambda () (expand-lambda-case e r w s mod lambda-formals - #'((args e1 e2 ...) (args* e1* e2* ...) ...))) + #'((args e1 e2 ...) ...))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) (_ (syntax-violation 'case-lambda "bad case-lambda" e))))) @@ -2105,12 +2117,12 @@ (global-extend 'core 'case-lambda* (lambda (e r w s mod) (syntax-case e () - ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) + ((_ (args e1 e2 ...) ...) (call-with-values (lambda () (expand-lambda-case e r w s mod lambda*-formals - #'((args e1 e2 ...) (args* e1* e2* ...) ...))) + #'((args e1 e2 ...) ...))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) (_ (syntax-violation 'case-lambda "bad case-lambda*" e))))) Modified test-suite/tests/compiler.test diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test index ee688c0..bb2be06 100644 --- a/test-suite/tests/compiler.test +++ b/test-suite/tests/compiler.test @@ -1,5 +1,5 @@ ;;;; compiler.test --- tests for the compiler -*- scheme -*- -;;;; Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +;;;; Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -163,4 +163,11 @@ (display (list x y)) (list x y)))) (display (t 'x))))) - "(x y)(x y)"))) + "(x y)(x y)")) + + (pass-if-exception "zero clauses" + exception:wrong-num-args + ;; See . + (compile '(let ((p (case-lambda))) + (and (procedure? p) (p))) + #:to 'value))) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable The problem is that the new test itself fails with: ERROR: compiler.test: case-lambda: zero clauses - arguments: ((wrong-numb= er-of-args "eval" "Wrong number of arguments" () #f)) and then a number of tests in tree-il.test fail because they were assuming the previous behavior for zero-clause =E2=80=98case-lambda=E2=80= =99. In addition, this patch uses the Guilish =E2=80=98wrong-number-of-args=E2= =80=99 exception, not the R6RS one. This is consistent, but it means that the R6RS layer would have to convert exceptions again. Thoughts? Thanks, Ludo=E2=80=99. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Wed Feb 01 00:09:17 2012 Received: (at 9776) by debbugs.gnu.org; 1 Feb 2012 05:09:17 +0000 Received: from localhost ([127.0.0.1]:48031 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RsSRY-0000vJ-1G for submit@debbugs.gnu.org; Wed, 01 Feb 2012 00:09:16 -0500 Received: from world.peace.net ([96.39.62.75]:44507 ident=hope5) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1RsSRU-0000v9-6S for 9776@debbugs.gnu.org; Wed, 01 Feb 2012 00:09:14 -0500 Received: from 209-6-91-212.c3-0.smr-ubr1.sbo-smr.ma.cable.rcn.com ([209.6.91.212] helo=yeeloong) by world.peace.net with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.69) (envelope-from ) id 1RsSR4-0005q1-JN; Wed, 01 Feb 2012 00:08:46 -0500 From: Mark H Weaver To: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> <87ehvals3q.fsf@Kagami.home> <87k447bhyc.fsf@gnu.org> Date: Wed, 01 Feb 2012 00:07:43 -0500 In-Reply-To: <87k447bhyc.fsf@gnu.org> ("Ludovic \=\?utf-8\?Q\?Court\=C3\=A8s\=22'\?\= \=\?utf-8\?Q\?s\?\= message of "Tue, 31 Jan 2012 23:55:23 +0100") Message-ID: <87hazbdtuo.fsf@netris.org> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.0.92 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -1.9 (-) X-Debbugs-Envelope-To: 9776 Cc: 9776@debbugs.gnu.org, =?utf-8?Q?G=C3=B6ran?= Weinholt , Ian Price X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -1.9 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Ludovic, Thanks for tackling this. Of course this is Andy's area, but psyntax is still fresh in my mind, so I'll attempt a review as well as my own tentative approach. ludo@gnu.org (Ludovic Court=C3=A8s) writes: > So, here=E2=80=99s a tentative patch for review: > > > Modified module/ice-9/psyntax.scm > diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm > index 728ab12..c3aa6d8 100644 > --- a/module/ice-9/psyntax.scm > +++ b/module/ice-9/psyntax.scm > @@ -1778,7 +1778,19 @@ > r* w* mod))))) >=20=20 > (syntax-case clauses () > - (() (values '() #f)) > + (() ; zero clauses > + (values > + '() > + (build-lambda-case s '() '() 'rest #f '() > + (list (build-lexical-var s 'rest)) > + (build-application s > + (make-toplevel-ref s '= throw) This 'make-toplevel-ref' should instead be 'build-primref', so that it refers to the 'throw' in the 'guile' module. As it is now, this won't work in modules that have bound 'throw' to something else. > + (list > + (build-data > + s 'wrong-number-of-a= rgs) > + (build-data > + s "Wrong number of a= rguments"))) > + #f))) Unfortunately, the above case is not only triggered for an empty case-lambda; it is the base case at the end of iteration over the clauses, so this code will be added to _every_ case-lambda. Apart from the extra bloat, this will make error reporting much worse. Right now, if you call a procedure created by 'case-lambda' with an incorrect number of arguments, the VM will generate a nice error message that includes the procedure itself, including the procedure's name. By adding this "catch-all" clause to the end of every 'case-lambda', you have taken over the job of error reporting for _all_ case-lambdas, but you produce a much less useful error message than the VM does. This also destroys the arity information for all case-lambdas. * * * * * I think the _right_ way to do this is to change all code that deals with case-lambdas (in the compiler and evaluator) to gracefully handle the zero-clause case. In the meantime, here's my attempt at a temporary fix for this problem. It contains a terrible hack, but the upside is that it produces helpful error messages in almost every case, and the tests do the right thing. Here's how it reports errors: > scheme@(guile-user)> (define foo (case-lambda)) > scheme@(guile-user)> (foo) > ;;; :2:0: warning: possibly wrong number of arguments to `foo' > ERROR: In procedure foo: > ERROR: Wrong number of arguments to # The terrible hack is that (case-lambda) expands into a normal 'lambda' that takes 32 arguments. The first six argument names form a message that informs the user that the procedure was created by an empty case lambda. The next 26 arguments make it very unlikely that you will call it with the correct number of arguments, because an inferior error message is generated in that case: > scheme@(guile-user)> (apply foo (iota 32)) > ERROR: In procedure scm-error: > ERROR: Wrong number of arguments to a procedure created by case-lambda wi= th no clauses Okay, here's my hackish attempt. Comments welcome. *ducks* :) Mark --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=MARKS_HACKISH_ZERO_CLAUSE_CASE_LAMBDA_FIX.patch Content-Description: Mark's hackish zero-clause case-lambda fix diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index 728ab12..3c0623c 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -2092,6 +2092,15 @@ (global-extend 'core 'case-lambda (lambda (e r w s mod) (syntax-case e () + ((_) (expand + ;; a terrible hack to produce helpful error messages in most cases + #`(lambda (created by case-lambda with no clauses + a b c d e f g h i j k l m n o p q r s t u v w x y z) + (scm-error + '#,'wrong-number-of-args #f + "Wrong number of arguments to a procedure created by case-lambda with no clauses" + '() #f)) + r w mod)) ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) (call-with-values (lambda () @@ -2105,6 +2114,7 @@ (global-extend 'core 'case-lambda* (lambda (e r w s mod) (syntax-case e () + ((_) (expand #'(case-lambda) r w mod)) ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) (call-with-values (lambda () diff --git a/test-suite/tests/compiler.test b/test-suite/tests/compiler.test index ee688c0..bb2be06 100644 --- a/test-suite/tests/compiler.test +++ b/test-suite/tests/compiler.test @@ -1,5 +1,5 @@ ;;;; compiler.test --- tests for the compiler -*- scheme -*- -;;;; Copyright (C) 2008, 2009, 2010, 2011 Free Software Foundation, Inc. +;;;; Copyright (C) 2008, 2009, 2010, 2011, 2012 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -163,4 +163,11 @@ (display (list x y)) (list x y)))) (display (t 'x))))) - "(x y)(x y)"))) + "(x y)(x y)")) + + (pass-if-exception "zero clauses" + exception:wrong-num-args + ;; See . + (compile '(let ((p (case-lambda))) + (and (procedure? p) (p))) + #:to 'value))) --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Thu Feb 02 17:17:19 2012 Received: (at 9776) by debbugs.gnu.org; 2 Feb 2012 22:17:19 +0000 Received: from localhost ([127.0.0.1]:51384 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Rt4xz-0002gd-Dj for submit@debbugs.gnu.org; Thu, 02 Feb 2012 17:17:19 -0500 Received: from xanadu.aquilenet.fr ([88.191.123.111]:48978) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Rt4xx-0002gW-B7 for 9776@debbugs.gnu.org; Thu, 02 Feb 2012 17:17:18 -0500 Received: from localhost (xanadu.aquilenet.fr [127.0.0.1]) by xanadu.aquilenet.fr (Postfix) with ESMTP id 5F5971770; Thu, 2 Feb 2012 23:16:47 +0100 (CET) Received: from xanadu.aquilenet.fr ([127.0.0.1]) by localhost (xanadu.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id yvFJm2FRmm9a; Thu, 2 Feb 2012 23:16:47 +0100 (CET) Received: from pluto (reverse-83.fdn.fr [80.67.176.83]) by xanadu.aquilenet.fr (Postfix) with ESMTPSA id 0364EDC2; Thu, 2 Feb 2012 23:16:45 +0100 (CET) From: ludo@gnu.org (Ludovic =?iso-8859-1?Q?Court=E8s?=) To: Mark H Weaver Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> <87ehvals3q.fsf@Kagami.home> <87k447bhyc.fsf@gnu.org> <87hazbdtuo.fsf@netris.org> X-URL: http://www.fdn.fr/~lcourtes/ X-Revolutionary-Date: 14 =?iso-8859-1?Q?Pluvi=F4se?= an 220 de la =?iso-8859-1?Q?R=E9volution?= X-PGP-Key-ID: 0xEA52ECF4 X-PGP-Key: http://www.fdn.fr/~lcourtes/ludovic.asc X-PGP-Fingerprint: 83C4 F8E5 10A3 3B4C 5BEA D15D 77DD 95E2 EA52 ECF4 X-OS: x86_64-unknown-linux-gnu Date: Thu, 02 Feb 2012 23:16:45 +0100 In-Reply-To: <87hazbdtuo.fsf@netris.org> (Mark H. Weaver's message of "Wed, 01 Feb 2012 00:07:43 -0500") Message-ID: <877h04swxe.fsf@gnu.org> User-Agent: Gnus/5.110018 (No Gnus v0.18) Emacs/24.0.93 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Spam-Score: -1.2 (-) X-Debbugs-Envelope-To: 9776 Cc: 9776@debbugs.gnu.org, =?iso-8859-1?Q?G=F6ran?= Weinholt , Ian Price X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -1.2 (-) --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hi Mark, Mark H Weaver skribis: > Thanks for tackling this. Of course this is Andy's area, but psyntax is > still fresh in my mind, so I'll attempt a review as well as my own > tentative approach. Psyntax is not yet a place where I feel comfortable, so I appreciate. :-) > ludo@gnu.org (Ludovic Court=C3=A8s) writes: >> So, here=E2=80=99s a tentative patch for review: >> >> >> Modified module/ice-9/psyntax.scm >> diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm >> index 728ab12..c3aa6d8 100644 >> --- a/module/ice-9/psyntax.scm >> +++ b/module/ice-9/psyntax.scm >> @@ -1778,7 +1778,19 @@ >> r* w* mod))))) >>=20=20 >> (syntax-case clauses () >> - (() (values '() #f)) >> + (() ; zero clauses >> + (values >> + '() >> + (build-lambda-case s '() '() 'rest #f '() >> + (list (build-lexical-var s 'rest)) >> + (build-application s >> + (make-toplevel-ref s = 'throw) > > This 'make-toplevel-ref' should instead be 'build-primref', so that it > refers to the 'throw' in the 'guile' module. As it is now, this won't > work in modules that have bound 'throw' to something else. Oh, OK. >> + (list >> + (build-data >> + s 'wrong-number-of-= args) >> + (build-data >> + s "Wrong number of = arguments"))) >> + #f))) > > Unfortunately, the above case is not only triggered for an empty > case-lambda; it is the base case at the end of iteration over the > clauses, so this code will be added to _every_ case-lambda. Oops, indeed. > Apart from the extra bloat, this will make error reporting much worse. > Right now, if you call a procedure created by 'case-lambda' with an > incorrect number of arguments, the VM will generate a nice error message > that includes the procedure itself, including the procedure's name. > > By adding this "catch-all" clause to the end of every 'case-lambda', you > have taken over the job of error reporting for _all_ case-lambdas, but > you produce a much less useful error message than the VM does. > > This also destroys the arity information for all case-lambdas. OK, I see. [...] > Here's how it reports errors: > >> scheme@(guile-user)> (define foo (case-lambda)) >> scheme@(guile-user)> (foo) >> ;;; :2:0: warning: possibly wrong number of arguments to `foo' >> ERROR: In procedure foo: >> ERROR: Wrong number of arguments to # [...] > + ;; a terrible hack to produce helpful error= messages in most cases > + #`(lambda (created by case-lambda with no c= lauses > + a b c d e f g h i j k l = m n o p q r s t u v w x y z) > + (scm-error > + '#,'wrong-number-of-args #f > + "Wrong number of arguments to a proced= ure created by case-lambda with no clauses" > + '() #f)) But this is terrrrrible! What about something along these lines instead (untested): --=-=-= Content-Type: text/x-patch Content-Disposition: inline diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index 728ab12..da7f16a 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -1704,7 +1704,7 @@ orig-args)))) (req orig-args '()))) - (define expand-lambda-case + (define expand-lambda-case* (lambda (e r w s mod get-formals clauses) (define (parse-req req opt rest kw body) (let ((vars (map gen-var req)) @@ -1795,6 +1795,25 @@ (build-lambda-case s req opt rest kw inits vars body else*)))))))))))) + (define expand-lambda-case + (lambda (e r w s mod get-formals clauses) + (syntax-case clauses () + (() + (values + '() + (build-lambda-case s '() '() 'rest #f '() + (list (build-lexical-var s 'rest)) + (build-application s + (build-primref s 'throw) + (list + (build-data + s 'wrong-number-of-args) + (build-data + s "Wrong number of arguments"))) + #f))) + (((args e1 e2 ...) (args* e1* e2* ...) ...) + (expand-lambda-case* e r w s mod get-formal clauses))))) + ;; data ;; strips syntax-objects down to top-wrap --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable The idea would be to explicitly check for the zero-clause case before any recursive call is made. Thanks, Ludo=E2=80=99. --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Mar 02 13:13:36 2013 Received: (at 9776) by debbugs.gnu.org; 2 Mar 2013 18:13:36 +0000 Received: from localhost ([127.0.0.1]:55702 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UBqwB-0004PC-Eh for submit@debbugs.gnu.org; Sat, 02 Mar 2013 13:13:36 -0500 Received: from a-pb-sasl-quonix.pobox.com ([208.72.237.25]:53126 helo=sasl.smtp.pobox.com) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UBqw5-0004P3-Oy for 9776@debbugs.gnu.org; Sat, 02 Mar 2013 13:13:33 -0500 Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 92A36BF90; Sat, 2 Mar 2013 13:13:24 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=51v7vAy5Y6zZkEqsjIr5tyQjWeo=; b=km0fOT BSKtA0wkamv2nklriGnQ4quHc3lkQt7yq0WGVAE4pJFAmLW197tpPaFI2kdwfC4o Zr0MYULTEsHB+ApVt8f9Vf4pJXUpIOQgY9cssbtWE43CUpm75Pv+vagC5XMGzkIG FAhwhvo8F1vnoLkjAmT9DFpYZdq79IqGv5ico= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=icwTFnaGfdP72I/ollimRTKTbrgZSlLt k5+uLSQnRDbSZ+V5q0O7azew6CQKXS16SfVw/huVDUv+EzhD7iKU6j8dbbN8NGwW 52Oln+gvkeg8lvId6mof1kI37pKAfg1cb+LVJRKqi8nHeZe2r1EZKgpWdgNq3g9H HLAN2QQr08A= Received: from a-pb-sasl-quonix.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 8A45ABF8F; Sat, 2 Mar 2013 13:13:24 -0500 (EST) Received: from badger (unknown [88.160.190.192]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTPSA id B2DA8BF8E; Sat, 2 Mar 2013 13:13:23 -0500 (EST) From: Andy Wingo To: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> <87ehvals3q.fsf@Kagami.home> <87k447bhyc.fsf@gnu.org> <87hazbdtuo.fsf@netris.org> <877h04swxe.fsf@gnu.org> Date: Sat, 02 Mar 2013 19:13:21 +0100 In-Reply-To: <877h04swxe.fsf@gnu.org> ("Ludovic =?utf-8?Q?Court=C3=A8s=22'?= =?utf-8?Q?s?= message of "Thu, 02 Feb 2012 23:16:45 +0100") Message-ID: <8738wdisam.fsf@pobox.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" X-Pobox-Relay-ID: DF2A2BEA-8364-11E2-AD42-034D0E5B5709-02397024!a-pb-sasl-quonix.pobox.com X-Spam-Score: -2.6 (--) X-Debbugs-Envelope-To: 9776 Cc: Mark H Weaver , =?utf-8?Q?G?= =?utf-8?Q?=C3=B6ran?= Weinholt , Ian Price , 9776@debbugs.gnu.org X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.6 (--) --=-=-= Content-Type: text/plain Hi! Picking up an old thread. What do people think about the attached patch? It preserves arity checking for case-lambdas defined in the same compilation unit. Case-lambdas are converted to nullary procedures in the last minute, before compiling or memoizing. Calling one of these procedures with arguments will still produce an arity-check warning; calling one without arguments will not. In both cases a wrong-number-of-args exception is thrown at runtime (either by the normal argument count check or via the explicit throw in the body). I think allowing lambda-body to be #f is the right way to go because it precludes inlining of ((case-lambda)). I'll push soon if there are no comments. Andy --=-=-= Content-Type: text/x-diff Content-Disposition: inline; filename=0001-allow-case-lambda-expressions-with-no-clauses.patch >From 8dbcaecca7492788452881b3f06328329ed8bcf1 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Sat, 2 Mar 2013 19:04:47 +0100 Subject: [PATCH] allow case-lambda expressions with no clauses * module/ice-9/psyntax-pp.scm: * module/ice-9/psyntax.scm (case-lambda, case-lambda*): Allow 0 clauses. * module/language/scheme/decompile-tree-il.scm (do-decompile): (choose-output-names): * module/language/tree-il.scm (unparse-tree-il): (tree-il-fold, post-order!, pre-order!): * module/language/tree-il/effects.scm (make-effects-analyzer): * module/language/tree-il/cse.scm (cse): * module/language/tree-il/debug.scm (verify-tree-il): * module/language/tree-il/peval.scm (peval): Allow for lambda-body to be #f. * libguile/memoize.c (memoize): * module/language/tree-il/canonicalize.scm (canonicalize!): Give a body to empty case-lambda before evaluating it or compiling it, respectively. * test-suite/tests/optargs.test ("case-lambda", "case-lambda*"): Add tests. --- libguile/memoize.c | 25 +++++++++++++++--- module/ice-9/psyntax-pp.scm | 30 +++++++++------------- module/ice-9/psyntax.scm | 8 +++--- module/language/scheme/decompile-tree-il.scm | 35 ++++++++++++++------------ module/language/tree-il.scm | 22 +++++++++++----- module/language/tree-il/canonicalize.scm | 17 ++++++++++++- module/language/tree-il/cse.scm | 8 +++--- module/language/tree-il/debug.scm | 7 +++--- module/language/tree-il/effects.scm | 9 +++++-- module/language/tree-il/peval.scm | 4 +-- test-suite/tests/optargs.test | 13 ++++++++++ 11 files changed, 120 insertions(+), 58 deletions(-) diff --git a/libguile/memoize.c b/libguile/memoize.c index 584096f..dfbeea7 100644 --- a/libguile/memoize.c +++ b/libguile/memoize.c @@ -269,14 +269,33 @@ memoize (SCM exp, SCM env) return MAKMEMO_BEGIN (memoize_exps (REF (exp, SEQUENCE, EXPS), env)); case SCM_EXPANDED_LAMBDA: - /* The body will be a lambda-case. */ + /* The body will be a lambda-case or #f. */ { - SCM meta, docstring, proc; + SCM meta, docstring, body, proc; meta = REF (exp, LAMBDA, META); docstring = scm_assoc_ref (meta, scm_sym_documentation); - proc = memoize (REF (exp, LAMBDA, BODY), env); + body = REF (exp, LAMBDA, BODY); + if (scm_is_false (body)) + /* Give a body to case-lambda with no clauses. */ + proc = MAKMEMO_LAMBDA + (MAKMEMO_CALL + (MAKMEMO_MOD_REF (list_of_guile, + scm_from_latin1_symbol ("throw"), + SCM_BOOL_F), + 5, + scm_list_5 (MAKMEMO_QUOTE (scm_args_number_key), + MAKMEMO_QUOTE (SCM_BOOL_F), + MAKMEMO_QUOTE (scm_from_latin1_string + ("Wrong number of arguments")), + MAKMEMO_QUOTE (SCM_EOL), + MAKMEMO_QUOTE (SCM_BOOL_F))), + FIXED_ARITY (0), + SCM_BOOL_F /* docstring */); + else + proc = memoize (body, env); + if (scm_is_string (docstring)) { SCM args = SCM_MEMOIZED_ARGS (proc); diff --git a/module/ice-9/psyntax-pp.scm b/module/ice-9/psyntax-pp.scm index 2adb83e..7b565db 100644 --- a/module/ice-9/psyntax-pp.scm +++ b/module/ice-9/psyntax-pp.scm @@ -1743,11 +1743,9 @@ 'case-lambda (lambda (e r w s mod) (let* ((tmp e) - (tmp ($sc-dispatch - tmp - '(_ (any any . each-any) . #(each (any any . each-any)))))) + (tmp ($sc-dispatch tmp '(_ . #(each (any any . each-any)))))) (if tmp - (apply (lambda (args e1 e2 args* e1* e2*) + (apply (lambda (args e1 e2) (call-with-values (lambda () (expand-lambda-case @@ -1757,11 +1755,10 @@ s mod lambda-formals - (cons (cons args (cons e1 e2)) - (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2))) - e2* - e1* - args*)))) + (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2))) + e2 + e1 + args))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) tmp) (syntax-violation 'case-lambda "bad case-lambda" e))))) @@ -1770,11 +1767,9 @@ 'case-lambda* (lambda (e r w s mod) (let* ((tmp e) - (tmp ($sc-dispatch - tmp - '(_ (any any . each-any) . #(each (any any . each-any)))))) + (tmp ($sc-dispatch tmp '(_ . #(each (any any . each-any)))))) (if tmp - (apply (lambda (args e1 e2 args* e1* e2*) + (apply (lambda (args e1 e2) (call-with-values (lambda () (expand-lambda-case @@ -1784,11 +1779,10 @@ s mod lambda*-formals - (cons (cons args (cons e1 e2)) - (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2))) - e2* - e1* - args*)))) + (map (lambda (tmp-2 tmp-1 tmp) (cons tmp (cons tmp-1 tmp-2))) + e2 + e1 + args))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) tmp) (syntax-violation 'case-lambda "bad case-lambda*" e))))) diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index 336c8da..228d8e3 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -2076,12 +2076,12 @@ (global-extend 'core 'case-lambda (lambda (e r w s mod) (syntax-case e () - ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) + ((_ (args e1 e2 ...) ...) (call-with-values (lambda () (expand-lambda-case e r w s mod lambda-formals - #'((args e1 e2 ...) (args* e1* e2* ...) ...))) + #'((args e1 e2 ...) ...))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) (_ (syntax-violation 'case-lambda "bad case-lambda" e))))) @@ -2089,12 +2089,12 @@ (global-extend 'core 'case-lambda* (lambda (e r w s mod) (syntax-case e () - ((_ (args e1 e2 ...) (args* e1* e2* ...) ...) + ((_ (args e1 e2 ...) ...) (call-with-values (lambda () (expand-lambda-case e r w s mod lambda*-formals - #'((args e1 e2 ...) (args* e1* e2* ...) ...))) + #'((args e1 e2 ...) ...))) (lambda (meta lcase) (build-case-lambda s meta lcase)))) (_ (syntax-violation 'case-lambda "bad case-lambda*" e))))) diff --git a/module/language/scheme/decompile-tree-il.scm b/module/language/scheme/decompile-tree-il.scm index 9191b2f..f94661d 100644 --- a/module/language/scheme/decompile-tree-il.scm +++ b/module/language/scheme/decompile-tree-il.scm @@ -1,6 +1,6 @@ ;;; Guile VM code converters -;; Copyright (C) 2001, 2009, 2012 Free Software Foundation, Inc. +;; Copyright (C) 2001, 2009, 2012, 2013 Free Software Foundation, Inc. ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -256,20 +256,22 @@ (build-define name (recurse exp))) (( meta body) - (let ((body (recurse body)) - (doc (assq-ref meta 'documentation))) - (if (not doc) - body - (match body - (('lambda formals body ...) - `(lambda ,formals ,doc ,@body)) - (('lambda* formals body ...) - `(lambda* ,formals ,doc ,@body)) - (('case-lambda (formals body ...) clauses ...) - `(case-lambda (,formals ,doc ,@body) ,@clauses)) - (('case-lambda* (formals body ...) clauses ...) - `(case-lambda* (,formals ,doc ,@body) ,@clauses)) - (e e))))) + (if body + (let ((body (recurse body)) + (doc (assq-ref meta 'documentation))) + (if (not doc) + body + (match body + (('lambda formals body ...) + `(lambda ,formals ,doc ,@body)) + (('lambda* formals body ...) + `(lambda* ,formals ,doc ,@body)) + (('case-lambda (formals body ...) clauses ...) + `(case-lambda (,formals ,doc ,@body) ,@clauses)) + (('case-lambda* (formals body ...) clauses ...) + `(case-lambda* (,formals ,doc ,@body) ,@clauses)) + (e e)))) + '(case-lambda))) (( req opt rest kw inits gensyms body alternate) (let ((names (map output-name gensyms))) @@ -694,7 +696,8 @@ (recurse test) (recurse consequent) (recurse alternate)) (( exps) (primitive 'begin) (for-each recurse exps)) - (( body) (recurse body)) + (( body) + (if body (recurse body))) (( req opt rest kw inits gensyms body alternate) (primitive 'lambda) diff --git a/module/language/tree-il.scm b/module/language/tree-il.scm index 1ac1809..aa00b38 100644 --- a/module/language/tree-il.scm +++ b/module/language/tree-il.scm @@ -1,4 +1,4 @@ -;;;; Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc. +;;;; Copyright (C) 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -287,7 +287,9 @@ `(define ,name ,(unparse-tree-il exp))) (( meta body) - `(lambda ,meta ,(unparse-tree-il body))) + (if body + `(lambda ,meta ,(unparse-tree-il body)) + `(lambda ,meta (lambda-case)))) (( req opt rest kw inits gensyms body alternate) `(lambda-case ((,req ,opt ,rest ,kw ,(map unparse-tree-il inits) ,gensyms) @@ -370,7 +372,11 @@ This is an implementation of `foldts' as described by Andy Wingo in (( exps) (up tree (loop exps (down tree result)))) (( body) - (up tree (loop body (down tree result)))) + (let ((result (down tree result))) + (up tree + (if body + (loop body result) + result)))) (( inits body alternate) (up tree (if alternate (loop alternate @@ -442,7 +448,9 @@ This is an implementation of `foldts' as described by Andy Wingo in (( exps) (fold-values foldts exps seed ...)) (( body) - (foldts body seed ...)) + (if body + (foldts body seed ...) + (values seed ...))) (( inits body alternate) (let-values (((seed ...) (fold-values foldts inits seed ...))) (if alternate @@ -511,7 +519,8 @@ This is an implementation of `foldts' as described by Andy Wingo in (set! (toplevel-define-exp x) (lp exp))) (( body) - (set! (lambda-body x) (lp body))) + (if body + (set! (lambda-body x) (lp body)))) (( inits body alternate) (set! inits (map lp inits)) @@ -595,7 +604,8 @@ This is an implementation of `foldts' as described by Andy Wingo in (set! (toplevel-define-exp x) (lp exp))) (( body) - (set! (lambda-body x) (lp body))) + (if body + (set! (lambda-body x) (lp body)))) (( inits body alternate) (set! inits (map lp inits)) diff --git a/module/language/tree-il/canonicalize.scm b/module/language/tree-il/canonicalize.scm index c3229ca..2fa8c2e 100644 --- a/module/language/tree-il/canonicalize.scm +++ b/module/language/tree-il/canonicalize.scm @@ -1,6 +1,6 @@ ;;; Tree-il canonicalizer -;; Copyright (C) 2011, 2012 Free Software Foundation, Inc. +;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -54,6 +54,21 @@ body) (($ src () () body) body) + (($ src meta #f) + ;; Give a body to case-lambda with no clauses. + (make-lambda + src meta + (make-lambda-case + #f '() #f #f #f '() '() + (make-application + #f + (make-primitive-ref #f 'throw) + (list (make-const #f 'wrong-number-of-args) + (make-const #f #f) + (make-const #f "Wrong number of arguments") + (make-const #f '()) + (make-const #f #f))) + #f))) (($ src tag body handler) (define (escape-only? handler) (match handler diff --git a/module/language/tree-il/cse.scm b/module/language/tree-il/cse.scm index d8c7e3f..b025bcb 100644 --- a/module/language/tree-il/cse.scm +++ b/module/language/tree-il/cse.scm @@ -1,6 +1,6 @@ ;;; Common Subexpression Elimination (CSE) on Tree-IL -;; Copyright (C) 2011, 2012 Free Software Foundation, Inc. +;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -535,8 +535,10 @@ (return (make-application src proc args) (concat db** db*)))) (($ src meta body) - (let*-values (((body _) (visit body (control-flow-boundary db) - env 'values))) + (let*-values (((body _) (if body + (visit body (control-flow-boundary db) + env 'values) + (values #f #f)))) (return (make-lambda src meta body) vlist-null))) (($ src req opt rest kw inits gensyms body alt) diff --git a/module/language/tree-il/debug.scm b/module/language/tree-il/debug.scm index 78f1324..97737c2 100644 --- a/module/language/tree-il/debug.scm +++ b/module/language/tree-il/debug.scm @@ -1,6 +1,6 @@ ;;; Tree-IL verifier -;; Copyright (C) 2011 Free Software Foundation, Inc. +;; Copyright (C) 2011, 2013 Free Software Foundation, Inc. ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -115,10 +115,11 @@ (cond ((and meta (not (and (list? meta) (and-map pair? meta)))) (error "meta should be alist" meta)) - ((not (lambda-case? body)) + ((and body (not (lambda-case? body))) (error "lambda body should be lambda-case" exp)) (else - (visit body env)))) + (if body + (visit body env))))) (($ src names gensyms vals body) (cond ((not (and (list? names) (and-map symbol? names))) diff --git a/module/language/tree-il/effects.scm b/module/language/tree-il/effects.scm index 4610f7f..1fe4aeb 100644 --- a/module/language/tree-il/effects.scm +++ b/module/language/tree-il/effects.scm @@ -1,6 +1,6 @@ ;;; Effects analysis on Tree-IL -;; Copyright (C) 2011, 2012 Free Software Foundation, Inc. +;; Copyright (C) 2011, 2012, 2013 Free Software Foundation, Inc. ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public @@ -315,7 +315,12 @@ of an expression." (cause &type-check)))) (($ ) (logior (compute-effects body) - (cause &type-check)))))) + (cause &type-check))) + (#f + ;; Calling a case-lambda with no clauses + ;; definitely causes bailout. + (logior (cause &definite-bailout) + (cause &possible-bailout)))))) ;; Bailout primitives. (($ src ($ _ (? bailout-primitive? name)) diff --git a/module/language/tree-il/peval.scm b/module/language/tree-il/peval.scm index da3f4a8..bf96179 100644 --- a/module/language/tree-il/peval.scm +++ b/module/language/tree-il/peval.scm @@ -1440,14 +1440,14 @@ top-level bindings from ENV and return the resulting expression." ((operator) exp) (else (record-source-expression! exp - (make-lambda src meta (for-values body)))))) + (make-lambda src meta (and body (for-values body))))))) (($ src req opt rest kw inits gensyms body alt) (define (lift-applied-lambda body gensyms) (and (not opt) rest (not kw) (match body (($ _ ($ _ '@apply) - (($ _ _ lcase) + (($ _ _ (and lcase ($ ))) ($ _ _ sym) ...)) (and (equal? sym gensyms) diff --git a/test-suite/tests/optargs.test b/test-suite/tests/optargs.test index 396fdec..0be1a54 100644 --- a/test-suite/tests/optargs.test +++ b/test-suite/tests/optargs.test @@ -221,7 +221,20 @@ (equal? (transmogrify quote) 10))) +(with-test-prefix/c&e "case-lambda" + (pass-if-exception "no clauses, no args" exception:wrong-num-args + ((case-lambda))) + + (pass-if-exception "no clauses, args" exception:wrong-num-args + ((case-lambda) 1))) + (with-test-prefix/c&e "case-lambda*" + (pass-if-exception "no clauses, no args" exception:wrong-num-args + ((case-lambda*))) + + (pass-if-exception "no clauses, args" exception:wrong-num-args + ((case-lambda*) 1)) + (pass-if "unambiguous" ((case-lambda* ((a b) #t) -- 1.7.10.4 --=-=-= Content-Type: text/plain -- http://wingolog.org/ --=-=-=-- From debbugs-submit-bounces@debbugs.gnu.org Sat Mar 09 05:18:33 2013 Received: (at 9776-done) by debbugs.gnu.org; 9 Mar 2013 10:18:33 +0000 Received: from localhost ([127.0.0.1]:40904 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UEGrH-0004Ni-PZ for submit@debbugs.gnu.org; Sat, 09 Mar 2013 05:18:33 -0500 Received: from a-pb-sasl-quonix.pobox.com ([208.72.237.25]:51048 helo=sasl.smtp.pobox.com) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1UEGrF-0004Na-SL for 9776-done@debbugs.gnu.org; Sat, 09 Mar 2013 05:18:30 -0500 Received: from sasl.smtp.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 4AE5DCF40; Sat, 9 Mar 2013 05:17:47 -0500 (EST) DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; s=sasl; bh=lKW2wLhNjPGHIdBqmz14dSm1zzY=; b=XBqVRh pmBOV0FF02cdFuj6y85jnRjcPDclra3ZFBJwKFNt53cIxXjFg2RBv7mQSwySc6AA ORVR9Jn3Rdvn46PY1RL7awsTcxFndZ9AnoSJdb8aIZGLVnWv+zoQWfctoC591CE+ jw52i/p+cghzFgNHAgKjcSv0O4ZcSjF11UJDc= DomainKey-Signature: a=rsa-sha1; c=nofws; d=pobox.com; h=from:to:cc :subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=sasl; b=L0G1r5CDOAsm+pHFSmyZzonZpxR5gdTw k9LlultGI7et4Lfc5yHrW5tVO17mans4T11enSTjNLzjLbLtlgE7OCsiq/yzX6Dr mP87DxQqAm19NNXy6irm4eD+rTNie/O+OhVY2ID/vLJNRKGvWO1pAtt7/z8iZqmL nqqDWIxeYgw= Received: from a-pb-sasl-quonix.pobox.com (unknown [127.0.0.1]) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTP id 431A8CF3F; Sat, 9 Mar 2013 05:17:47 -0500 (EST) Received: from badger (unknown [88.160.190.192]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by a-pb-sasl-quonix.pobox.com (Postfix) with ESMTPSA id BFDBACF3E; Sat, 9 Mar 2013 05:17:46 -0500 (EST) From: Andy Wingo To: ludo@gnu.org (Ludovic =?utf-8?Q?Court=C3=A8s?=) Subject: Re: bug#9776: case-lambda should accept zero clauses References: <87ty77c4ab.fsf@weinholt.se> <87fwftu7lt.fsf@gnu.org> <87ehvals3q.fsf@Kagami.home> <87k447bhyc.fsf@gnu.org> <87hazbdtuo.fsf@netris.org> <877h04swxe.fsf@gnu.org> <8738wdisam.fsf@pobox.com> Date: Sat, 09 Mar 2013 11:17:44 +0100 In-Reply-To: <8738wdisam.fsf@pobox.com> (Andy Wingo's message of "Sat, 02 Mar 2013 19:13:21 +0100") Message-ID: <87d2v83mif.fsf@pobox.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.2 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-Pobox-Relay-ID: 96B5AD2E-88A2-11E2-B835-59240E5B5709-02397024!a-pb-sasl-quonix.pobox.com X-Spam-Score: -0.6 (/) X-Debbugs-Envelope-To: 9776-done Cc: Ian Price , 9776-done@debbugs.gnu.org, =?utf-8?Q?G=C3=B6ran?= Weinholt X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: debbugs-submit-bounces@debbugs.gnu.org Errors-To: debbugs-submit-bounces@debbugs.gnu.org X-Spam-Score: -2.5 (--) On Sat 02 Mar 2013 19:13, Andy Wingo writes: > Picking up an old thread. What do people think about the attached > patch? It preserves arity checking for case-lambdas defined in the same > compilation unit. Case-lambdas are converted to nullary procedures in > the last minute, before compiling or memoizing. Calling one of these > procedures with arguments will still produce an arity-check warning; > calling one without arguments will not. In both cases a > wrong-number-of-args exception is thrown at runtime (either by the > normal argument count check or via the explicit throw in the body). > > I think allowing lambda-body to be #f is the right way to go because it > precludes inlining of ((case-lambda)). > > I'll push soon if there are no comments. Pushed. Later we can figure out a way to warn for all applications of (case-lambda), regardless of arity. Andy -- http://wingolog.org/ From unknown Sat Aug 16 10:43:30 2025 Received: (at fakecontrol) by fakecontrolmessage; To: internal_control@debbugs.gnu.org From: Debbugs Internal Request Subject: Internal Control Message-Id: bug archived. Date: Sat, 06 Apr 2013 11:24:05 +0000 User-Agent: Fakemail v42.6.9 # This is a fake control message. # # The action: # bug archived. thanks # This fakemail brought to you by your local debbugs # administrator