From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= Newsgroups: gmane.emacs.devel Subject: Re: Changing a cl-defstruct definition in a published package Date: Fri, 13 Jul 2018 18:01:29 +0100 Message-ID: References: <9afc36c6-5759-6ea0-4cd4-9d6eb6b073b5@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="0000000000000b75de0570e46ff8" X-Trace: blaine.gmane.org 1531501212 26466 195.159.176.226 (13 Jul 2018 17:00:12 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 13 Jul 2018 17:00:12 +0000 (UTC) Cc: emacs-devel To: =?UTF-8?Q?Cl=C3=A9ment_Pit=2DClaudel?= Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Jul 13 19:00:08 2018 Return-path: Envelope-to: ged-emacs-devel@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 1fe1QN-0006ma-IX for ged-emacs-devel@m.gmane.org; Fri, 13 Jul 2018 19:00:07 +0200 Original-Received: from localhost ([::1]:38440 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fe1SU-0006Nr-NT for ged-emacs-devel@m.gmane.org; Fri, 13 Jul 2018 13:02:18 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:48612) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fe1Rv-0006Nm-RA for emacs-devel@gnu.org; Fri, 13 Jul 2018 13:01:45 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fe1Ru-0007aQ-IU for emacs-devel@gnu.org; Fri, 13 Jul 2018 13:01:43 -0400 Original-Received: from mail-it0-x22e.google.com ([2607:f8b0:4001:c0b::22e]:51728) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fe1Ru-0007ZO-A6 for emacs-devel@gnu.org; Fri, 13 Jul 2018 13:01:42 -0400 Original-Received: by mail-it0-x22e.google.com with SMTP id h2-v6so10595053itj.1 for ; Fri, 13 Jul 2018 10:01:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=1cs/s7KUYZnl6Kn02iYN9ZLJEsuSvtPhX4Dk0JRJdmM=; b=lh0svvSk6TfHNUANaazU4MhT0yfQCEQXgk8Ldi/w2aU9nPseiWin7zfZkSAwo2vJiI 8GrZlusKV8UuKyXOvdINvJvu56QWvjabiRpU87AB1Pts/XutrOiPV3EAzSfd7SGs51Yk 7KbZprc0YhaTAqwVYY0auQkZief2PRerq/BbpSKk4xQ/9m8qxM5vpnEE8xtlgP+wpBU0 iwKadhyuvI1eyEOaJZV3xMlnsL/ecBxNkiWTQBsnHuYGGbhCzx2oc6DtMuMEmX4GlVXp njhSqUlG7hdQhy3P6vALmAwl8Eo2VUqFxmDK8DYFL61Fm3CO3dXwC1xf8GWJH+LRZjB6 5Qbg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=1cs/s7KUYZnl6Kn02iYN9ZLJEsuSvtPhX4Dk0JRJdmM=; b=nMmmSezVdDuuWQhErtjoNpbwrMchDZm6PN3KAeB4wuOS3qHHRjwman+DyKd6QOk3jL ObRmnzZ3UgCgoCnFbqOW0Mpg3184OG0O4E8O3XqUm9ej2SNhXtRosPb5z6dDc/qHhvCw mwntgY82ySba8E9hiGjkEjRczyLALXwNVEoCexsGyEAe0viNsv7l7ytY7lGgIfbBMz9L bGbfUwsZQ2AVZWHLwJP0tmY2zrutC9JGiN+36Y7L3O+1jD6h4ukkzCaWfLkIJelf4GKc WB5MKbWofNNjYKGmSYmgfe3fi/H1QGFxxH0Afus8foc53INCrwF2/OlhOx4Ep7RHCn85 t6dQ== X-Gm-Message-State: AOUpUlHYeRwiZQTGlEMEjyLC5tdZhrqHfsvZm7HSNh3suxOWRCUJXtjm IVtZA2Q4lvk/LMmtObae9r6HQWuNGnPZmnAGFZE= X-Google-Smtp-Source: AAOMgpfY0pbinZmLQvk2YIvEcQcfsdE+hk2wXJ0CiATbukRFBby/MW7fUPTUK6qbE0M040TMeDJid5H0vtnEy40dz3s= X-Received: by 2002:a24:e4cf:: with SMTP id o198-v6mr5244941ith.21.1531501301427; Fri, 13 Jul 2018 10:01:41 -0700 (PDT) In-Reply-To: <9afc36c6-5759-6ea0-4cd4-9d6eb6b073b5@gmail.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4001:c0b::22e X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.1.21 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" Xref: news.gmane.org gmane.emacs.devel:227351 Archived-At: --0000000000000b75de0570e46ff8 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Thu, Jul 12, 2018, 21:13 Cl=C3=A9ment Pit-Claudel wrote: > Hi all, > > I'm sure this has already been discussed, but I couldn't find the relevan= t > discussion. I'm running into issues trying to update a package without > breaking other packages that depend on it. Advice would be very welcome. > > I maintain package A, which contains this: > > (cl-defstruct aaa-info > line message) > > (provide 'aaa) > > Someone else wrote a package B that contains this: > > (require 'aaa) > > (defun bbb-print-message (info) > (message (aaa-info-message info))) > > (provide 'bbb) > > Users have installed both packages through package.el. I update A by > adding a new field to the definition of aaa-info, and push the update to > ELPA or MELPA: > > (cl-defstruct aaa-info > line column message) > > Users update using package.el, but this does not cause b to be > recompiled. From this point on, any subsequent call to bbb-print-message > to bbb-print-message fails: for example, (bbb-print-message (make-aaa-inf= o > :line 1 :column 2 :message "XYZ")) prints this: > > Debugger entered--Lisp error: (wrong-type-argument stringp 2) > message(2) > bbb-print-message(#s(aaa-info :line 1 :column 2 :message "XYZ")) > > Similarly, if I update the constructor of aaa-info to give the new > 'column' field a default value, instances created by the > previously-compiled B will still be missing the 'column' slot, leading to > all sorts of errors. > > What is the recommended way to change a cl-defstruct definition without > running into these issues? > > Thanks! > Cl=C3=A9ment. > Hi Cl=C3=A9ment, There's no way to fix the problem now without breaking backward compatibility because by now B's use of your accessor has been compiled into something that probably looks like an aref into an array. So if you change your object layout in A, you break a compiled B. The way to avoid this beforehand is not to expose the defstruct's accessors as a public interface. You can't think of them as functions, because they have compiler macros associated. The easiest "solution" now is to make proper functions for those accessors that are public, and then having B recompiled. Also consider if you really need defstructs for their speed, because they're usually an array in disguise. Perhaps a (slightly, in most cases) slower eieio class would do. Jo=C3=A3o --0000000000000b75de0570e46ff8 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
On Thu, = Jul 12, 2018, 21:13 Cl=C3=A9ment Pit-Claudel <cpitclaudel@gmail.com> wrote:
Hi all,

I'm sure this has already been discussed, but I couldn't find the r= elevant discussion.=C2=A0 I'm running into issues trying to update a pa= ckage without breaking other packages that depend on it.=C2=A0 Advice would= be very welcome.

I maintain package A, which contains this:

=C2=A0 (cl-defstruct aaa-info
=C2=A0 =C2=A0 line message)

=C2=A0 (provide 'aaa)

Someone else wrote a package B that contains this:

=C2=A0 (require 'aaa)

=C2=A0 (defun bbb-print-message (info)
=C2=A0 =C2=A0 (message (aaa-info-message info)))

=C2=A0 (provide 'bbb)

Users have installed both packages through package.el.=C2=A0 I update A by = adding a new field to the definition of aaa-info, and push the update to EL= PA or MELPA:

=C2=A0 (cl-defstruct aaa-info
=C2=A0 =C2=A0 line column message)

Users update using package.el, but this does not cause b to be recompiled.= =C2=A0 From this point on, any subsequent call to bbb-print-message to bbb-= print-message fails: for example, (bbb-print-message (make-aaa-info :line 1= :column 2 :message "XYZ")) prints this:

=C2=A0 Debugger entered--Lisp error: (wrong-type-argument stringp 2)
=C2=A0 =C2=A0 message(2)
=C2=A0 =C2=A0 bbb-print-message(#s(aaa-info :line 1 :column 2 :message &quo= t;XYZ"))

Similarly, if I update the constructor of aaa-info to give the new 'col= umn' field a default value, instances created by the previously-compile= d B will still be missing the 'column' slot, leading to all sorts o= f errors.

What is the recommended way to change a cl-defstruct definition without run= ning into these issues?

Thanks!
Cl=C3=A9ment.

Hi Cl=C3=A9ment,

There's= no way to fix the problem now without breaking backward compatibility beca= use by now B's use of your accessor has been compiled into something th= at probably looks like an aref into an array.=C2=A0 So if you change your o= bject layout in A, you break a compiled B.

The way to avoid this beforehand is not to expose the defstruct&#= 39;s accessors as a public interface.=C2=A0 You can't think of them as = functions, because they have compiler macros associated.=C2=A0 The easiest = "solution" now is to make proper functions for those accessors th= at are public, and then having B recompiled.=C2=A0 Also consider if you rea= lly need defstructs for their speed, because they're usually an array i= n disguise.=C2=A0 Perhaps a (slightly, in most cases) slower eieio class wo= uld do.=C2=A0

<= /div>
Jo=C3=A3o
--0000000000000b75de0570e46ff8--