Topic: Informal request for comments: Overloadable switch statements


Author: Sean Hunt <scshunt@csclub.uwaterloo.ca>
Date: Thu, 6 Nov 2014 15:14:17 -0800 (PST)
Raw View
------=_Part_431_1369292159.1415315657772
Content-Type: text/plain; charset=UTF-8

Hey fellow language geeks,

I vaguely recall that, a long time ago, I submitted a similar proposal to
comp.std.c++ to lukewarm reception, but I can't dig it up and the language
and process have evolved a lot, so I figured it might be interesting to see
what current people think.

Currently, there is no thrust towards getting a relaxed switch statement
into the language, but the EWG did express some interest in continuing with
N3627,[1] which proposes a much more restricted version than I propose here.

The general concept is to allow a fully overloadable switch operator. The
inspiration comes from Perl's experimental smart match operator,[2] which
is designed to make the code "do the right thing" in the context of a
switch.

The first component is the addition of a new overloadable operator name. We
could use a magic name function name like begin() and end(), but that's
really a bikeshedding problem and doesn't affect the substance of the
proposal, I think.

The new operator, "operator switch", must return bool and take exactly two
arguments (optionally, we could allow a one-argument member form as well).
As an example, we might have:

bool operator switch(const std::regex& re, const std::string &s) {
    return regex_match(s, re, std::match_any);
}

The use of this operator is straightforward. switch(s) { case e: ; } is
roughly translated to "if (operator switch(e, s)) ; ". In case of multiple
possible matches, the first one is chosen. Existing switch behaviour is
implemented with implicit overload candidates, as with built-in operators.

So as an example, assuming a UDL for regexes exists, you could do:

switch (some_long_string) {
case "(a )?colou?red house"_regex:
    std::cout << "coloured house";
    break;
case "(a )?house"_regex:
    std::cout << "house";
    break;
default:
    std::cout << "dunno";
    break;
}

Rather than have "default" mean "true", I would rather preserve the
existing behaviour that default is fallen back onto whenever none of the
case expressions match.

The biggest potential issue with this is reuse of conversions. Because new
expressions need to be evaluated on the matching expression, there is no
consistent way to minimize conversions like the current switch does (where
a value is converted to integer type only once). In the above example, if
some_long_string is not a string, but is convertible to one, is the
conversion called multiple times? Perhaps it could be unspecified whether a
conversion function is called more than once in the evaluation of a
switch---this would help ensure that implementations can continue to use
optimizations like jump tables for builtin types. Other options may include
requiring explicit specification of the type ("switch std::string
(some_long_string)"), which, if not specified, gives the non-overloaded
switch behaviour ("switch auto(e)" could be used for getting the new
behaviour with the type of e) or restricting the implicit conversions that
can be performed.

Thoughts?

Sean

[1]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3627.html
[2]: http://perldoc.perl.org/perlop.html#Smartmatch-Operator

--

---
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_431_1369292159.1415315657772
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Hey fellow language geeks,<div><br></div><div>I vaguely re=
call that, a long time ago, I submitted a similar proposal to comp.std.c++ =
to lukewarm reception, but I can't dig it up and the language and process h=
ave evolved a lot, so I figured it might be interesting to see what current=
 people think.</div><div><br></div><div>Currently, there is no thrust towar=
ds getting a relaxed switch statement into the language, but the EWG did ex=
press some interest in continuing with N3627,[1] which proposes a much more=
 restricted version than I propose here.</div><div><br></div><div>The gener=
al concept is to allow a fully overloadable switch operator. The inspiratio=
n comes from Perl's experimental smart match operator,[2] which is designed=
 to make the code "do the right thing" in the context of a switch.</div><di=
v><br></div><div>The first component is the addition of a new overloadable =
operator name. We could use a magic name function name like begin() and end=
(), but that's really a bikeshedding problem and doesn't affect the substan=
ce of the proposal, I think.</div><div><br></div><div>The new operator, "op=
erator switch", must return bool and take exactly two arguments (optionally=
, we could allow a one-argument member form as well). As an example, we mig=
ht have:</div><div><br></div><div>bool operator switch(const std::regex&amp=
; re, const std::string &amp;s) {</div><div>&nbsp; &nbsp; return regex_matc=
h(s, re, std::match_any);</div><div>}</div><div><br></div><div>The use of t=
his operator is straightforward. switch(s) { case e: ; } is roughly transla=
ted to "if (operator switch(e, s)) ; ". In case of multiple possible matche=
s, the first one is chosen. Existing switch behaviour is implemented with i=
mplicit overload candidates, as with built-in operators.</div><div><br></di=
v><div>So as an example, assuming a UDL for regexes exists, you could do:</=
div><div><br></div><div>switch (some_long_string) {</div><div>case "(a )?co=
lou?red house"_regex:</div><div>&nbsp; &nbsp; std::cout &lt;&lt; "coloured =
house";</div><div>&nbsp; &nbsp; break;</div><div>case "(a )?house"_regex:</=
div><div>&nbsp; &nbsp; std::cout &lt;&lt; "house";</div><div>&nbsp; &nbsp; =
break;</div><div>default:</div><div>&nbsp; &nbsp; std::cout &lt;&lt; "dunno=
";</div><div>&nbsp; &nbsp; break;</div><div>}</div><div><br></div><div>Rath=
er than have "default" mean "true", I would rather preserve the existing be=
haviour that default is fallen back onto whenever none of the case expressi=
ons match.</div><div><br></div><div>The biggest potential issue with this i=
s reuse of conversions. Because new expressions need to be evaluated on the=
 matching expression, there is no consistent way to minimize conversions li=
ke the current switch does (where a value is converted to integer type only=
 once). In the above example, if some_long_string is not a string, but is c=
onvertible to one, is the conversion called multiple times? Perhaps it coul=
d be unspecified whether a conversion function is called more than once in =
the evaluation of a switch---this would help ensure that implementations ca=
n continue to use optimizations like jump tables for builtin types. Other o=
ptions may include requiring explicit specification of the type ("switch st=
d::string (some_long_string)"), which, if not specified, gives the non-over=
loaded switch behaviour ("switch auto(e)" could be used for getting the new=
 behaviour with the type of e) or restricting the implicit conversions that=
 can be performed.</div><div><br></div><div>Thoughts?</div><div><br></div><=
div>Sean</div><div><br></div><div>[1]: http://www.open-std.org/jtc1/sc22/wg=
21/docs/papers/2013/n3627.html<br></div><div>[2]: http://perldoc.perl.org/p=
erlop.html#Smartmatch-Operator</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_431_1369292159.1415315657772--

.