220 38763 <6349a7db-6d98-45ff-a022-3ab98078d011@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: The madness called "simple concepts syntax"
Date: Wed, 20 Jun 2018 18:17:15 -0700 (PDT)
Lines: 250
Approved: news@gmane.org
Message-ID: <6349a7db-6d98-45ff-a022-3ab98078d011@isocpp.org>
References: <19c57a60-e883-4474-b106-7ff2ebc122ee@isocpp.org>
 <83850f66-75f2-4497-86f3-afd5fa91a067@isocpp.org> <a1ae0248-5af7-40b9-abcf-9f8c9e2c761e@isocpp.org>
 <ee3facb4-a0cd-4bd8-9197-f922787fec75@isocpp.org> <5574e3bb-3c4d-4459-a956-3fb77e26d050@isocpp.org>
 <3c5f8766-9ef4-46be-a9c2-7b5f9c7f5ee7@isocpp.org> <f866bc73-ddd3-43a6-82db-b977c90c09b1@isocpp.org>
 <57272b82-fbc7-490a-b332-73a2deaedac5@isocpp.org> <02c84409-d59c-480c-b33f-ced5cdd4fff2@isocpp.org>
 <906c89da-61de-41ae-bf38-c2cf8ade77b9@isocpp.org> <becbeb5f-cd4f-40df-998c-10f849a6a3fe@isocpp.org>
 <CAANG=kVjYC90M6YB-VDHWQrSGPsunhXnbLwjYJ3uqQQhM_b-bQ@mail.gmail.com> <2a47070a-1488-41d6-9a36-2860723aaa07@isocpp.org>
 <CAANG=kWZdjrde2=U2gCHQu4X_8fDz9eej5_OUBF_NFY2KtUa8Q@mail.gmail.com>
 <08cd7791-715d-42ba-b863-1d8829e9ec1e@isocpp.org>
 <a1b8a8a0-4b72-4179-9c0a-ad44fd659450@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1968_2126933012.1529543835247"
X-Trace: blaine.gmane.org 1529543716 3496 195.159.176.226 (21 Jun 2018 01:15:16 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 21 Jun 2018 01:15:16 +0000 (UTC)
Cc: mihailnajdenov@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCP4374NRYKBBHHZVPMQKGQE656PEDQ@isocpp.org Thu Jun 21 03:15:11 2018
Return-path: <std-proposals+bncBCP4374NRYKBBHHZVPMQKGQE656PEDQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw0-f199.google.com ([209.85.161.199])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCP4374NRYKBBHHZVPMQKGQE656PEDQ@isocpp.org>)
	id 1fVoBm-0000jx-Lm
	for gclcip-std-proposals@m.gmane.org; Thu, 21 Jun 2018 03:15:06 +0200
Original-Received: by mail-yw0-f199.google.com with SMTP id t78-v6sf984403ywg.20
        for <gclcip-std-proposals@m.gmane.org>; Wed, 20 Jun 2018 18:17:18 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=VBdtZzHpBk39VT+ucupVe69FkcDzf9t4AWyHsdxKwEY=;
        b=yqqQvd8f/DNaOZXwNA3sjnNiCvkoI7xNrB6cAJ5NlIuHCZavQvqjgxEOL3SH7WVOHE
         gu0Tj4ID5Ag+UTjPurEHtk/T7Vbm4EGTCobqn0E9Xiyejc9lOMF9p7B2oUm8Mh60dzLW
         L0up/h8EeAJt2XGb6QwULsF45jU5KsCxZ7kcP4pmMaCfY/R/bZ0nHt7NLR/ghtZvtr5K
         5MsH7aJgNFqOgBvEUtOPmOIa+z1ScuR/jTl5gKkKLAeG2M3YS5TXdzZRPAC5r/5mukpc
         XGCqXom1t2BzpHVWAVvDXYQFCaoaAu7t5APiKWwvpfGbjr5Hc2xR2CU3fQILmw9tc5oI
         V/Jw==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=VBdtZzHpBk39VT+ucupVe69FkcDzf9t4AWyHsdxKwEY=;
        b=e++3fpUPblMXip/eoeMClax8LRJnr/JIl4Ccy14kCxOn3OOoY5nZsgxWGCNzXuqUUB
         G+/LPzqLngugLQvtJPa9yIYmFDgqiownunQ3rtOxjq9HPaNaZiRMMaGT5s4eXbdfsTVA
         p9CZBuPPXqiSZFY3wKRkr9PonO0EhC42mlk0UBR6GUDWETN5CF60UfqhWbkOU1mHEGwn
         Pdu3Wn38V3WXci1zx9YDk001ajecGUvcYMIwirwG01Oz38KqVMjajOMDJvn9QhKzxdlH
         Hw4GaQs5Xrjqu6x6nz7xKX1961/zmhTvO5ByLTe2VPbpAEr20REqds6q//uUqDk6Elbo
         EnNw==
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:cc:message-id:in-reply-to
         :references: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=VBdtZzHpBk39VT+ucupVe69FkcDzf9t4AWyHsdxKwEY=;
        b=smqJYD3lWf1aO+NtohSql7zK8Q0+AO47ET5M45Mjx6YqV1mZB3yglTBbMNxhELsZYu
         Dgx7JZoMx/i8wzOn75U4JwTYPFVUdEl8G6eHxaSKe1wEpybd/5c29VNLWyvDT1DPaWmq
         IRkDTY+pKR6HSEFSgAl30VPCilUwJaLhVACwncGhKT2JLMhjbvbULiEdL5Rys2AoFGab
         L0p/tm3znz6W3ImyZvYJ1bXYF2g4vmR/KLwJyLJJdLnqrMpsSOm+RhiVxoN6wTi/5yE5
         8yCDhJhXhYkbwq3kkskb+b1ZgfOiEh3LaEkFGy1SvIKmKKZhzweSpPFZVmz4/PRLw1zO
         yTfg==
X-Gm-Message-State: APt69E3NhpsDaqtDh61JFytZv9oRbUNEpSL5srYHp+KAs3TFFDSBQuZa
	lIWgRJ/40riEoT6imuKR9QCrZw==
X-Google-Smtp-Source: ADUXVKJb6vfHaUuCSHhJPQdffB6bUncBAYuzy05s+Oy0blYvag6R8sWpuzYt80B2/TAJJ1m1j1QORw==
X-Received: by 2002:a0d:e9c7:: with SMTP id s190-v6mr7324899ywe.108.1529543837459;
        Wed, 20 Jun 2018 18:17:17 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:a25:18c3:: with SMTP id 186-v6ls1198340yby.2.gmail; Wed, 20
 Jun 2018 18:17:16 -0700 (PDT)
X-Received: by 2002:a25:50d3:: with SMTP id e202-v6mr1265852ybb.4.1529543835887;
        Wed, 20 Jun 2018 18:17:15 -0700 (PDT)
In-Reply-To: <a1b8a8a0-4b72-4179-9c0a-ad44fd659450@isocpp.org>
X-Original-Sender: abv150ci@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: 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:38763
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/38763>

------=_Part_1968_2126933012.1529543835247
Content-Type: multipart/alternative; 
	boundary="----=_Part_1969_1379145745.1529543835248"

------=_Part_1969_1379145745.1529543835248
Content-Type: text/plain; charset="UTF-8"

I'm not an expert but in my point of view, in order to don't adding too 
much verbosity or new syntax elements under the "time-traveler" approach, I 
think C++ has already constructs enough to implement concepts without 
changing template syntax too much. As a C++ user since at least 10 years 
ago, something like this will be good enough for me without confusing the 
alleged time-traveler:

   template<class T> // `T` refers to the type being checked.
   concept my_concept
   {
         // Anything that can be declared inside classes.

         static bool requires() { // `requires` it's a keyword but only as 
a concept function member.
             // expressions that must compile with usual C++ syntax.
             // No need for `return statements`. If a call to `requires()` 
compiles, it returns true.
         } // Of course, any future syntactic sugar can still be applied 
over this base syntax which for now adds nothing new but the keyword 
`concept`.
   };

   template<class T>
   void f(my_concept<T> const& a) { do_whatever_with_a(); }

Here, when calling `f` with anytype, the compiler must first call 
`a.requires();`, and, if it compiles, then the concept is satisfied. The 
syntax is the same as has been always be. If there's further improvements 
or simplifications in template or concept syntax, it is applied all the 
same to functions, classes and concepts. The problem with concepts having 
its own syntax is that it must be treated or re-thinked separatedly for any 
change on the language.

The adventage of defining concepts as some kind of metaclasses, is that you 
can declare attributes, static functions, using-declarations and anything 
that helps you to write your requires expressions in a more readable way, 
or do anything that can be currently done with classes, like writting 
partial specializations, inheritance of concepts or defining local 
(auxiliary) concepts. Any future change to the core language, can be 
applied and being used in metaclasses as well. So, syntactic concerns about 
concepts can be left to future discussions, and the language could add 
concepts "right know". The only concerns are semantical, not syntactical.

When the time-traveler reads `my_concept` he will initially think 
`my_concept` is a class that must be defined somewhere, with no further 
misunderstandings because there's no extra syntax; and then he founds 
`concept`. The time-traveler just *google*s it and will easily understand 
what is going on.

In case you need a manual check of a constraint, you can just do: `if 
constexpr (concept_a<T>::requires()) bla_bla_bla();`.

About future improvements, another thing that worries me is about the extra 
compilation step to check concepts. For example, standard library 
components will be implemented in such a way that will satisfy for sure 
certain concepts. Having to check the same contrainsts over and over again 
with types that we already know will satisfy them is a waste. This can be 
also applied to user-defined types that have been fully tested.

So maybe any mechanism to declare that a class satisfies a concept would be 
a good think. To don't adding new syntaxes for that, let's just keep using 
the functional notation, with a colon to identify it as a keyword 
(emacs-lisp style):

    struct A
    {
         bool :satisfies(destructible<T> const&) { return true; } // 
constexpr is mandatory, and then, implicit.
         bool :satisfies(iterable<T> const&) { return false; } // SFINAE 
purposes with fast compilation times for known contexts?
    };

If you instantiate a function using an object of type `A`, and the function 
requires it is `destructible`, you promises that `A` already satisfies it 
and then the `requires` check of the function parameter can be skipped to 
improve compilation times. If you lied, you will get the usual compiler 
errors in the instantiation steps.

Of course, if a `satisfability` assertion rest on dependent types, you can 
use `if constexpr` constructs to computate the result (or just use `if`; 
`constexpr` is implicit inside `:satisfies`).

If later you want to reduce typing when declaring constraints (like the 
already know `requires` clauses in function signatures), the language 
should just use syntactic sugar over the standard approach (a `concept` 
class is automatically created with the usual members described above; like 
it's already done with `lambda` expressions).

Each time I read about future purposal on concepts and templates, usually 
the discussions are mixed: in one hand, we have the problem of template 
verbosity, and on the other hand, how to add concepts to the language, and 
the discussions tries to solve both problems at once.

I think that way of expressing concepts allow more separation of concerns. 
You add concepts capabilities to the language using the already existing 
syntax with just a couple of keywords. Then, you can apply any liked 
syntactic sugar on template declarations in an independent way (which will 
affect the expressibility of concepts as well), and later, based on the 
agreed template simplifications, then any specific syntactic sugar for 
concepts.


-- 
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/6349a7db-6d98-45ff-a022-3ab98078d011%40isocpp.org.

------=_Part_1969_1379145745.1529543835248
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><span style=3D"font-family: arial, sans-serif; font-size: =
small;">I&#39;m not an expert but in my point of view, in order to don&#39;=
t adding too much verbosity or new syntax elements under the &quot;time-tra=
veler&quot; approach, I think C++ has already constructs enough to implemen=
t concepts without changing template syntax too much. As a C++ user since a=
t least 10 years ago, something like this will be good enough for me withou=
t confusing the alleged time-traveler:</span><div><span style=3D"font-famil=
y: arial, sans-serif; font-size: small;"><br></span></div><div><span style=
=3D"font-family: arial, sans-serif; font-size: small;">=C2=A0 =C2=A0templat=
e&lt;class T&gt; // `T` refers to the type being checked.</span></div><div>=
<span style=3D"font-family: arial, sans-serif; font-size: small;">=C2=A0 =
=C2=A0concept my_concept</span></div><div><span style=3D"font-family: arial=
, sans-serif; font-size: small;">=C2=A0 =C2=A0{</span></div><div><span styl=
e=3D"font-family: arial, sans-serif; font-size: small;">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 =C2=A0// Anything that can be declared inside classes.</span></d=
iv><div><br></div><div><span style=3D"font-family: arial, sans-serif; font-=
size: small;">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0static bool requires() { //=
 `requires` it&#39;s a keyword but only as a concept function member.</span=
></div><div><span style=3D"font-family: arial, sans-serif; font-size: small=
;">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0// expressions that must=
 compile with usual C++ syntax.</span></div><div><span style=3D"font-family=
: arial, sans-serif; font-size: small;">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0// No need for `return statements`. If a call to `requires()` =
compiles, it returns true.</span></div><div><span style=3D"font-family: ari=
al, sans-serif; font-size: small;">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0} // O=
f course, any future syntactic sugar can still be applied over this base sy=
ntax which for now adds nothing new but the keyword `concept`.</span></div>=
<div><span style=3D"font-family: arial, sans-serif; font-size: small;">=C2=
=A0 =C2=A0};</span></div><div><span style=3D"font-family: arial, sans-serif=
; font-size: small;"><br></span></div><div><span style=3D"font-family: aria=
l, sans-serif; font-size: small;">=C2=A0 =C2=A0template&lt;class T&gt;</spa=
n></div><div><span style=3D"font-family: arial, sans-serif; font-size: smal=
l;">=C2=A0 =C2=A0void f(my_concept&lt;T&gt; const&amp; a) { do_whatever_wit=
h_a(); }</span></div><div><span style=3D"font-family: arial, sans-serif; fo=
nt-size: small;"><br></span></div><div><font face=3D"arial, sans-serif" siz=
e=3D"2">Here, when calling `f` with anytype, the compiler must first call `=
a.requires();`, and, if it compiles, then the concept is satisfied. The syn=
tax is the same as has been always be. If there&#39;s further improvements =
or simplifications in template or concept syntax, it is applied all the sam=
e to functions, classes and concepts. The problem with concepts having its =
own syntax is that it must be treated or re-thinked separatedly for any cha=
nge on the language.<br><br>The adventage of defining concepts as some kind=
 of metaclasses, is that you can declare attributes, static functions, usin=
g-declarations and anything that helps you to write your requires expressio=
ns in a more readable way, or do anything that can be currently done with c=
lasses, like writting partial specializations, inheritance of concepts or d=
efining local (auxiliary) concepts. Any future change to the core language,=
 can be applied and being used in metaclasses as well. So, syntactic concer=
ns about concepts can be left to future discussions, and the language could=
 add concepts &quot;right know&quot;. The only concerns are semantical, not=
 syntactical.</font></div><div><font face=3D"arial, sans-serif" size=3D"2">=
<br></font></div><div><font face=3D"arial, sans-serif" size=3D"2">When the =
time-traveler reads `my_concept` he will initially think `my_concept` is a =
class that must be defined somewhere, with no further misunderstandings bec=
ause there&#39;s no extra syntax; and then he founds `concept`. The time-tr=
aveler just <i>google</i>s it and will easily understand what is going on.<=
/font></div><div><br></div><div><font face=3D"arial, sans-serif" size=3D"2"=
>In case you need a manual check of a constraint, you can just do: `if cons=
texpr (concept_a&lt;T&gt;::requires()) bla_bla_bla();`.</font></div><div><f=
ont face=3D"arial, sans-serif" size=3D"2"><br></font></div><div><font face=
=3D"arial, sans-serif" size=3D"2">About future improvements, a</font><span =
style=3D"font-family: arial, sans-serif; font-size: small;">nother thing th=
at worries me is about the extra compilation step to check concepts. For ex=
ample, standard library components will be implemented in such a way that w=
ill satisfy for sure certain concepts. Having to check the same contrainsts=
 over and over again with types that we already know will satisfy them is a=
 waste. This can be also applied to user-defined types that have been fully=
 tested.<br><br>So maybe any mechanism to declare that a class satisfies a =
concept would be a good think. To don&#39;t adding new syntaxes for that, l=
et&#39;s just keep using the functional notation, with a colon to identify =
it as a keyword (emacs-lisp style):</span></div><div><font face=3D"arial, s=
ans-serif" size=3D"2"><br>=C2=A0 =C2=A0 struct A</font></div><div><font fac=
e=3D"arial, sans-serif" size=3D"2">=C2=A0 =C2=A0 {</font></div><div><font f=
ace=3D"arial, sans-serif" size=3D"2">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bool=
 :satisfies(destructible&lt;T&gt; const&amp;) { return true; } // constexpr=
 is mandatory, and then, implicit.</font></div><div><font face=3D"arial, sa=
ns-serif" size=3D"2">=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0bool :satisfies(iter=
able&lt;T&gt; const&amp;) { return false; } // SFINAE purposes with fast co=
mpilation times for known contexts?</font></div><div><font face=3D"arial, s=
ans-serif" size=3D"2">=C2=A0 =C2=A0 };</font></div><div><font face=3D"arial=
, sans-serif" size=3D"2"><br></font></div><div><font face=3D"arial, sans-se=
rif" size=3D"2">If you instantiate a function using an object of type `A`, =
and the function requires it is `destructible`, you promises that `A` alrea=
dy satisfies it and then the `requires` check of the function parameter can=
 be skipped to improve compilation times. If you lied, you will get the usu=
al compiler errors in the instantiation steps.<br><br>Of course, if a `sati=
sfability` assertion rest on dependent types, you can use `if constexpr` co=
nstructs to computate the result (or just use `if`; `constexpr` is implicit=
 inside `:satisfies`).</font></div><div><font face=3D"arial, sans-serif" si=
ze=3D"2"><br></font></div><div><font face=3D"arial, sans-serif" size=3D"2">=
If later you want to reduce typing when declaring constraints (like the alr=
eady know `requires` clauses in function signatures), the language should j=
ust use syntactic sugar over the standard approach (a `concept` class is au=
tomatically created with the usual members described above; like it&#39;s a=
lready done with `lambda` expressions).</font></div><div><font face=3D"aria=
l, sans-serif" size=3D"2"><br></font></div><div><font face=3D"arial, sans-s=
erif" size=3D"2">Each time I read about future purposal on concepts and tem=
plates, usually the discussions are mixed: in one hand, we have the problem=
 of template verbosity, and on the other hand, how to add concepts to the l=
anguage, and the discussions tries to solve both problems at once.</font></=
div><div><font face=3D"arial, sans-serif" size=3D"2"><br></font></div><div>=
<font face=3D"arial, sans-serif" size=3D"2">I think that way of expressing =
concepts allow more separation of concerns. You add concepts capabilities t=
o the language using the already existing syntax with just a couple of keyw=
ords. Then, you can apply any liked syntactic sugar on template declaration=
s in an independent way (which will affect the expressibility of concepts a=
s well), and later, based on the agreed template simplifications, then any =
specific syntactic sugar for concepts.</font></div><div><font face=3D"arial=
, sans-serif" size=3D"2"><br></font></div><div><font face=3D"arial, sans-se=
rif" size=3D"2"><br></font></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/6349a7db-6d98-45ff-a022-3ab98078d011%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6349a7db-6d98-45ff-a022-3ab98078d011=
%40isocpp.org</a>.<br />

------=_Part_1969_1379145745.1529543835248--

------=_Part_1968_2126933012.1529543835247--

.
