220 40103 <CAOfiQqknXM3=8x4wmGGboSYh=tuMfrUU2MuxVM0XtEur95LhgA@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Richard Smith <richard@metafoo.co.uk>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Parametric Expression
Date: Thu, 30 Aug 2018 15:01:18 -0700
Lines: 420
Approved: news@gmane.org
Message-ID: <CAOfiQqknXM3=8x4wmGGboSYh=tuMfrUU2MuxVM0XtEur95LhgA@mail.gmail.com>
References: <95ae303b-329c-4121-aa5f-69edf040d5b5@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="000000000000a8320e0574ae379d"
X-Trace: blaine.gmane.org 1535666370 25436 195.159.176.226 (30 Aug 2018 21:59:30 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Thu, 30 Aug 2018 21:59:30 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDVNBJG4YAIBBP6SUHOAKGQEKD3UDHQ@isocpp.org Thu Aug 30 23:59:26 2018
Return-path: <std-proposals+bncBDVNBJG4YAIBBP6SUHOAKGQEKD3UDHQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-wr1-f70.google.com ([209.85.221.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDVNBJG4YAIBBP6SUHOAKGQEKD3UDHQ@isocpp.org>)
	id 1fvUyL-0006Vz-TO
	for gclcip-std-proposals@m.gmane.org; Thu, 30 Aug 2018 23:59:26 +0200
Original-Received: by mail-wr1-f70.google.com with SMTP id a37-v6sf6977975wrc.5
        for <gclcip-std-proposals@m.gmane.org>; Thu, 30 Aug 2018 15:01:36 -0700 (PDT)
ARC-Seal: i=2; a=rsa-sha256; t=1535666496; cv=pass;
        d=google.com; s=arc-20160816;
        b=wtCToNfeWHIFHKBCsUISabqliFID/I5FIySMm+jj7Pp4rrUpIkiaWdLEWnd2fThEHR
         2L43QFBjF+BZiODadkDGpfIrTHDEiZoZpz0r1i2VNyauQogwqkxYjvMTYuB5d7rZeajk
         t4RzHYk+74qgDRL45OgGVPKMPYDKM3tO7lFzOEzZwrLaYMOu9QVurSves8CGJzQjYFGy
         5vL8oRcm+yPFTj0IqAEB+flmFBXvGJiptxVlSfw3LP3aBIadHyxWSNjUdrHOBlnIlAu5
         FXP1aE+tBFIXEDMaVMe9YvRyG7hLO3XQyfqL6Aj9YMHSSOdT316jfkpaiWgt5d+HaW27
         r+HQ==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:to:subject:message-id:date
         :from:in-reply-to:references:mime-version:arc-authentication-results
         :arc-message-signature:dkim-signature:arc-authentication-results;
        bh=s/0ZalUO25976qVO4VKe3xML/BLllwH+2AOgvHbqqSQ=;
        b=LX6YLF2ZnYSEzZIkK+vc4GZOtDDht9Mbs06UKgBa0nY5Ru3wNi2xQpeUfMjblJQogq
         aMISpml+Uyf1b5vk+veLMTq6rCgS0GoDVEJ5zDL5A3wykr/lpqEgI+GT1b9ZnP6Z319g
         z9ifidFp0wn7pbWVdnWItx9tRUcG74D0PE7rESmdcxURwicEdc0MaEofFLG3zs0YOfZq
         IAvCiNwFwDwr9vTHjm7c4/MO2VLE3B/sQ3emjeqoL+mfZoChYEN0cy0Np4xbZ2+E4m/u
         UXi1rd43MFekwHVTyoYHjAed0wxEmaM6wid7GgX9Mszk7N4COfpXKQSYbl/iIwghLeMn
         eSUw==
ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@metafoo.co.uk header.s=default header.b=NZ7UiR83;
       spf=neutral (google.com: 81.27.85.19 is neither permitted nor denied by best guess record for domain of richard@metafoo.co.uk) smtp.mailfrom=richard@metafoo.co.uk
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:references:in-reply-to:from:date:message-id:subject:to
         :x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=s/0ZalUO25976qVO4VKe3xML/BLllwH+2AOgvHbqqSQ=;
        b=FcJwhViHjPUn5G9Q9QjZCUmB6xzEHkvAianT6Dq7OI6n1g3yDGVZ9LNjGpbN9gVxd3
         oI8lRsaNLEl9g8BkMa1T6jUqZn4TqsSGn0jdLh5706Yh2LOHhzSRuM8nKbxZRjIIiyVV
         9aASZ3uVdudmEOGQotlHBesLQ2Y74NfAnLocl8XZnU9aPWClvbCBwC3zOlrJbC45OgQi
         zHuKdqYHx8JkDbNjwCqIhd3JJ2qJk5xKQ/dhmIzEw37EoIzfWApNIgtokLD1JUET9eeg
         CToVGPTCmIrf0w7qmIwNcIAqzaeHl6gy3jPuX/ylsCqOsHIKrxne48NV4++CPTs/rNYy
         ELvA==
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:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=s/0ZalUO25976qVO4VKe3xML/BLllwH+2AOgvHbqqSQ=;
        b=uUdYTkGD6x3pT8pos2Xh9amRwHgxec04E9NMLhvnwm4A7tnIw9cHjRp0wdSu0gVXFG
         +sdKraorneJAlqkEQHdTh3ZOzacAKhReu6f+xawRnuoFS1/yHGgUjF3dmUuGTCKh6Y6+
         D6wX+lSnOnDVMJFATlmM83hVVPf4rx8p2VA00t7cmwIN6Iox+DGLOKjo8mEvCcWRMTxN
         jhV5h/VK6NQCYkqrVW54g/oouBV4+vJRE2UkRICYw6p3pXk2naZgVe6Lua9yYKDGAx6U
         QXy1zWva/GC797UEwnqjoNodAS0AnFBlMVFUAKcxwo71j0eaNTF5qhrn74kRCW4Rs0gm
         9NIQ==
X-Gm-Message-State: APzg51DBsV0tuoPBL21LWQNpiRqYWXsQTr5OYE+tFuPOGIr+O5OOfXLo
	aolAa0walRfRNrdL503kPb9/Sg==
X-Google-Smtp-Source: ANB0Vdb/v30EqhH8j6yFzaoOON5KHl6jUaOo4bkEKUSQ2MPFRaeJFoanksMuc/K5sALNe30dNueSlQ==
X-Received: by 2002:a1c:b8d7:: with SMTP id i206-v6mr408816wmf.11.1535666496050;
        Thu, 30 Aug 2018 15:01:36 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:a1c:7c18:: with SMTP id x24-v6ls643242wmc.5.canary-gmail;
 Thu, 30 Aug 2018 15:01:34 -0700 (PDT)
X-Received: by 2002:a1c:dac9:: with SMTP id r192-v6mr2804933wmg.141.1535666494684;
        Thu, 30 Aug 2018 15:01:34 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1535666494; cv=none;
        d=google.com; s=arc-20160816;
        b=RO4gKgykjLamfVoPmoKMrrm02kP9jL2WyqQMuyA2wO3e5IuBHahPd4z011FT14fTub
         ulOrJHv0h1cxcRrcSikvX5cPdhOhnau4jjyZRlDa8A1NkvYZOoBbTkG73Kc4Vm7e+8Js
         fqSQqUQYHXEFC9RTE1iqMBzoUZdMIc94OxIjf8n4CL0VIWOgxB5f58MFP3IGEGN4VIoB
         KIlatkeziPCxrICjMvPl3RJSemDdicWnk+cKEeO9v6ovtlFjiw7Z/edidLzVM8YwFRXV
         4BzUdn2NCLL/3lbPEGY3NetaSOLwPu9ML3z1bch14qZ4guh6tj+bN+kIIdV/GPDo/taw
         pqpA==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=to:subject:message-id:date:from:in-reply-to:references:mime-version
         :dkim-signature:arc-authentication-results;
        bh=GBRDY2VJ8jhNQ4XpFqLVGAmH822uOEBzKza+ZS/9+VU=;
        b=jLtyUYR+0GoagWeyaz3/YJDY/BqZhVTqimvXMr+6J5zXF5ZU6tuZbQ+2ju0VSVQrlY
         riMwn8dWRrk3A5z7s0e+0nCRMHb88uyFwGk+Zxo04BStsb7Rp8r2Vg37KywDZFgGCwRP
         GDSzUT2rucAv3zc1HIxaR2I8Cnu0zpSEpciH9o0wpAclaDlkJuw8rLMCFcRBpdIcwSZk
         A694ItktUsm+i7+83aI1E+/gOmB3DD0iSD2gafEwWrc29A2UGxc07hwSF2Hr7MM/XjgR
         Ie4fzHJ0W5548MH7i38S/Qh8+fi5nTQ40QkSrHxD7qaUX2T830Nr7iyYb4okQCYkLUIM
         WPQg==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@metafoo.co.uk header.s=default header.b=NZ7UiR83;
       spf=neutral (google.com: 81.27.85.19 is neither permitted nor denied by best guess record for domain of richard@metafoo.co.uk) smtp.mailfrom=richard@metafoo.co.uk
Original-Received: from uk12.easy-internet.co.uk (uk12.easy-internet.co.uk. [81.27.85.19])
        by mx.google.com with ESMTPS id g6-v6si6900234wrp.7.2018.08.30.15.01.34
        for <std-proposals@isocpp.org>
        (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);
        Thu, 30 Aug 2018 15:01:34 -0700 (PDT)
Received-SPF: neutral (google.com: 81.27.85.19 is neither permitted nor denied by best guess record for domain of richard@metafoo.co.uk) client-ip=81.27.85.19;
Original-Received: from mail-oi0-f49.google.com ([209.85.218.49]:44087)
	by uk12.easy-internet.co.uk with esmtpsa (TLSv1.2:ECDHE-RSA-AES128-GCM-SHA256:128)
	(Exim 4.91)
	(envelope-from <richard@metafoo.co.uk>)
	id 1fvV0M-00039H-Gq
	for std-proposals@isocpp.org; Thu, 30 Aug 2018 23:01:33 +0100
Original-Received: by mail-oi0-f49.google.com with SMTP id l82-v6so18229579oih.11
        for <std-proposals@isocpp.org>; Thu, 30 Aug 2018 15:01:31 -0700 (PDT)
X-Received: by 2002:aca:4507:: with SMTP id s7-v6mr4301660oia.200.1535666490452;
 Thu, 30 Aug 2018 15:01:30 -0700 (PDT)
In-Reply-To: <95ae303b-329c-4121-aa5f-69edf040d5b5@isocpp.org>
X-Gmail-Original-Message-ID: <CAOfiQqknXM3=8x4wmGGboSYh=tuMfrUU2MuxVM0XtEur95LhgA@mail.gmail.com>
X-OutGoing-Spam-Status: No, score=-0.1
X-AntiAbuse: This header was added to track abuse, please include it with any abuse report
X-AntiAbuse: Primary Hostname - uk12.easy-internet.co.uk
X-AntiAbuse: Original Domain - isocpp.org
X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12]
X-AntiAbuse: Sender Address Domain - metafoo.co.uk
X-Get-Message-Sender-Via: uk12.easy-internet.co.uk: authenticated_id: metafooc/from_h
X-Authenticated-Sender: uk12.easy-internet.co.uk: richard@metafoo.co.uk
X-Source: 
X-Source-Args: 
X-Source-Dir: 
X-Original-Sender: richard@metafoo.co.uk
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@metafoo.co.uk header.s=default header.b=NZ7UiR83;       spf=neutral
 (google.com: 81.27.85.19 is neither permitted nor denied by best guess record
 for domain of richard@metafoo.co.uk) smtp.mailfrom=richard@metafoo.co.uk
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:40103
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/40103>

--000000000000a8320e0574ae379d
Content-Type: text/plain; charset="UTF-8"

I'd worry a little about such a facility being overused where people really
just want a function with a strong "inline this please" hint (but then
again, any feature can be misused). But this seems like an interesting way
to address a collection of cases where people currently use macros.

The paper would benefit from a collection of realistic usage examples.

"Expressions evaluating to an rvalue have the last evaluated use in the
definition cast to an rvalue.
The compiler should be able to determine this internally even for cases
where order of evaluation is unspecified."

Can the body of the alias contain control flow constructs? I don't think
the compiler can determine this in general. It's also unfortunate that you
don't support (guaranteed) copy elision for rvalue parameters under any
circumstances.

On Thu, 30 Aug 2018 at 09:42, Jason Rice <ricejasonf@gmail.com> wrote:

> Here is a write up for a language feature that I would like to have
> considered:
>
> https://gist.github.com/ricejasonf/84c11ac6bb093c1ea8c380a9a466d8cb
>
> I'm attempting to implement it in Clang, but I would like to get some
> early feedback.
>
> I've already received some feedback from Louis Dionne and he encouraged me
> to post it here.
>
>
> Thanks!
>
>
>
> # Parametric Expression
>
> The primary purpose here is to improve compile-time performance by
> providing a tool that augments existing
> metaprogramming features in C++. It involves the transformation of
> expressions.
>
> Essentially this feature is meant to combine the power of function
> templates with the performance of type
> aliases. Function templates as we have them now are loaded with features
> such as overloading, constraints,
> type deduction, SFINAE, ect.. When called not only do we get an expensive
> template instantiation but also
> potentially large symbols and extraneous code generation all for functions
> we wouldn't call otherwise
> unless we expected the optimizer to inline them out anyways. With this
> tool we want to give programmers
> the ability to allow this inlining at an earlier stage, but the solution
> is elegant enough to provide a
> few additional bonus features.
>
> Consider the following declaration syntax:
>
> ```cpp
> using add(auto a, auto b) {
>   return a + b;
> }
> ```
>
> Here is a function-like declaration where the domain and codomain are
> expressions.
>
> Invoking it merely transforms the expression in the context of the site of
> invocation.
>
> ```cpp
> int main() {
>   return add(40, 2);
> }
>
> // the same as
>
> int main() {
>   return 40 + 2;
> }
> ```
>
> This ability to transform expressions has the same power as type aliases,
> but here we can work with
> constructs that have run-time effects as seen in Fusion/Hana style
> metaprogramming. Additionally,
> since this is a language feature, we could pontentially see the same
> compile-time performance that
> Kvasir.Mpl has without the difficult continuation interface (and it works
> on expressions!).
>
>
> ## Additional Bonus Features
>
> Since the expressions maintain the context of the site of invocation we
> also get constexpr parameters.
>
> ```cpp
> using to_integral_constant(auto x) {
>   return std::integral_constant<int, x>{};
> }
>
> int main() {
>   constexpr int x = 0;
>   static_assert(std::is_same_v<std::integral_constant<int, 0>,
> decltype(to_integral_constant(x)));
> }
> ```
>
> We also get arrays and string literals that do not decay.
>
> ```cpp
> using id(auto x) {
>   return x;
> }
>
> int main() {
>   char const* foo = id("foo");
> }
>
> // the same as
>
> int main() {
>   char const* foo = "foo";
> }
> ```
>
> To top it off, we also get a clean syntax for Perfect Forwarding
>
>   * This assumes that the input expression casts to an rvalue
>   * See the rules below for information on how value categories are handled
>
> ```cpp
> template <typename F, typename X, typename Y>
> decltype(auto) flip(F&& f, X&& x, y&& y) {
>   return std::forward<F>(f)(std::forward<Y>(y), std::forward<X>(x));
> }
>
> // becomes
>
> using flip(auto f, auto x, auto y) {
>   return f(y, x);
> }
> ```
>
> ## As a Member of a Class
>
> Parametric expressions can be used as a member in conjunction with
> operator overloading to create an
> invocable object:
>
> ```cpp
>   struct id_fn {
>     using operator()(auto x) {
>       return x;
>     }
>   };
>
>   id_fn{}(42);
>
>   static_assert(std::is_invocable<id_fn, int>::value);
> ```
>
>
> ## The Rules
>
> 1. The input parameter list may contain only one parameter pack in any
> position.
>     * This is afforded since we don't do type deduction
>
> 2. The input parameters may be unexpanded parameter packs.
>     * This adds a bit more power for working with lists.
>     * see [Multicategory][1]
>
> 3. The output expression must NOT contain any unexpanded parameter packs
>     * This would prevent pack expansion ambiguity at the call site
>
> 4. Input parameter type specifiers must be completely unconstrained and
> never have type qualifiers.
>     * We could possibly apply constraints to the type in the future via
> Concepts
>
> 5. The definition is a compound statement where the final statement must
> either be a return statement
>    or a constexpr if/else statement where each branch follows this same
> rule.
>     * There can be only one return statement which yields the output
> expression
>
> 6. Recursion is not allowed
>     * Not sure if recursion would be feasible, but we could at least use
> Odin Holmes' recursive
>       alias pattern
>
> 7. Input parameters are expression aliases which follow different rules
> with regard to the evaluated
>    type's value category and reference type:
>     1. Prvalue constant-expressions are simply pasted wherever it is used
> in the definition.
>         * This affords constexpr parameters and literals
>     2. Unexpanded parameter packs are pasted where the parameter is used
> in the expression.
>         * Again note that they must be expanded wherever they are used in
> the definition
>     2. Everything else is bound to an lvalue reference within the compound
> statement implicitly.
>     3. Expressions evaluating to an rvalue have the last evaluated use in
> the definition cast to an
>        rvalue.
>         * The compiler should be able to determine this internally even
> for cases where order of
>           evaluation is unspecified.
>         * This also implies that this could be used to detect order of
> evaluation of a function call.
>         * This is similar to how Rust handles implicit moves!
>
> 8. Input expressions that are not constant-expressions will be evaluated
> immediately from left to right
>    as specified in the parameter list.
>     * Note that unexpanded packs are not included in this
>
> 9. The output is a generated compound statement evaluated as an expression
> that is specified using
>    the return statement in the definition body of the parametric
> expression.
>
>
> I see this as potentially having a huge impact on the ability to implement
> ranges, expression templates,
> metaprogramming libraries, and my own pet case of nesting continuations
> for various purposes. It would be
> really cool to get this in C++20 if it is not too late.
>
>
> Thanks for looking at this!
>
> Jason Rice
>
> [1]: https://en.wikipedia.org/wiki/Multicategory
>
> --
> 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/95ae303b-329c-4121-aa5f-69edf040d5b5%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/95ae303b-329c-4121-aa5f-69edf040d5b5%40isocpp.org?utm_medium=email&utm_source=footer>
> .
>

-- 
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/CAOfiQqknXM3%3D8x4wmGGboSYh%3DtuMfrUU2MuxVM0XtEur95LhgA%40mail.gmail.com.

--000000000000a8320e0574ae379d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I&#39;d worry a little about such a facility being ov=
erused where people really just want a function with a strong &quot;inline =
this please&quot; hint (but then again, any feature can be misused). But th=
is seems like an interesting way to address a collection of cases where peo=
ple currently use macros.</div><div><br></div><div>The paper would benefit =
from a collection of realistic usage examples.</div><div><br></div>&quot;Ex=
pressions evaluating to an rvalue have the last evaluated use in the defini=
tion cast to an rvalue.<div>The compiler should be able to determine this i=
nternally even for cases where order of evaluation is unspecified.&quot;</d=
iv><div><br></div><div>Can the body of the alias contain control flow const=
ructs? I don&#39;t think the compiler can determine this in general. It&#39=
;s also unfortunate that you don&#39;t support (guaranteed) copy elision fo=
r rvalue parameters under any circumstances.</div></div><br><div class=3D"g=
mail_quote"><div dir=3D"ltr">On Thu, 30 Aug 2018 at 09:42, Jason Rice &lt;<=
a href=3D"mailto:ricejasonf@gmail.com">ricejasonf@gmail.com</a>&gt; wrote:<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Here is a write up=
 for a language feature that I would like to have considered: <br><br><a hr=
ef=3D"https://gist.github.com/ricejasonf/84c11ac6bb093c1ea8c380a9a466d8cb" =
target=3D"_blank">https://gist.github.com/ricejasonf/84c11ac6bb093c1ea8c380=
a9a466d8cb</a><br><div><br></div><div>I&#39;m attempting to implement it in=
 Clang, but I would like to get some early feedback.<br><br>I&#39;ve alread=
y received some feedback from Louis Dionne and he encouraged me to post it =
here.<br><br><br></div>Thanks!<br><br><br><br># Parametric Expression<br><b=
r>The primary purpose here is to improve compile-time performance by provid=
ing a tool that augments existing<br>metaprogramming features in C++. It in=
volves the transformation of expressions.<br><br>Essentially this feature i=
s meant to combine the power of function templates with the performance of =
type<br>aliases. Function templates as we have them now are loaded with fea=
tures such as overloading, constraints,<br>type deduction, SFINAE, ect.. Wh=
en called not only do we get an expensive template instantiation but also <=
br>potentially large symbols and extraneous code generation all for functio=
ns we wouldn&#39;t call otherwise<br>unless we expected the optimizer to in=
line them out anyways. With this tool we want to give programmers<br>the ab=
ility to allow this inlining at an earlier stage, but the solution is elega=
nt enough to provide a<br>few additional bonus features.<br><br>Consider th=
e following declaration syntax:<br><br>```cpp<br>using add(auto a, auto b) =
{<br>=C2=A0 return a + b;<br>}<br>```<br><br>Here is a function-like declar=
ation where the domain and codomain are expressions.<br><br>Invoking it mer=
ely transforms the expression in the context of the site of invocation.<br>=
<br>```cpp<br>int main() {<br>=C2=A0 return add(40, 2);<br>}<br><br>// the =
same as<br><br>int main() {<br>=C2=A0 return 40 + 2;<br>}<br>```<br><br>Thi=
s ability to transform expressions has the same power as type aliases, but =
here we can work with<br>constructs that have run-time effects as seen in F=
usion/Hana style metaprogramming. Additionally,<br>since this is a language=
 feature, we could pontentially see the same compile-time performance that<=
br>Kvasir.Mpl has without the difficult continuation interface (and it work=
s on expressions!).<br><br><br>## Additional Bonus Features<br><br>Since th=
e expressions maintain the context of the site of invocation we also get co=
nstexpr parameters.<br><br>```cpp<br>using to_integral_constant(auto x) {<b=
r>=C2=A0 return std::integral_constant&lt;int, x&gt;{};<br>}<br><br>int mai=
n() {<br>=C2=A0 constexpr int x =3D 0;<br>=C2=A0 static_assert(std::is_same=
_v&lt;std::integral_constant&lt;int, 0&gt;, decltype(to_integral_constant(x=
)));<br>}<br>```<br><br>We also get arrays and string literals that do not =
decay.<br><br>```cpp<br>using id(auto x) {<br>=C2=A0 return x;<br>}<br><br>=
int main() {<br>=C2=A0 char const* foo =3D id(&quot;foo&quot;);<br>}<br><br=
>// the same as<br><br>int main() {<br>=C2=A0 char const* foo =3D &quot;foo=
&quot;;<br>}<br>```<br><br>To top it off, we also get a clean syntax for Pe=
rfect Forwarding<br>=C2=A0=C2=A0=C2=A0 <br>=C2=A0 * This assumes that the i=
nput expression casts to an rvalue<br>=C2=A0 * See the rules below for info=
rmation on how value categories are handled<br><br>```cpp<br>template &lt;t=
ypename F, typename X, typename Y&gt;<br>decltype(auto) flip(F&amp;&amp; f,=
 X&amp;&amp; x, y&amp;&amp; y) {<br>=C2=A0 return std::forward&lt;F&gt;(f)(=
std::forward&lt;Y&gt;(y), std::forward&lt;X&gt;(x));<br>}<br><br>// becomes=
<br><br>using flip(auto f, auto x, auto y) {<br>=C2=A0 return f(y, x);<br>}=
<br>```<br><br>## As a Member of a Class<br><br>Parametric expressions can =
be used as a member in conjunction with operator overloading to create an<b=
r>invocable object:<br><br>```cpp<br>=C2=A0 struct id_fn {<br>=C2=A0=C2=A0=
=C2=A0 using operator()(auto x) {<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 return =
x;<br>=C2=A0=C2=A0=C2=A0 }<br>=C2=A0 };<br><br>=C2=A0 id_fn{}(42);<br><br>=
=C2=A0 static_assert(std::is_invocable&lt;id_fn, int&gt;::value);<br>```<br=
><br><br>## The Rules<br><br>1. The input parameter list may contain only o=
ne parameter pack in any position.<br>=C2=A0=C2=A0=C2=A0 * This is afforded=
 since we don&#39;t do type deduction<br><br>2. The input parameters may be=
 unexpanded parameter packs.<br>=C2=A0=C2=A0=C2=A0 * This adds a bit more p=
ower for working with lists.<br>=C2=A0=C2=A0=C2=A0 * see [Multicategory][1]=
<br>=C2=A0<br>3. The output expression must NOT contain any unexpanded para=
meter packs<br>=C2=A0=C2=A0=C2=A0 * This would prevent pack expansion ambig=
uity at the call site<br><br>4. Input parameter type specifiers must be com=
pletely unconstrained and never have type qualifiers.<br>=C2=A0=C2=A0=C2=A0=
 * We could possibly apply constraints to the type in the future via Concep=
ts<br><br>5. The definition is a compound statement where the final stateme=
nt must either be a return statement<br>=C2=A0=C2=A0 or a constexpr if/else=
 statement where each branch follows this same rule.<br>=C2=A0=C2=A0=C2=A0 =
* There can be only one return statement which yields the output expression=
<br><br>6. Recursion is not allowed<br>=C2=A0=C2=A0=C2=A0 * Not sure if rec=
ursion would be feasible, but we could at least use Odin Holmes&#39; recurs=
ive<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 alias pattern<br><br>7. Input paramet=
ers are expression aliases which follow different rules with regard to the =
evaluated<br>=C2=A0=C2=A0 type&#39;s value category and reference type:<br>=
=C2=A0=C2=A0=C2=A0 1. Prvalue constant-expressions are simply pasted wherev=
er it is used in the definition.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0 * This affords constexpr parameters and literals<br>=C2=A0=C2=A0=C2=A0 =
2. Unexpanded parameter packs are pasted where the parameter is used in the=
 expression.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 * Again note tha=
t they must be expanded wherever they are used in the definition<br>=C2=A0=
=C2=A0=C2=A0 2. Everything else is bound to an lvalue reference within the =
compound statement implicitly.<br>=C2=A0=C2=A0=C2=A0 3. Expressions evaluat=
ing to an rvalue have the last evaluated use in the definition cast to an<b=
r>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 rvalue.<br>=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0 * The compiler should be able to determine this internal=
ly even for cases where order of<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 evaluation is unspecified.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0 * This also implies that this could be used to detect order=
 of evaluation of a function call.<br>=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0 * This is similar to how Rust handles implicit moves!<br><br>8. Inpu=
t expressions that are not constant-expressions will be evaluated immediate=
ly from left to right<br>=C2=A0=C2=A0 as specified in the parameter list.<b=
r>=C2=A0=C2=A0=C2=A0 * Note that unexpanded packs are not included in this<=
br><br>9. The output is a generated compound statement evaluated as an expr=
ession that is specified using<br>=C2=A0=C2=A0 the return statement in the =
definition body of the parametric expression.<br><br><br>I see this as pote=
ntially having a huge impact on the ability to implement ranges, expression=
 templates,<br>metaprogramming libraries, and my own pet case of nesting co=
ntinuations for various purposes. It would be<br>really cool to get this in=
 C++20 if it is not too late.<br><br><br>Thanks for looking at this!<br><br=
>Jason Rice<br><br>[1]: <a href=3D"https://en.wikipedia.org/wiki/Multicateg=
ory" target=3D"_blank">https://en.wikipedia.org/wiki/Multicategory</a><br><=
br></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" target=3D"_=
blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">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/95ae303b-329c-4121-aa5f-69edf040d5b5%=
40isocpp.org?utm_medium=3Demail&amp;utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/95ae303b-329c-=
4121-aa5f-69edf040d5b5%40isocpp.org</a>.<br>
</blockquote></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/CAOfiQqknXM3%3D8x4wmGGboSYh%3DtuMfrUU=
2MuxVM0XtEur95LhgA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAOfiQqknXM3%=
3D8x4wmGGboSYh%3DtuMfrUU2MuxVM0XtEur95LhgA%40mail.gmail.com</a>.<br />

--000000000000a8320e0574ae379d--

.
