unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Daniel Colascione <dancol@dancol.org>
To: Stefan Monnier <monnier@IRO.UMontreal.CA>
Cc: emacs-devel@gnu.org
Subject: Re: [Emacs-diffs] trunk r117002: Correctly treat progn contents as toplevel forms when byte compiling
Date: Mon, 21 Apr 2014 21:46:58 -0700	[thread overview]
Message-ID: <5355F442.6080606@dancol.org> (raw)
In-Reply-To: <jwv8uqym46i.fsf-monnier+emacsdiffs@gnu.org>

[-- Attachment #1: Type: text/plain, Size: 4286 bytes --]

On 04/21/2014 09:25 PM, Stefan Monnier wrote:
>>> That's not the kind of example I was thinking if.  Do you have a real
>>> example, maybe?
>> Try writing a macro that emits a defstruct, then a function that uses
>> cl-typep for that struct, all wrapped in the same toplevel progn.
> 
> That's getting closer to an actual example.  I still can't think of
> a case where you'd want to use cl-typep in this way, tho.

cl-struct-slot-value uses typep  It makes sense to do so given that
cl-struct-slot-value knows the name of the struct, but not necessarily
the name of its predicate function --- which might not even exist.

The chunk below is from the iface code I'm working on. This code isn't
even close to done --- it's just here to give you a sense of the
problem. You see that we declare a structure, then emit some functions
that use the structure. Some of these functions go on to do things with
values that are allegedly of the structure type, and they use typep to
check that these values are actually of the struct type. This approach
is a perfectly logical way to go about writing code, and we should
support it. Forcing users to do something else is especially pernicious
because the problem we're discussing only shows up when compiling (or
loading) files --- in normal interactive development, everything seems fine!

(eval-and-compile
  (defun iface--make-member-wrapper (iface-name member)
    "Create a lisp form defining an interface accessor.
IFACE-NAME is a symbol giving the name of the interface being
defined.  MEMBER is an element of the MEMBERS parameter to
`iface-declare'."
    (cl-destructuring-bind ((member-name inst-arg &rest xarglist)
                            &optional doc) member
      (unless (and inst-arg
                   (symbolp inst-arg)
                   (not (eql (aref (symbol-name inst-arg) 0) ?\&)))
        (error (concat "Interface members must accept an instance as"
                       " their first argument")))
      `(defun ,member-name (,inst-arg &rest xargs)
         ,doc
         (declare (advertised-calling-convention (,inst-arg ,@xarglist)
                                                 ,emacs-version))
         (apply (cl-struct-slot-value ',iface-name ',member-name ,inst-arg)
                ,inst-arg xargs)))))

(cl-defmacro iface-declare ((name base) &rest members)
  "Create a new interface called NAME, inheriting from BASE.
MEMBERS is a list of member specifiers.  Each is a list of the form
 ((NAME . ARGUMENTS) DOCUMENTATION), where NAME is a symbol
naming the interface member, ARGUMENTS is a cl-lib-style argument
list, and DOCUMENTATION is documentation to attach to that
function."
  (let ((doc (and (stringp (car members)) (pop members)))
        (prefix (concat (symbol-name name) "--iface-")))
    `(progn
       (cl-defstruct (,name (:include ,base)
                            (:conc-name ,(intern prefix))
                            (:copier nil))
         ,@(if doc (list doc))
         ,@(mapcar #'caar members))
       ,@(mapcar (lambda (member)
                   (iface--make-member-wrapper name member))
                 members)
       ',name)))

>> The reason we have automated tests is to make sure we can maintain this
>> "level of detail". That it's not immediately useful to you isn't a
>> reason not to include it. I can't believe this issue is even
>> contentious: the current behavior is a clear bug.
> 
> It's a clear bug if we assume Common-Lisp semantics.  But in many cases,
> Elisp chooses to provide simpler semantics, to allow a simpler and/or
> more naive implementation.

I don't care whether we diverge from CL in sets of supported features
and names of functions, but we should try hard to match CL's fundamental
execution semantics. Practically every possible bad lisp idea was tried
before Common Lisp came around. The CL people knew about the precise
problem we're discussing on this thread and codified the best solution
in the language. There are solutions in CL for problems that we haven't
even encountered yet. The less closely we follow CL, the less we benefit
from the experience baked into the specification and the harder it is to
fix problems that eventually do come up.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 884 bytes --]

  reply	other threads:[~2014-04-22  4:46 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <E1WcAcP-0006zy-MJ@vcs.savannah.gnu.org>
2014-04-21 15:09 ` [Emacs-diffs] trunk r117002: Correctly treat progn contents as toplevel forms when byte compiling Stefan Monnier
2014-04-21 17:44   ` Daniel Colascione
2014-04-21 22:09     ` Stefan Monnier
2014-04-21 22:29       ` Daniel Colascione
2014-04-22  2:09         ` Stefan Monnier
2014-04-22  2:21           ` Daniel Colascione
2014-04-22  4:25             ` Stefan Monnier
2014-04-22  4:46               ` Daniel Colascione [this message]
2014-04-22 15:06                 ` Stefan Monnier
2014-04-22 17:22                   ` Daniel Colascione
2014-04-22 18:13                     ` Daniel Colascione
2014-04-22 18:37                       ` Stefan Monnier
2014-04-22 19:08                         ` Daniel Colascione
2014-04-22 18:44                       ` Drew Adams
2014-04-22 19:23                         ` Daniel Colascione
2014-04-22 19:59                           ` Drew Adams
2014-04-22 20:10                             ` Daniel Colascione
2014-04-22 20:41                               ` Drew Adams
2014-04-22 21:05                                 ` Daniel Colascione
2014-04-23  0:50                                 ` Stephen J. Turnbull
2014-04-22 18:29                     ` Stefan Monnier
2014-04-22 15:20                 ` Stefan Monnier
2014-04-22 17:04                   ` Daniel Colascione

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5355F442.6080606@dancol.org \
    --to=dancol@dancol.org \
    --cc=emacs-devel@gnu.org \
    --cc=monnier@IRO.UMontreal.CA \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).