220 32143 <bacbf6b9-06a8-4f30-b8f0-74a85a875191@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: David Peterson <djpeterson83@hotmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Idea: New Language Feature for Safer, Easier Optional Access
Date: Sat, 22 Apr 2017 14:23:52 -0700 (PDT)
Lines: 202
Approved: news@gmane.org
Message-ID: <bacbf6b9-06a8-4f30-b8f0-74a85a875191@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1129_1663349901.1492896232193"
X-Trace: blaine.gmane.org 1492896233 26924 195.159.176.226 (22 Apr 2017 21:23:53 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sat, 22 Apr 2017 21:23:53 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBC2O5JM7VUCBB2MT57DQKGQEYEM4ZNI@isocpp.org Sat Apr 22 23:23:48 2017
Return-path: <std-proposals+bncBC2O5JM7VUCBB2MT57DQKGQEYEM4ZNI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yb0-f197.google.com ([209.85.213.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBC2O5JM7VUCBB2MT57DQKGQEYEM4ZNI@isocpp.org>)
	id 1d22VQ-0006r6-2r
	for gclcip-std-proposals@m.gmane.org; Sat, 22 Apr 2017 23:23:48 +0200
Original-Received: by mail-yb0-f197.google.com with SMTP id p143sf42545455yba.13
        for <gclcip-std-proposals@m.gmane.org>; Sat, 22 Apr 2017 14:23:54 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:subject:mime-version:x-original-sender
         :reply-to:precedence:mailing-list:list-id:x-spam-checked-in-group
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe;
        bh=lsHN48dpewpDTZncYBcupBsMelssrOlh4yhkFBa7eSs=;
        b=wYl56oW7EEkZlsRvdItwrYPCtEsRhUhwjQRz9r9NE8rzrulsQGkTg3IOXj/LQnWGte
         KRqOqfhljwiZhfeWRgQ5XFqxExpcVOeKVj7+cxStu6k/FgYLVEVJfHHwywvgF6kbM+62
         KUiCEF8LT8osri2i9nQr2y4RSBYa85ULcU7GBk3Ni+HdjJpMrlE9eMkzs4t1IJpu05iD
         5wqX6a/nz3LCcxmdtEVzWLqJQxNpYtN5orICnjFiOUHToc9HL3X1njAV3Whi01om1aAm
         8f22SwpeYlMKy2nWl11E9spPy2j/oiZydCCafyrvSlLkIwlg/Tn4P869ciCAAosy3A1t
         EZsQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=lsHN48dpewpDTZncYBcupBsMelssrOlh4yhkFBa7eSs=;
        b=JtoZfzY/C4RzYESi338Kq8aCFjf9vyp+IcJ7Ft/NMtY/guhtBZFMJNdMv+WiJmrJCB
         cjVCIphbWgE8+geBd/bKIjYmtOF5fKIsOIctJtoq1fHpYP+0pWLGhWRRbuUYMkovQDq/
         uy4KQPu+w8ZIXwDh6wn0+VeYpmX3h1Z21txFEmOv5bZYjV3gfZIoU+a1cebG/1DR1P3M
         AZYoXNA7AXM0MIqquSpErd4e7iHZf6xx97HPO2qWKgDngSR2u7UMV/w4Uo3t7l8paV/X
         iDMG0MfjL5N4LK+fC0Qxu+EejuCtRPrRwkWV+QO/YhX64RTi/+1Xl2MRt1BP0mZyvZQL
         r6iw==
X-Gm-Message-State: AN3rC/4DhlyHnwTDVf1qVvJs8LIjQeiK0hFTLQ2vacilPpbOEVrewguk
	a9uTPL7Xinjjww==
X-Received: by 10.129.80.86 with SMTP id e83mr9482908ywb.141.1492896233593;
        Sat, 22 Apr 2017 14:23:53 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.16.125 with SMTP id o58ls11169552oto.15.gmail; Sat, 22 Apr
 2017 14:23:52 -0700 (PDT)
X-Received: by 10.157.26.98 with SMTP id u31mr415881otu.0.1492896232733;
        Sat, 22 Apr 2017 14:23:52 -0700 (PDT)
X-Original-Sender: djpeterson83@hotmail.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: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://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>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:32143
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32143>

------=_Part_1129_1663349901.1492896232193
Content-Type: multipart/alternative; 
	boundary="----=_Part_1130_1259922149.1492896232193"

------=_Part_1130_1259922149.1492896232193
Content-Type: text/plain; charset=UTF-8

Hi Everyone, this is my first time floating an idea so apologies if I get 
the format wrong.  Constructive criticism is very welcome!

I've had a look at the new std::optional<T> and as exciting as it is to 
finally have such a useful type in the standard, I worry that the feature 
may be too cumbersome and possibly too easy to use incorrectly.  Here's an 
example of its current usage as provided by the C++ 17 standard:

// C++ 17 New Optional Usage //
if (auto customer = get_customer(customer_id)) {
    process(*customer);
}
else {
    show_customer_not_found();
}

This isn't too bad, but I think it could be better.  The first issue I have 
is with `customer` being an actual std::optional instance.  This creates a 
level of indirection that seems awkward to use.  One must also remember to 
dereference the `customer` optional when attempting to gain access to the 
value as can be seen during the `process` call.  It would be nice to remove 
this indirection and gain direct access to the underlying type rather than 
through the optional itself.  After some thinking, I realized that the 
range-based for loop had the solution I was looking for.  Essentially, an 
optional is a list containing either no items or exactly one item.  In such 
a case, one could think of iterating over an optional as if it were a 
simple container:

// Example of an optional as if it were a container of one or zero items //
for (auto& customer : get_customer(customer_id)) {
    process(customer);
}

Obviously, this syntax is a bit awkward.  It just doesn't make sense to 
consider an optional as a container.  Furthermore, there would likely be a 
high degree of unnecessary overhead in interpreting the optional as a 
container.  Iterators would also have to be made to support the begin/end 
range.  To correct these shortcomings, my proposal is to extend the 
range-based for loop syntax for single instance item which may or may not 
exist (optionals and pointers, primarily) to the `if` statement.  Here is 
an example:

// New way with `if` auto-dereferencing language feature //
if (auto& customer : get_customer(customer_id)) {
    process(customer); // customer is a Customer& and not an optional.
                       // We can safely use customer as we are guaranteed
                       // to have a valid reference and that reference
                       // cannot extend beyond the `if` scope
}
else {
    show_customer_not_found();
}

As you can see, this feature is readable and addresses the indirection 
problem from earlier.  Furthermore, it can be optimized easier for optional 
types and can theoretically work with any type, including user types, so 
long as they provide a conversion to boolean operator and a dereference 
operator.  An example of how this could be interpreted follows:

// New feature translates into... //
auto _optional_customer = get_customer(customer_id);
if (_optional_customer) {
    auto& customer = *_optional_customer;
    process(customer);
}
else {
    show_customer_not_found();
}

I'm sure language features are not the easiest thing to add, and I'm no 
compiler developer, but I'm anxious to hear any feedback you may have in 
regards to short comings, enhancements and overall complexity to implement. 
 Thank you for considering this feature. - David Peterson

-- 
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 email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/bacbf6b9-06a8-4f30-b8f0-74a85a875191%40isocpp.org.

------=_Part_1130_1259922149.1492896232193
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hi Everyone, this is my first time floating an idea so apo=
logies if I get the format wrong. =C2=A0Constructive criticism is very welc=
ome!<div><br></div><div>I&#39;ve had a look at the new std::optional&lt;T&g=
t; and as exciting as it is to finally have such a useful type in the stand=
ard, I worry that the feature may be too cumbersome and possibly too easy t=
o use incorrectly. =C2=A0Here&#39;s an example of its current usage as prov=
ided by the C++ 17 standard:</div><div><br></div><div><div style=3D"color: =
rgb(212, 212, 212); background-color: rgb(30, 30, 30); font-family: Consola=
s, &quot;Courier New&quot;, monospace; font-size: 14px; line-height: 19px;"=
><div><span style=3D"color: #608b4e;">//=C2=A0C++=C2=A017=C2=A0New=C2=A0Opt=
ional Usage //</span></div><div><span style=3D"color: #c586c0;">if</span>=
=C2=A0(<span style=3D"color: #569cd6;">auto</span>=C2=A0customer=C2=A0=3D=
=C2=A0get_customer(customer_id))=C2=A0{</div><div>=C2=A0=C2=A0=C2=A0=C2=A0<=
span style=3D"color: #dcdcaa;">process</span>(*customer);</div><div>}</div>=
<div><span style=3D"color: #c586c0;">else</span>=C2=A0{</div><div>=C2=A0=C2=
=A0=C2=A0=C2=A0<span style=3D"color: #dcdcaa;">show_customer_not_found</spa=
n>();</div><div>}</div></div></div><div><br></div><div>This isn&#39;t too b=
ad, but I think it could be better. =C2=A0The first issue I have is with `c=
ustomer` being an actual std::optional instance. =C2=A0This creates a level=
 of indirection that seems awkward to use. =C2=A0One must also remember to =
dereference the `customer` optional when attempting to gain access to the v=
alue as can be seen during the `process` call. =C2=A0It would be nice to re=
move this indirection and gain direct access to the underlying type rather =
than through the optional itself. =C2=A0After some thinking, I realized tha=
t the range-based for loop had the solution I was looking for. =C2=A0Essent=
ially, an optional is a list containing either no items or exactly one item=
.. =C2=A0In such a case, one could think of iterating over an optional as if=
 it were a simple container:</div><div><br></div><div><div style=3D"color: =
rgb(212, 212, 212); background-color: rgb(30, 30, 30); font-family: Consola=
s, &quot;Courier New&quot;, monospace; font-size: 14px; line-height: 19px;"=
><div><span style=3D"color: #608b4e;">//=C2=A0Example=C2=A0of=C2=A0an=C2=A0=
optional=C2=A0as=C2=A0if=C2=A0it=C2=A0were=C2=A0a=C2=A0container=C2=A0of=C2=
=A0one=C2=A0or=C2=A0zero=C2=A0items=C2=A0//</span></div><div><span style=3D=
"color: #c586c0;">for</span>=C2=A0(<span style=3D"color: #569cd6;">auto</sp=
an>&amp;=C2=A0customer=C2=A0:=C2=A0get_customer(customer_id))=C2=A0{</div><=
div>=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color: #dcdcaa;">process</span>(=
customer);</div><div>}</div></div></div><div><br></div><div>Obviously, this=
 syntax is a bit awkward. =C2=A0It just doesn&#39;t make sense to consider =
an optional as a container. =C2=A0Furthermore, there would likely be a high=
 degree of unnecessary overhead in interpreting the optional as a container=
.. =C2=A0Iterators would also have to be made to support the begin/end range=
.. =C2=A0To correct these shortcomings, my proposal is to extend the range-b=
ased for loop syntax for single instance item which may or may not exist (o=
ptionals and pointers, primarily) to the `if` statement. =C2=A0Here is an e=
xample:</div><div><br></div><div><div style=3D"color: rgb(212, 212, 212); b=
ackground-color: rgb(30, 30, 30); font-family: Consolas, &quot;Courier New&=
quot;, monospace; font-size: 14px; line-height: 19px;"><div><div style=3D"l=
ine-height: 19px;"><div><span style=3D"color: #608b4e;">//=C2=A0New=C2=A0wa=
y=C2=A0with=C2=A0`if` auto-dereferencing language=C2=A0feature=C2=A0//</spa=
n></div><div><span style=3D"color: #c586c0;">if</span>=C2=A0(<span style=3D=
"color: #569cd6;">auto</span>&amp;=C2=A0customer=C2=A0:=C2=A0get_customer(c=
ustomer_id))=C2=A0{</div><div>=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color:=
 #dcdcaa;">process</span>(customer);=C2=A0<span style=3D"color: #608b4e;">/=
/=C2=A0customer=C2=A0is=C2=A0a=C2=A0Customer&amp;=C2=A0and=C2=A0not=C2=A0an=
=C2=A0optional.</span></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0<span style=3D"color: #608b4e;">//=C2=A0We=C2=A0can=C2=
=A0safely=C2=A0use=C2=A0customer=C2=A0as=C2=A0we=C2=A0are=C2=A0guaranteed</=
span></div><div>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0<span style=3D"color: #608b4e;">//=C2=A0to=C2=A0have=C2=A0a=C2=A0vali=
d=C2=A0reference=C2=A0and=C2=A0that=C2=A0reference</span></div><div>=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"col=
or: #608b4e;">//=C2=A0cannot=C2=A0extend=C2=A0beyond=C2=A0the `if` scope</s=
pan></div><div>}</div><div><span style=3D"color: #c586c0;">else</span>=C2=
=A0{</div><div>=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color: #dcdcaa;">show=
_customer_not_found</span>();</div><div>}</div></div></div></div></div><div=
><br></div><div>As you can see, this feature is readable and addresses the =
indirection problem from earlier. =C2=A0Furthermore, it can be optimized ea=
sier for optional types and can theoretically work with any type, including=
 user types, so long as they provide a conversion to boolean operator and a=
 dereference operator. =C2=A0An example of how this could be interpreted fo=
llows:</div><div><br></div><div><div style=3D"color: rgb(212, 212, 212); ba=
ckground-color: rgb(30, 30, 30); font-family: Consolas, &quot;Courier New&q=
uot;, monospace; font-size: 14px; line-height: 19px;"><div><span style=3D"c=
olor: #608b4e;">//=C2=A0New=C2=A0feature=C2=A0translates=C2=A0into...=C2=A0=
//</span></div><div><span style=3D"color: #569cd6;">auto</span>=C2=A0_optio=
nal_customer=C2=A0=3D=C2=A0get_customer(customer_id);</div><div><span style=
=3D"color: #c586c0;">if</span>=C2=A0(_optional_customer)=C2=A0{</div><div>=
=C2=A0=C2=A0=C2=A0=C2=A0<span style=3D"color: #569cd6;">auto</span>&amp;=C2=
=A0customer=C2=A0=3D=C2=A0*_optional_customer;</div><div>=C2=A0=C2=A0=C2=A0=
=C2=A0<span style=3D"color: #dcdcaa;">process</span>(customer);</div><div>}=
</div><div><span style=3D"color: #c586c0;">else</span>=C2=A0{</div><div>=C2=
=A0=C2=A0=C2=A0=C2=A0<span style=3D"color: #dcdcaa;">show_customer_not_foun=
d</span>();</div><div>}</div></div></div><div><br></div><div>I&#39;m sure l=
anguage features are not the easiest thing to add, and I&#39;m no compiler =
developer, but I&#39;m anxious to hear any feedback you may have in regards=
 to short comings, enhancements and overall complexity to implement. =C2=A0=
Thank you for considering this feature. - David Peterson</div></div>

<p></p>

-- <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 />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/bacbf6b9-06a8-4f30-b8f0-74a85a875191%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/bacbf6b9-06a8-4f30-b8f0-74a85a875191=
%40isocpp.org</a>.<br />

------=_Part_1130_1259922149.1492896232193--

------=_Part_1129_1663349901.1492896232193--

.
