220 18423 <54f37450-b427-432b-b2ab-14be88d8782f@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Thoughts on Exceptions, Expected, and Error Handling
Date: Fri, 5 Jun 2015 10:44:26 -0700 (PDT)
Lines: 346
Approved: news@gmane.org
Message-ID: <54f37450-b427-432b-b2ab-14be88d8782f@isocpp.org>
References: <b171ba85-b2cf-436a-9fa6-11525c186498@isocpp.org> <E6F01357-3E18-4695-A437-3F9E4F1CDA9F@gmail.com> <db5fa95d-24a0-4aef-9413-db739deacf9e@isocpp.org>
 <5AB7DB18-04CE-432A-8B20-E922A0D5CABA@gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1343_1862999950.1433526266026"
X-Trace: ger.gmane.org 1433526297 25376 80.91.229.3 (5 Jun 2015 17:44:57 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Fri, 5 Jun 2015 17:44:57 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCEKFTV6ZUMBB657Y6VQKGQEFPU675A@isocpp.org Fri Jun 05 19:44:57 2015
Return-path: <std-proposals+bncBCEKFTV6ZUMBB657Y6VQKGQEFPU675A@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-qc0-f198.google.com ([209.85.216.198])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBB657Y6VQKGQEFPU675A@isocpp.org>)
	id 1Z0vfa-0008Nz-Oo
	for gclcip-std-proposals@m.gmane.org; Fri, 05 Jun 2015 19:44:39 +0200
Original-Received: by qczw4 with SMTP id w4sf58732466qcz.2
        for <gclcip-std-proposals@m.gmane.org>; Fri, 05 Jun 2015 10:44:27 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :content-type:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=xzyxuaNDBxkKfsspRkFgiXifJfyN3G8cJ0Vzl85AAfc=;
        b=yrAxBTcFxrEK1IzGwhW1MqChCsJFXRaYSGbmxldLTm50p4x/Po3oOl5pWh6h/Rjk6D
         vYhYK+T3x7Vv4dCb2kqtFwAyMLKS5mXttZXRgsXOjS7hBOWxB6WI2fEiFtaQnOxSGc4O
         OrxaI3OYWQTKR2ZOlG8b0TVs2aHVvUGn+hdseV5IwafcNW6yWPCDbE5xwLjAgYzxAQAk
         7Swd+atH4LOrV+P9oCuEXmvumk9p+IRN+MZlhEGZRQ/ruGZzDVMQjWkiO7mYRrPazGAA
         e83voVttT8oFweeq0kUYUg0+qmuekmqwF1o/Ph11lit0tE4Znn9SRkQnt97r8Ex4YG2m
         Qh0w==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:content-type:x-original-sender:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=xzyxuaNDBxkKfsspRkFgiXifJfyN3G8cJ0Vzl85AAfc=;
        b=FitcmZkabXYXQEQhxFdOVozzKhDF3vVTbTSNi4XxKD2gwxyiDerH2OKUgSJd0MyOlK
         J27KITkjf28r/UXMuRYmZd3NKqDFSPJcnpqEvZt0EudhaaUVop7BCuK9Q7yJKE3m0P84
         lv2b/RotZN6gA1ecO1aNB13A2DoiyEt28pgVAXgCnUgV2x6pmaI9EtDDyfZ3IDNAr2MF
         CBKmdwVDaOSTJOiaqTmYFpQZSwevhAa8ZWfnYRzFr5FiaBHcz8QGEKikvTXhPmIzGBpO
         SpIsJQ+UNDfJLSoO0pXpKdvEYLmSb2VbxkXK58ZhcgK9wV9goaWzShE10oF0Fh+sDl9z
         9jiQ==
X-Gm-Message-State: ALoCoQmXn0rhVKng9kKDtkg9yRwOhim3zjYkflysubAwzkQgnZloz6DDqpWWQGOInm76fDRYvZiy
X-Received: by 10.52.33.104 with SMTP id q8mr5353734vdi.1.1433526267501;
        Fri, 05 Jun 2015 10:44:27 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.140.16.178 with SMTP id 47ls1592725qgb.89.gmail; Fri, 05 Jun
 2015 10:44:26 -0700 (PDT)
X-Received: by 10.140.19.76 with SMTP id 70mr60607qgg.21.1433526266934;
        Fri, 05 Jun 2015 10:44:26 -0700 (PDT)
In-Reply-To: <5AB7DB18-04CE-432A-8B20-E922A0D5CABA@gmail.com>
X-Original-Sender: jmckesson@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:18423
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/18423>

------=_Part_1343_1862999950.1433526266026
Content-Type: multipart/alternative; 
	boundary="----=_Part_1344_1128586390.1433526266026"

------=_Part_1344_1128586390.1433526266026
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Thursday, June 4, 2015 at 5:02:44 AM UTC-4, Nicola Gigante wrote:
>
>
> > Il giorno 03/giu/2015, alle ore 23:01, Nicol Bolas <jmck...@gmail.com=
=20
> <javascript:>> ha scritto:=20
> >=20
> > Agreed.=20
> >=20
> >=20
> > You... do? The entire rest of your post seems to disagree.=20
> >=20
>
> You=E2=80=99re right, I should have replied with more details on the thre=
e points=20
>
> > That all brings me to a number of conclusions:=20
> >=20
> > 1) Exceptions work best in non-local error handling contexts. Local=20
> error handling best works via `expected`, except where `expected` cannot =
be=20
> used or is poor at the job.=20
> >=20
>
> I believe what you call =E2=80=9Cnon local=E2=80=9D is what I=E2=80=99d r=
ecognize as a consequence=20
> of the presence of IO actions=20
> and thus we agree that nonlocal errors are best handled with exceptions.
>
Everything else is =E2=80=9Clocal=E2=80=9D in the sense that, in the spirit=
 of striving to=20
> have as much total pure functions as possible,=20
>
 I don=E2=80=99t want to make my functions to affect anything other than th=
eir=20
> return values and (since we=E2=80=99re in C++) some controlled and precis=
ely=20
> defined piece of state (for example the object instance of a member=20
> function call).=20
>
> In that sense I agree with your dichotomy: exceptions for out-of-band=20
> error reporting, and expected (or optional) to just=20
> locally represent the absence of a return value (e.g. turning a partial=
=20
> function into a total one by adding an element to its range)=20
>

What I call "non local" is exactly that: non-local. "Local" is the=20
immediate caller of a function; "non-local" is everyone else. To handle an=
=20
error locally means that the process continues on, from the perspective of=
=20
the outside world. To handle the error non-locally means that part of the=
=20
process has to stop, and control must be returned to some higher level code=
=20
to deal with it.

By these definitions, locality is defined *by the user*, not by the nature=
=20
of the error. So your arbitrary decision that IO errors are non-local is=20
wrong. It's a misinterpretation of what I'm saying, through your functional=
=20
programming lens. You want locality of error handling to be decided by a=20
fundamental property of the error in question. I am explicitly saying that=
=20
this is *wrong*; it should be decided *by the user*, not some ad-hoc rule.

> 2) The difference between local and non-local handling cannot be known to=
=20
> the library. It may guess and hope, but there are usually legitimate case=
s=20
> where a user might handle errors one way or the other.=20
> >=20
>
> There are always legitimate cases where the user could want to do=20
> anything.=20
> Even in Haskell there are legitimate cases to break purity using=20
> unsafePerformIO,=20
> so I don=E2=80=99t think we can talk about C++ without taking into accoun=
t the=20
> corner cases.=20
> The language should encourage best practices, and make bad practices to=
=20
> require=20
> explicit action, but not make them truly impossible.
>

You're still missing my point. You are unilaterally deciding that IO errors=
=20
ought to be exceptions and parse errors ought to be `expected`. The point=
=20
of my conclusion #2 is that *the API has no right to make that decision for=
=20
the user*.

Consider the following. I'm building a system that writes video data. And I=
=20
have to support outdated filesystems that have maximum file sizes. Which=20
means that I write to a file until I can't write anymore, then create a new=
=20
file and write to that. The way to do that is to attempt to expand the=20
file's size when writing the next block of data. If the file's size cannot=
=20
be expanded, then I open a new file and write to that. This all happens in=
=20
a loop.

For me, an error in expanding the file's size is, um, expected; it is not=
=20
an exceptional circumstance. I ought to be able to use an `expected`=20
interface or some other local error handling mechanism (since expanding a=
=20
file's size probably doesn't return a value), rather than an=20
exception-based one. Yes, other IO errors (creating new files, writing the=
=20
actual data) will probably be exceptions that have to stop the whole=20
process.

But why deny the proper error handling mechanism for this case? Why should=
=20
the user be denied the choice?

This is why trying to graft functional programming nonsense into C++ is a=
=20
bad idea. Functional programming makes a distinction between IO errors and=
=20
other errors because it ultimately has no choice. The very idea of=20
input/output is decidedly outside the scope of the functional model. Thus,=
=20
allowing functional programming to work with input/output requires breaking=
=20
that model. Because these operations work outside of the functional model,=
=20
errors reported through them cannot be handled in the usual functional way=
=20
of handling errors. Therefore, it must use something else.

C++ is not a functional language, nor should it become one. C++ is more=20
free-form in terms of programming style, and it should not adopt constructs=
=20
that force you into decisions like this. Where you have to use exceptions=
=20
in some circumstance, because to do otherwise breaks the box you've=20
deliberately chosen to live within.

If you want to live inside the functional programming box, if you want to=
=20
decide to handle all IO errors as exceptions, fine. But don't force the=20
rest of us in there with you.
=20

> > 3) Where possible, allow the user to decide whether errors are handled=
=20
> locally or not. As such, functions that error should have two versions: o=
ne=20
> that throws and one that uses `expected`.=20
> >=20
> > You all but stated that having a parsing system throw exceptions was a=
=20
> priori the wrong way to deal with them.=20
> >=20
> > And yet, you agree that libraries, including parsing libraries, should=
=20
> offer both interfaces where possible? Why do you agree with that?=20
>
> This is not a general design principle.


Then you don't agree, because what I'm saying is that it *should be* a=20
"general design principle." For all error types, all things being equal,=20
both should be allowed. I say this not to support !C++ users who turn off=
=20
exception handling, not to support functional-programming-in-C++ users. But=
=20
simply to allow C++ programmers of all kinds to determine how best to=20
handle each individual error: locally or non-locally.

It is just not a choice that an API has the right to make.

--=20

---=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposa=
ls/.

------=_Part_1344_1128586390.1433526266026
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Thursday, June 4, 2015 at 5:02:44 AM UTC-4, Nicola Giga=
nte wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
<br>&gt; Il giorno 03/giu/2015, alle ore 23:01, Nicol Bolas &lt;<a href=3D"=
javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"7lCsBEXliXkJ" rel=
=3D"nofollow" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">jmck...@gmail.com</a>&gt; ha s=
critto:
<br>&gt;=20
<br>&gt; Agreed.
<br>&gt;=20
<br>&gt;=20
<br>&gt; You... do? The entire rest of your post seems to disagree.
<br>&gt;=20
<br>
<br>You=E2=80=99re right, I should have replied with more details on the th=
ree points
<br>
<br>&gt; That all brings me to a number of conclusions:
<br>&gt;=20
<br>&gt; 1) Exceptions work best in non-local error handling contexts. Loca=
l error handling best works via `expected`, except where `expected` cannot =
be used or is poor at the job.
<br>&gt;=20
<br>
<br>I believe what you call =E2=80=9Cnon local=E2=80=9D is what I=E2=80=99d=
 recognize as a consequence of the presence of IO actions
<br>and thus we agree that nonlocal errors are best handled with exceptions=
..<br></blockquote><div><blockquote class=3D"gmail_quote" style=3D"margin: 0=
;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">Everyth=
ing else is =E2=80=9Clocal=E2=80=9D in the sense that, in the spirit of str=
iving to have as much total pure functions as possible,&nbsp;<br></blockquo=
te></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: =
0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">&nbsp;I don=E2=80=99t=
 want to make my functions to affect anything other than their=20
return values and (since we=E2=80=99re in C++) some controlled and precisel=
y defined piece of state (for example the object instance of a member funct=
ion call).
<br>
<br>In that sense I agree with your dichotomy: exceptions for out-of-band e=
rror reporting, and expected (or optional) to just=20
<br>locally represent the absence of a return value (e.g. turning a partial=
 function into a total one by adding an element to its range)
<br></blockquote><div><br>What I call "non local" is exactly that: non-loca=
l.
 "Local" is the immediate caller of a function; "non-local" is everyone=20
else. To handle an error locally means that the process continues on,=20
from the perspective of the outside world. To handle the error=20
non-locally means that part of the process has to stop, and control must
 be returned to some higher level code to deal with it.<br><br>By these def=
initions, locality is defined <i>by the user</i>, not by the nature of the =
error. So your arbitrary decision that IO errors are non-local is wrong. It=
's a misinterpretation of what I'm saying, through your functional programm=
ing lens. You want locality of error handling to be decided by a fundamenta=
l property of the error in question. I am explicitly saying that this is <i=
>wrong</i>; it should be decided <i>by the user</i>, not some ad-hoc rule.<=
br><br></div><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-le=
ft: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">
&gt; 2) The difference between local and non-local handling cannot be known=
 to the library. It may guess and hope, but there are usually legitimate ca=
ses where a user might handle errors one way or the other.
<br>&gt;=20
<br>
<br>There are always legitimate cases where the user could want to do anyth=
ing.
<br>Even in Haskell there are legitimate cases to break purity using unsafe=
PerformIO,
<br>so I don=E2=80=99t think we can talk about C++ without taking into acco=
unt the corner cases.
<br>The language should encourage best practices, and make bad practices to=
 require
<br>explicit action, but not make them truly impossible.<br></blockquote><d=
iv><br>You're still missing my point. You are unilaterally deciding that IO=
 errors ought to be exceptions and parse errors ought to be `expected`. The=
 point of my conclusion #2 is that <i>the API has no right to make that dec=
ision for the user</i>.<br><br>Consider the following. I'm building a syste=
m that writes video data. And I have to support outdated filesystems that h=
ave maximum file sizes. Which means that I write to a file until I can't wr=
ite anymore, then create a new file and write to that. The way to do that i=
s to attempt to expand the file's size when writing the next block of data.=
 If the file's size cannot be expanded, then I open a new file and write to=
 that. This all happens in a loop.<br><br>For me, an error in expanding the=
 file's size is, um, expected; it is not an exceptional circumstance. I oug=
ht to be able to use an `expected` interface or some other local error hand=
ling mechanism (since expanding a file's size probably doesn't return a val=
ue), rather than an exception-based one. Yes, other IO errors (creating new=
 files, writing the actual data) will probably be exceptions that have to s=
top the whole process.<br><br>But why deny the proper error handling mechan=
ism for this case? Why should the user be denied the choice?<br><br>This is=
 why trying to graft functional programming nonsense into C++ is a bad idea=
.. Functional programming makes a distinction between IO errors and other er=
rors because it ultimately has no choice. The very idea of input/output is =
decidedly outside the scope of the functional model. Thus, allowing functio=
nal programming to work with input/output requires breaking that model. Bec=
ause these operations work outside of the functional model, errors reported=
 through them cannot be handled in the usual functional way of handling err=
ors. Therefore, it must use something else.<br><br>C++ is not a functional =
language, nor should it become one. C++ is more free-form in terms of progr=
amming style, and it should not adopt constructs that force you into decisi=
ons like this. Where you have to use exceptions in some circumstance, becau=
se to do otherwise breaks the box you've deliberately chosen to live within=
..<br><br>If you want to live inside the functional programming box, if you =
want to decide to handle all IO errors as exceptions, fine. But don't force=
 the rest of us in there with you.<br>&nbsp;</div><blockquote class=3D"gmai=
l_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;=
padding-left: 1ex;">&gt; 3) Where possible, allow the user to decide whethe=
r errors are handled locally or not. As such, functions that error should h=
ave two versions: one that throws and one that uses `expected`.
<br>&gt;=20
<br>&gt; You all but stated that having a parsing system throw exceptions w=
as a priori the wrong way to deal with them.
<br>&gt;=20
<br>&gt; And yet, you agree that libraries, including parsing libraries, sh=
ould offer both interfaces where possible? Why do you agree with that?
<br>
<br>This is not a general design principle.</blockquote><div><br>Then you d=
on't agree, because what I'm saying is that it <i>should be</i> a "general =
design principle." For all error types, all things being equal, both should=
 be allowed. I say this not to support !C++ users who turn off exception ha=
ndling, not to support functional-programming-in-C++ users. But simply to a=
llow C++ programmers of all kinds to determine how best to handle each indi=
vidual error: locally or non-locally.<br><br>It is just not a choice that a=
n API has the right to make.<br></div></div>

<p></p>

-- <br />
<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_1344_1128586390.1433526266026--
------=_Part_1343_1862999950.1433526266026--

.
