From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Klaus-Dieter Bauer Newsgroups: gmane.emacs.devel Subject: Re: Can the byte-compiler check whether functions passed by name are defined? Date: Wed, 31 Jul 2013 15:44:39 +0200 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary=20cf3071ced422520804e2ceefc4 X-Trace: ger.gmane.org 1375278654 20959 80.91.229.3 (31 Jul 2013 13:50:54 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 31 Jul 2013 13:50:54 +0000 (UTC) Cc: emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Wed Jul 31 15:50:56 2013 Return-path: Envelope-to: ged-emacs-devel@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1V4Wnj-00030q-NJ for ged-emacs-devel@m.gmane.org; Wed, 31 Jul 2013 15:50:51 +0200 Original-Received: from localhost ([::1]:58291 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4Wnj-0001eO-9k for ged-emacs-devel@m.gmane.org; Wed, 31 Jul 2013 09:50:51 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:41383) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4WnU-0001dG-Dj for emacs-devel@gnu.org; Wed, 31 Jul 2013 09:50:48 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V4WnO-0004t3-OB for emacs-devel@gnu.org; Wed, 31 Jul 2013 09:50:36 -0400 Original-Received: from mail-vb0-x22c.google.com ([2607:f8b0:400c:c02::22c]:58528) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4WiE-0002eo-JR for emacs-devel@gnu.org; Wed, 31 Jul 2013 09:45:10 -0400 Original-Received: by mail-vb0-f44.google.com with SMTP id e13so699182vbg.31 for ; Wed, 31 Jul 2013 06:45:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=2ICEgr3fumzcnpEKf5CkRXKLXZnYm44I2QF77Muj+Xw=; b=furcBRFex6EeLXi5VkRw/WGOfeZ+dMJEP33GAeYDkQPGAWJeHsoNgut9OmdBqVM4tL JFzdxwVO7PgYLwN+bSU83jLkXqY+aBFN+raVmBCts7slao/k41Rwv2Ea9Ge9fkNPJx8r dlvggLpyGWnJJOgi8QabZDrgYcFzoufjFYBc/KDWrdt2B/ABNzy+Hi9rF94vt/8M9qBL vxhrmTfP7z4HwOIzd9Q4v/oVRtfUL2ffANWnBByVsdN3F/gz+/e1D38KCYIci26Z5JQF zcdpzzK4xQQiePkssFmbgHXr5poVUW884o4QhwwbX59agaJDO71hVrFfrje4oR+KIVij hnCw== X-Received: by 10.52.75.4 with SMTP id y4mr1235985vdv.118.1375278309984; Wed, 31 Jul 2013 06:45:09 -0700 (PDT) Original-Received: by 10.220.38.194 with HTTP; Wed, 31 Jul 2013 06:44:39 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:400c:c02::22c X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "Emacs development discussions." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Original-Sender: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.devel:162292 Archived-At: --20cf3071ced422520804e2ceefc4 Content-Type: text/plain; charset=UTF-8 2013/7/29 Stefan Monnier > > (mapcar 'my-function-1 some-list)? > > We could do it for symbols quoted with #' but not for quoting with '. > > Stefan > #' would allow checking for a defined function independent of the function, the function is oassed to, true... Would require however to change coding practice to using this syntax, with the advantage of preventing warnings when people don't want the check but the disadvantage, that the warning is also supressed when people just don't care. I guess it would still be the best solution, that is backward compatible though. Another possibilty (probably less good though): (eval-and-compile (put 'mapcar 'compiler-macro (lambda (&rest form) (let ((function (nth 1 form))) (when (and (macroexp--compiling-p) (listp function) (= 2 (length function)) (member (nth 0 function) '(function quote)) (symbolp (nth 1 function)) (not (fboundp (nth 1 function)))) (warn "Function not know to be defined: %S" (nth 1 function)))) (car form)))) (mapcar 'message '("Hello" "World")) (mapcar 'foobar '("Foo" "Bar")) Some caveats here: 1. Has to be done, though maybe through a macro, for every higher-order function. 2. `compiler-macro' doesn't seem to be documented anywhere. The arguments the function gets passed seem to differ from case to case... 3. (warn) doesn't emit warnings to the compilation buffer but to the separate *Warnings* buffer, making this code only a prrof-of-concept without practical value. 4. If the quoted funciton is defined in the same file as the higher-order function it is passed to, the definition of the quoted function must be both before the first use of the function and inside an (eval-and-compile ..) block, which can only be prevented by changes to the compiler code anyway. kind regards, Klaus --20cf3071ced422520804e2ceefc4 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable
2013/7/29 Stefan Monnier <monnier@iro.umontreal.ca= >
> =C2=A0 =C2=A0 (mapcar 'my-function-1 some-list)?

We could do it for symbols quoted with #' but not for quoting with '= ;.

=C2=A0 =C2=A0 =C2=A0 =C2=A0 Stefan

#'= ; would allow checking for a defined function independent of the function, = the function is oassed to, true... Would require however to change coding p= ractice to using this syntax, with the advantage of preventing warnings whe= n people don't want the check but the disadvantage, that the warning is= also supressed when people just don't care. I guess it would still be = the best solution, that is backward compatible though.=C2=A0

Another pos= sibilty (probably less good though):

=C2=A0 =C2=A0 (eval-and-compile=C2=A0
=C2=A0 =C2=A0 =C2=A0 (put 'mapcar 'compiler-m= acro=C2=A0
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0(lambda (&rest form)
=C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(let ((function (nth 1 form)))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0(when (and (macroexp--compiling-p)
<= span class=3D"" style=3D"white-space:pre"> =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0(listp function)
=C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 (=3D 2 (length function))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (member (nth 0 function) '(f= unction quote))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (symbolp (n= th 1 function))
=C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (not (fboun= dp (nth 1 function))))
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0(warn "Function not know to be defined: %S" (nth 1 = function))))
=C2=A0 =C2=A0 (car form))))
=C2=A0 =C2=A0=C2=A0
=C2=A0 =C2=A0 (mapcar &= #39;message '("Hello" "World"))
=C2=A0 =C2=A0 (mapcar 'foobar '("Foo" "= Bar"))

Some caveats here:
1. Has to be done, though maybe through a macro, for every hig= her-order function.
2. `compiler-macro'= doesn't seem to be documented anywhere. The arguments the function get= s passed seem to differ from case to case...=C2=A0
3. (warn) doesn't emit warnings to the compi= lation buffer but to the separate *Warnings* buffer, making this code only = a prrof-of-concept without practical value.
4. If the quoted funciton is defined in the same file as the higher-order f= unction it is passed to, the definition of the quoted function must be both= before the first use of the function and inside an (eval-and-compile ..) b= lock, which can only be prevented by changes to the compiler code anyway.

kind regard= s, Klaus
--20cf3071ced422520804e2ceefc4--