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: [PATCH] Accept plists when serializing and parsing JSON Date: Sat, 2 Jun 2018 09:45:53 +0200 Message-ID: References: <87sh6awls5.fsf@gmail.com> NNTP-Posting-Host: blaine.gmane.org Mime-Version: 1.0 Content-Type: multipart/alternative; boundary="0000000000008c4262056da3e470" X-Trace: blaine.gmane.org 1527925450 29199 195.159.176.226 (2 Jun 2018 07:44:10 GMT) X-Complaints-To: usenet@blaine.gmane.org NNTP-Posting-Date: Sat, 2 Jun 2018 07:44:10 +0000 (UTC) Cc: =?UTF-8?B?Sm/Do28gVMOhdm9yYQ==?= , Emacs developers To: Yuri Khan Original-X-From: emacs-devel-bounces+ged-emacs-devel=m.gmane.org@gnu.org Sat Jun 02 09:44:06 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 1fP1Cn-0007VU-14 for ged-emacs-devel@m.gmane.org; Sat, 02 Jun 2018 09:44:05 +0200 Original-Received: from localhost ([::1]:58629 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fP1Et-0007fB-TO for ged-emacs-devel@m.gmane.org; Sat, 02 Jun 2018 03:46:15 -0400 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:56713) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fP1El-0007ep-Ct for emacs-devel@gnu.org; Sat, 02 Jun 2018 03:46:08 -0400 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fP1Ek-000350-3e for emacs-devel@gnu.org; Sat, 02 Jun 2018 03:46:07 -0400 Original-Received: from mail-oi0-x242.google.com ([2607:f8b0:4003:c06::242]:44679) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1fP1Ej-000344-S7 for emacs-devel@gnu.org; Sat, 02 Jun 2018 03:46:06 -0400 Original-Received: by mail-oi0-x242.google.com with SMTP id c128-v6so15152341oig.11 for ; Sat, 02 Jun 2018 00:46:05 -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=CSido9H4sz+zYRlR7uG+Brbf2UZmdRSTanJ/GGSnYYA=; b=Gz8A+5Vf4Lf1V+ygPHROxzwdAQNuR3MmtLXbViFAuA/YmdHwIr96rTpH/Ppxpui3E2 btQpnIqlVyWUdJo3Kw5CxBHO3rKh9ZU3PZZmXniLzr7mGLbRn3SaGEytTVAgi1Rxmead GYccOFE47NouIF6N48Sc14AW1kvtSUza2wpu5TaoYPztesqCtmB+OT++ACtfaQJg7sM1 1M/tVly5eikWkZsWGbUkHgxCtGqdmyPBMOU1WFe4sHUQqI3kRgdqIExR5xK6liQ/xvOu qwoI+mWKEiigpLVVrHcNyWqOR+MV0liBsKCycxnaxeWi3WR9J/PrRnwICMSd5RAo+Iw8 wjjw== 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=CSido9H4sz+zYRlR7uG+Brbf2UZmdRSTanJ/GGSnYYA=; b=YIpy+J6zQ+beiynB94kOVF3g46XTGVhBKsjkGCaeJyh7YEnDXwK44edHF8grjeKZ+y Qx8zxboJ5e7umYvjo9QIcjnsj1XMqoMBY83C/j7BrztAgowo/BmSIjnVTM94nm5QW9TE kYiynDT74fMl5GQ9IjYI9WFsWBseKCecVKY/+0a1eCmq6xmerz1L7+ItIAzq/3M6KOgl pVYuz1+DbhNas7VsjJlPwiQQRKJIGNa8U/1L8Q2yRDeBR/xStd82dTwhRijwiDiWo5cQ If6/u/CuJaQHgVTnV2yw/GQ0HIwCi6miPPUaiG8uc5T+6uDZ54VVBl7VgVMiBxygaCyW ulGA== X-Gm-Message-State: APt69E27KPWFHTQxVJW+dnbnVGdQpYfU96LF7Yvmo7hB9qg2n3aQfkC4 +HU8Z1joRQH4k2CHr4re/TjJ/fRZ8otgzevqKKM= X-Google-Smtp-Source: ADUXVKKWZLEpRZtJCWc4xn3xrjniKqRlqeXkWobJhcnAUcZUuVr96AdaP2FSn/MLYwZWXJt+QMnu7Mn8KoJZsyUL+C0= X-Received: by 2002:aca:c314:: with SMTP id t20-v6mr7267421oif.341.1527925565045; Sat, 02 Jun 2018 00:46:05 -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::242 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:225913 Archived-At: --0000000000008c4262056da3e470 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Yuri Khan schrieb am Mi., 30. Mai 2018 um 08:37 Uhr: > On Wed, May 30, 2018 at 5:31 AM Jo=C3=A3o T=C3=A1vora wrote: > > > On Tue, May 29, 2018, 22:21 Philipp Stephani > wrote: > > >> Please don't add global state to json.c. It's a low-level library that > shouldn't rely on global state (and global state should generally be > avoided in libraries). Not having global state was one of my explicit > design goals for json.c > > > Well, it's not really "global state" in the sense I believe you're > talking about, because no part of the library is maintaining any state in > global variables -- it's read-only from json.c. > > I think the objection to global state (or a global setting, as the case m= ay > be) can be illustrated with the following scenario. > > * Consider two independent Elisp packages =E2=80=98foo=E2=80=99 and =E2= =80=98bar=E2=80=99, both of which > want to use the JSON library. > * =E2=80=98foo=E2=80=99 wants plists while =E2=80=98bar=E2=80=99 wants al= ists. > * =E2=80=98foo=E2=80=99 has a hook. The user adds to that hook a function= that invokes > =E2=80=98bar=E2=80=99. > * Result (after ironing out all bugs related to shared state): Every call > to the JSON library has to be wrapped in a (let ((json-serialize-use-plis= ts > =E2=80=A6)) =E2=80=A6), which is more cumbersome than just passing an arg= ument to a > function. > Yes, exactly. Any dynamic variable is effectively a hidden parameter. That's much worse than an explicit parameter because you have to remember that it's a parameter and explicitly bind it on every call. Consider the Java equivalent: class Json { public static Object deserialize(String json) { ... } // uses useHashtables public static bool useHashtables =3D false; } Very few people would consider such an interface good style: there's a subtle interaction between deserialize and useHashtables, and all callers need to be aware of the interaction. But interfaces should be easy to use correctly and hard to use incorrectly, and this interface is easy to use incorrectly and hard to use correctly. BTW, This has nothing to do with Java or ELisp, but is generally true for all (imperative) programming languages: avoid mutable global state, avoid "action at a distance" (seemingly unrelated parts of the code influencing each other). For ELisp, this means: avoid introducing dynamic variables if possible. --0000000000008c4262056da3e470 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable


Yuri K= han <yurivkhan@gmail.com> = schrieb am Mi., 30. Mai 2018 um 08:37=C2=A0Uhr:
On Wed, May 30, 2018 at 5:31 AM Jo=C3=A3o T=C3=A1vora <joaotavora@gmail.com= > wrote:

> On Tue, May 29, 2018, 22:21 Philipp Stephani <p.stephani2@gmail.com>
wrote:

>> Please don't add global state to json.c. It's a low-level = library that
shouldn't rely on global state (and global state should generally be avoided in libraries). Not having global state was one of my explicit
design goals for json.c

> Well, it's not really "global state" in the sense I beli= eve you're
talking about, because no part of the library is maintaining any state in global variables -- it's read-only from json.c.

I think the objection to global state (or a global setting, as the case may=
be) can be illustrated with the following scenario.

* Consider two independent Elisp packages =E2=80=98foo=E2=80=99 and =E2=80= =98bar=E2=80=99, both of which
want to use the JSON library.
* =E2=80=98foo=E2=80=99 wants plists while =E2=80=98bar=E2=80=99 wants alis= ts.
* =E2=80=98foo=E2=80=99 has a hook. The user adds to that hook a function t= hat invokes
=E2=80=98bar=E2=80=99.
* Result (after ironing out all bugs related to shared state): Every call to the JSON library has to be wrapped in a (let ((json-serialize-use-plists=
=E2=80=A6)) =E2=80=A6), which is more cumbersome than just passing an argum= ent to a
function.

Yes, exactly. Any dynamic var= iable is effectively a hidden parameter. That's much worse than an expl= icit parameter because you have to remember that it's a parameter and e= xplicitly bind it on every call.
Consider the Java equivalent:

class Json {
=C2=A0 public static Object d= eserialize(String json) { ... }=C2=A0 // uses useHashtables
=C2= =A0 public static bool useHashtables =3D false;
}

<= /div>
Very few people would consider such an interface good style: ther= e's a subtle interaction between deserialize and useHashtables, and all= callers need to be aware of the interaction. But interfaces should be easy= to use correctly and hard to use incorrectly, and this interface is easy t= o use incorrectly and hard to use correctly. BTW, This has nothing to do wi= th Java or ELisp, but is generally true for all (imperative) programming la= nguages: avoid mutable global state, avoid "action at a distance"= (seemingly unrelated parts of the code influencing each other). For ELisp,= this means: avoid introducing dynamic variables if possible.
--0000000000008c4262056da3e470--