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: Mon, 5 Aug 2013 10:52:43 +0200 Message-ID: References: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: ger.gmane.org 1375692801 19195 80.91.229.3 (5 Aug 2013 08:53:21 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Mon, 5 Aug 2013 08:53:21 +0000 (UTC) Cc: Sebastian Wiesner , emacs-devel@gnu.org To: Stefan Monnier Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Mon Aug 05 10:53:24 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 1V6GXb-0001U7-BE for ged-emacs-devel@m.gmane.org; Mon, 05 Aug 2013 10:53:23 +0200 Original-Received: from localhost ([::1]:56821 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6GXb-00005K-16 for ged-emacs-devel@m.gmane.org; Mon, 05 Aug 2013 04:53:23 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37541) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6GXV-0008Vo-Mz for emacs-devel@gnu.org; Mon, 05 Aug 2013 04:53:21 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V6GXS-0002ke-AD for emacs-devel@gnu.org; Mon, 05 Aug 2013 04:53:17 -0400 Original-Received: from mail-vb0-x22d.google.com ([2607:f8b0:400c:c02::22d]:49663) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V6GXS-0002kZ-5Y for emacs-devel@gnu.org; Mon, 05 Aug 2013 04:53:14 -0400 Original-Received: by mail-vb0-f45.google.com with SMTP id e15so2549079vbg.32 for ; Mon, 05 Aug 2013 01:53:13 -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=3PV0Nc3DFIudy0fIE4hD5aAR+aaeMjWT84A9cG5AQuU=; b=MHfEBs6IZTL3lX4lvplAcV62zlcm4cwhFUx17J3rT9hGgu213dSA7xYQYJTwH1IMxD bKTFOnUwHx+fPgNSA0cRhJcM+vrSwFUgqvxAsgOZ1yC7hgO/ehpBnEwDinn2ZabtLwmQ nx7uznHtotu12l54yS4gnz1Blg/2kOn2vkWSu+9g6Ke+6UyAojAPBSI/TR+tg9cKkeAd 68fCIQ4BI+Cm1yeMtoG7/EpM/2HhcFA9kdilaax8uU3oVfUtTtgVhvOcGcT56MPqUnnB 6nCHynxkkriWQt6+ZKe2jgNehsMrCp0lHvHnW9hvKNRUrSxX0S8wGmSCNVU2LiOHuvEH q52Q== X-Received: by 10.58.146.196 with SMTP id te4mr5484936veb.62.1375692793682; Mon, 05 Aug 2013 01:53:13 -0700 (PDT) Original-Received: by 10.220.38.194 with HTTP; Mon, 5 Aug 2013 01:52:43 -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::22d 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:162428 Archived-At: 2013/8/4 Stefan Monnier : > > As mentioned, the best option is to start by adding warnings for the > #'symbol form (should be easy: handle it in the same way we handle > warnings for function calls). > > Then make the higher-order functions turn 'symbol into #'symbol. > That's important for things like > > (if foo #'a #'b) > I am not sure I understand what you have in mind. Is the following snippet such a case? (mapcar (if flag 'f1 'f2) list) => (mapcar (if flag #'f1 #'f2) list) I don't see much point in that, because I don't like the notion that the above code behaves different from (defun select-function (flag f) (if flag f 'default-f)) ... (mapcar (select-function flag 'f1) alist) In my implementation still warnings would be created if the programmer explicitly writes #'f1, #'f2 in `select-function', which I suppose would happen with yours too. Handling cases like computed function names seems fairly complex -- what about e.g. (mapcar (catch 'function (dolist (f function-list) (when (PREDICATE f) (throw 'function f))) 'default-function) list) When the simple if-case generates a warning, naively I'd expect this to generate a warning too, but I'd expect it to become impossibly complex then. > Sadly, I defined the `compiler-macro' declaration to take a function > rather than an exp that returns a function, so you can't just > write a function macroexp--rewrite-function-arguments and then use: > > (defun my-combine (func1 func2) > (declare (compiler-macro (macroexp--rewrite-function-arguments 0 1))) > > But you can do something like > > (defun my-combine (func1 func2) > (declare (compiler-macro > (lambda (body) > (macroexp--rewrite-function-arguments > body (rewrite func1) (rewrite func2))))) > > (defun my-mapcar (func list) > (declare (compiler-macro > (lambda (body) > (macroexp--rewrite-function-arguments > body (rewrite func) list)))) > > Still, this annotation is only needed to turn a ' into a #', so it's not > the most important. Shouldn't the markup for user-written functions be a bit easier? Something along the lines of using a list of positions (like specified by my declare form) and having the rewriting, if any, done inside byte-compile-normal-call or whichever function would be the correct place. Especially since `compiler-macro' seems to be undocumented... >> I couldn't define the handler in "byte-run.el" however, as when I added it >> to the declaration of `defun-declaration-alist', it would suddenly be >> missing again during compilation. > > Probably because you didn't re-dump Emacs (byte-run.el is preloaded > into the `emacs' executable so if you change it, you need to rebuild > `emacs'). Indeed I did not, since I did not expect this behaviour. Rebuilding emacs is fairly slow on windows, so I didn't even think of this possibility. Anyway, I find the behaviour confusing. Having code preloaded into the binary is okay, but having code in installation directory that is ignored even when it has been changed seems a bit awkward. Or IS it loaded when changed and just didn't change `defun-declaration-alist', because it is bound already before loading the changed byte-code? - Klaus