From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!.POSTED!not-for-mail From: Philipp Stephani Newsgroups: gmane.emacs.devel Subject: Re: Should records be able to mimic primitive types? Date: Fri, 16 Jun 2017 18:42:08 +0000 Message-ID: References: <8777899d-ca8e-212c-b8bf-2f8da4c54836@cs.ucla.edu> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="001a113ce0fa24737f05521825ee" X-Trace: blaine.gmane.org 1497638548 31874 195.159.176.226 (16 Jun 2017 18:42:28 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Fri, 16 Jun 2017 18:42:28 +0000 (UTC) To: Stefan Monnier , emacs-devel@gnu.org Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Fri Jun 16 20:42:24 2017 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 1dLwCN-00081k-Rq for ged-emacs-devel@m.gmane.org; Fri, 16 Jun 2017 20:42:24 +0200 Original-Received: from localhost ([::1]:60314 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dLwCT-00078M-5p for ged-emacs-devel@m.gmane.org; Fri, 16 Jun 2017 14:42:29 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:40838) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dLwCL-000785-R8 for emacs-devel@gnu.org; Fri, 16 Jun 2017 14:42:23 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dLwCK-0005uq-FM for emacs-devel@gnu.org; Fri, 16 Jun 2017 14:42:21 -0400 Original-Received: from mail-oi0-x229.google.com ([2607:f8b0:4003:c06::229]:33551) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1dLwCK-0005uV-93 for emacs-devel@gnu.org; Fri, 16 Jun 2017 14:42:20 -0400 Original-Received: by mail-oi0-x229.google.com with SMTP id s3so28711566oia.0 for ; Fri, 16 Jun 2017 11:42:20 -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; bh=jouF3FiKUiRhVD+vHGRd3uCF6a70qc1FzV3XaYXtHlY=; b=sotHHzRGE5ZgjPzTkad/XbINvjDWnSMlTTJ5upX4x/oRY9HjIMrzwmhXMcuW5ZINtK c/2WS2E+FHnlLEYQX1tcTilas0GBOmiQQp1Dhli9LliRs5ifzEk2Gtpq9c11ASD1yGPX lg5wcst3aQ7T8BF7NROHIvJZk010gcEa7ie2onsYJTGSAHslFaAxWec+e7bWcbTYi8C5 Poft0phdWQxifTmkB3YlGWBiWRbOjN0yiZJiQoEJIr4h/EoqUUV6I52YDWw/XF7XyaK9 LQvNr8qfujOzlvkWPhmOZUk6aH3huyPUb20YuT4g1m0v6YhLenOVebrt/gGSnRLsFM4B FduQ== 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; bh=jouF3FiKUiRhVD+vHGRd3uCF6a70qc1FzV3XaYXtHlY=; b=ovdG+XVEbKoKTQdFNDPhe+5QtBieN+J8LP1zTF291gVBA8zTr5pX7B9rWMSyOa9EmM YejA+ArbbGReJhw/Jop9cI7XJ1m55Ntrvv3q2qbGf2O9OetSNy6kWhSjpHN+gebA36er GYIwjuxTExUDmhjTZmuuzMOvuLrtv7U1GZ/+l81hFBozYY7ZL2RJoNeS8vLo6W7xMxfI DnYtVjInAeBCekdDJ0USGvu5uGaF2GzR+haLjISZVBqh6/IZp8PHqm6vJuNNxuMa49Ms LMn+WC3xjyWb+nz7fNRKVMWVoBcSWrB2P+bP3eI6Md7yAwUour1+x09v6h0HvqPeWosD KAXg== X-Gm-Message-State: AKS2vOygSban78MjgkEqbMh8kkCslZLhg7UkR4cJI9bhtyy2yGpY8qnt C2J2z/ujCjmhiJpmt2rYIdD9Z1nP4A== X-Received: by 10.202.186.195 with SMTP id k186mr299981oif.75.1497638539388; Fri, 16 Jun 2017 11:42:19 -0700 (PDT) In-Reply-To: X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2607:f8b0:4003:c06::229 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:215680 Archived-At: --001a113ce0fa24737f05521825ee Content-Type: text/plain; charset="UTF-8" Stefan Monnier schrieb am Mo., 12. Juni 2017 um 19:41 Uhr: > >> It's not trying hard, just a simple check for a known, small, and > >> rarely-changing list of primitive symbols. > > To me, that's working very hard: > > - extra code. > > - extra maintenance > > - extra run-time checks. > > - no benefit since this doesn't catch a common situation. > > More concretely: what would be a scenario where such a check would > be useful? > > AFAICT, you need all 3 of: > 1- First, you'd need someone to be foolish enough to set his record's > type to be one of the primitive types. This is the actual bug that > your extra check would aim to catch. > Yes, though I wouldn't consider it foolish. make-record can be called indirectly, maybe even from a function that somehow generates the type name. People might try to create records named 'integer' and be happy that that appears to work. > 2- Then you'd need to pass that object to a chunk of code which uses > `type-of` and then checks the result for that primitive type. > Otherwise, the type you set would behave just like any other > non-primitive type so the "bug" would be harmless anyway. > 3- Furthermore, you'd need this object to be manipulated exclusively in > a way which also works with your record object without signaling an > error (e.g. if the primitive type used is `integer`, it means your > object should never be passed to the likes of `+` since otherwise the > bug would already be discovered by `+` without any need for your extra > check). > > I haven't seen any evidence that step 1 will ever occur, even by accident. > I don't care about how often some bug will occur. Rather the contrary: it's the rare bugs that are insidious. People learn about the common ones quickly, but nobody will expect a rare bug, until it arises. > > No idea how likely is step 2. `type-of` is very rarely used (except via > cl-defmethod) so it's fairly unlikely, but possible. > > Step 3 seems again very unlikely in itself, and even more so if step > 2 occurred: if you checked with type-of that your object is of type > `integer` there's a very high likelihood that you're going to then use > operations which only work on integers. > > Will all 3 steps ever occur at the same time? > I don't think this is an important question. The important point is: Previously, there were invariants such as (integerp x) == (eq (type-of x) 'integer) or that prin1 would only generate #s(hash-table ...) for actual hash tables. Now these invariants are broken. But it's critical that invariants are never broken, no matter how unlikely the breakage is. Imagine a system where 1 + 1 = 3 in one trillionth of the executions: even if the bug were rare, that system would be unusable. Even worse, because it is so rare, it is much more disastrous when it happens, because people started relying on the invariant that is "almost" guaranteed. But there's a discontinuity between "invariant is guaranteed" and "invariant is almost always guaranteed": the latter is identical to "invariant is not guaranteed at all". > > Do we really want to make every call to `make-record` pay the extra test > in order to hope to catch this hypothetical case? Yes, absolutely. I don't care whether it's rare or hypothetical, it breaks an invariant, and invariants must not be broken. --001a113ce0fa24737f05521825ee Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Stefan= Monnier <monnier@iro.umontr= eal.ca> schrieb am Mo., 12. Juni 2017 um 19:41=C2=A0Uhr:
>> It's not trying hard, just a simp= le check for a known, small, and
>> rarely-changing list of primitive symbols.
> To me, that's working very hard:
> - extra code.
> - extra maintenance
> - extra run-time checks.
> - no benefit since this doesn't catch a common situation.

More concretely: what would be a scenario where such a check would
be useful?

AFAICT, you need all 3 of:
1- First, you'd need someone to be foolish enough to set his record'= ;s
=C2=A0 =C2=A0type to be one of the primitive types.=C2=A0 This is the actua= l bug that
=C2=A0 =C2=A0your extra check would aim to catch.

=
Yes, though I wouldn't consider it foolish. make-record can = be called indirectly, maybe even from a function that somehow generates the= type name. People might try to create records named 'integer' and = be happy that that appears to work.
=C2=A0
2- Then you'd need to pass that object to a chunk of code which uses =C2=A0 =C2=A0`type-of` and then checks the result for that primitive type.<= br> =C2=A0 =C2=A0Otherwise, the type you set would behave just like any other =C2=A0 =C2=A0non-primitive type so the "bug" would be harmless an= yway.
3- Furthermore, you'd need this object to be manipulated exclusively in=
=C2=A0 =C2=A0a way which also works with your record object without signali= ng an
=C2=A0 =C2=A0error (e.g. if the primitive type used is `integer`, it means = your
=C2=A0 =C2=A0object should never be passed to the likes of `+` since otherw= ise the
=C2=A0 =C2=A0bug would already be discovered by `+` without any need for yo= ur extra
=C2=A0 =C2=A0check).

I haven't seen any evidence that step 1 will ever occur, even by accide= nt.

I don't care about how often so= me bug will occur. Rather the contrary: it's the rare bugs that are ins= idious. People learn about the common ones quickly, but nobody will expect = a rare bug, until it arises.
=C2=A0

No idea how likely is step 2.=C2=A0 `type-of` is very rarely used (except v= ia
cl-defmethod) so it's fairly unlikely, but possible.

Step 3 seems again very unlikely in itself, and even more so if step
2 occurred: if you checked with type-of that your object is of type
`integer` there's a very high likelihood that you're going to then = use
operations which only work on integers.

Will all 3 steps ever occur at the same time?

I don't think this is an important question. The important point= is: Previously, there were invariants such as (integerp x) =3D=3D (eq (typ= e-of x) 'integer) or that prin1 would only generate #s(hash-table ...) = for actual hash tables. Now these invariants are broken. But it's criti= cal that invariants are never broken, no matter how unlikely the breakage i= s. Imagine a system where 1=C2=A0+ 1 =3D 3 in one trillionth of the executi= ons: even if the bug were rare, that system would be unusable. Even worse, = because it is so rare, it is much more disastrous when it happens, because = people started relying on the invariant that is "almost" guarante= ed. But there's a discontinuity between "invariant is guaranteed&q= uot; and "invariant is almost always guaranteed": the latter is i= dentical to "invariant is not guaranteed at all".
=C2= =A0

Do we really want to make every call to `make-record` pay the extra test in order to hope to catch this hypothetical case?

Yes, absolutely. I don't care whether it's rare or hypotheti= cal, it breaks an invariant, and invariants must not be broken.=C2=A0
=
--001a113ce0fa24737f05521825ee--