{"id":312846,"date":"2020-11-09T21:00:37","date_gmt":"2020-11-09T21:00:37","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=312846"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=312846","title":{"rendered":"\u041c\u0435\u0442\u0430\u043b\u0438\u043d\u0433\u0432\u0438\u0441\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u043e\u0432\u0440\u0430\u0442\u0438\u0442\u0435\u043b\u044c \u0421\u0438. \u041e\u043f\u0443\u0441 II: \u0420\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u044b\u0439 \u044d\u043a\u0441\u0442\u0430\u0437"},"content":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ij\/9p\/-n\/ij9p-nygxt17eoxodrwteoi07-m.jpeg\"><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/youtu.be\/QNpuUXcm5zw?t=526\" rel=\"nofollow\"><em>&gt;&gt; \u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e, \u043c\u043e\u0434\u0435\u0440\u043d! 2 \u2014 0.2. \u041f\u0440\u043e\u043f\u0430\u0436\u0430 \u0437\u0430\u043d\u0430\u0447\u043a\u0438<\/em><\/a><\/p>\n<p>  <\/p>\n<p><em>\u0413\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u0432 15 \u043b\u0435\u0442, \u043c\u0435\u043d\u044f \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 compile-time \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Algebraic_data_type\" rel=\"nofollow\">\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/a> \u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0421\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0441\u043e\u0437\u0434\u0430\u043b <a href=\"https:\/\/github.com\/Hirrolot\/poica\" rel=\"nofollow\">poica<\/a> \u2014 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a \u043d\u0430 \u043c\u0430\u043a\u0440\u043e\u0441\u0430\u0445. \u0421\u0435\u0440\u0438\u044f \u044d\u0442\u0438\u0445 \u043e\u043f\u0443\u0441\u043e\u0432 \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0435\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f.<\/em><\/p>\n<p>  <\/p>\n<h1 id=\"predislovie\">\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0421\u0438 \u044f\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rewriting\" rel=\"nofollow\">\u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0435\u0440\u043c\u043e\u0432<\/a> \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0422\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u2014 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lambda_calculus\" rel=\"nofollow\">\u043b\u044f\u043c\u0431\u0434\u0430-\u0438\u0441\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/a>. \u0418\u043c\u0435\u044f \u0432 \u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0435 \u044d\u0442\u0443 \u043d\u0435\u0432\u044b\u043d\u043e\u0441\u0438\u043c\u043e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044e, \u043c\u043e\u0436\u043d\u043e, \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043e\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u0430\u043c\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043f\u043e\u0434\u0434\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f!<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u043e &quot;\u043d\u043e&quot;: \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 (macro blueprinting), \u0437\u0430\u0448\u0438\u0442\u0430\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0435 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0430 <a href=\"https:\/\/www.ioccc.org\/2001\/herrmann1.hint\" rel=\"nofollow\">\u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/a> \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ackermann_function\" rel=\"nofollow\">\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0410\u043a\u043a\u0435\u0440\u043c\u0430\u043d\u0430<\/a> \u0438 \u043c\u043d\u043e\u0433\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u0432\u0435\u0449\u0430\u043c; \u0434\u0430\u0436\u0435 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fixed-point_combinator#Y_combinator\" rel=\"nofollow\">Y \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440<\/a> \u043d\u0435 \u0432 \u0441\u0438\u043b\u0430\u0445 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0432\u0438\u0434\u0443 <a href=\"https:\/\/en.wikipedia.org\/wiki\/First-class_citizen\" rel=\"nofollow\">\u043d\u0435\u043f\u0435\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u043e\u0439<\/a> \u043f\u0440\u0438\u0440\u043e\u0434\u044b \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u044d\u0442\u043e \u043d\u0430\u0441 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442! \u041d\u0435 \u043c\u043e\u0436\u0435\u0448\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u2014 \u0440\u0435\u0448\u0438 \u0435\u0451 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e. \u0421\u0435\u0439 \u043e\u043f\u0443\u0441 \u043f\u043e\u0441\u0432\u044f\u0449\u0451\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0439 \u043c\u0430\u043a\u0440\u043e\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u0432 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuation-passing_style\" rel=\"nofollow\">\u0441\u0442\u0438\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439<\/a> \u043d\u0430 <a href=\"https:\/\/github.com\/pfultz2\/Cloak\/wiki\/C-Preprocessor-tricks,-tips,-and-idioms#deferred-expression\" rel=\"nofollow\">\u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f\u0445<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0426\u0435\u043b\u044c \u2014 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cons\" rel=\"nofollow\">Cons-\u0441\u043f\u0438\u0441\u043e\u043a<\/a>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e02\/dc8\/259\/e02dc82595761e51e8ffd29ffc812874.svg\" alt=\"$ ((((((((((0), 1), 2), 3), 4), 5), 6), 7), 8), 9) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0442\u0430\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043a\u0432\u0430\u0436\u0438\u043d\u0443 \u0432 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u2026 \u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442 \u0443\u0436\u0435 \u043b\u043e\u0445\u043c\u0430\u0442\u0438\u0442\u044c \u0431\u0430\u0431\u0443\u0448\u043a\u0443, \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442!<\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"prerekvizity\">\u041f\u0440\u0435\u0440\u0435\u043a\u0432\u0438\u0437\u0438\u0442\u044b<\/h1>\n<p>  <\/p>\n<p>\u041e\u0442 \u0447\u0438\u0442\u0430\u0442\u0435\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0432\u044b\u043a \u0432\u043b\u0430\u0434\u0435\u043d\u0438\u044f \u044f\u0437\u044b\u043a\u043e\u043c \u0421\u0438. <a href=\"https:\/\/habr.com\/en\/post\/520850\/\">\u041f\u0435\u0440\u0432\u044b\u0439 \u043e\u043f\u0443\u0441<\/a> \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0443\u044e \u0438\u043d\u0442\u0443\u0438\u0446\u0438\u044e \u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043d\u043e\u0441\u0442\u044c \u0432 \u0443\u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u043d\u043e\u043c \u043c\u0435\u0442\u0430\u044f\u0437\u044b\u043a\u0435.<\/p>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"1-potug-i-naivnaya-nerabochaya-realizaciya\">1. \u041f\u043e\u0442\u0443\u0433 I: \u041d\u0430\u0438\u0432\u043d\u0430\u044f \u043d\u0435\u0440\u0430\u0431\u043e\u0447\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h1>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u0446\u0435\u043b\u043e\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u0443\u044e \u0430\u0440\u0438\u0444\u043c\u0435\u0442\u0438\u043a\u0443. \u041d\u0435\u0434\u043e\u0441\u0442\u0430\u044e\u0449\u0438\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b <a href=\"https:\/\/github.com\/Hirrolot\/habr-metalinguistic-seduction\/blob\/master\/testing-framework\/aux.h\" rel=\"nofollow\">\u0442\u0443\u0442<\/a>.<\/p>\n<p>  <\/p>\n<h3 id=\"inkrementaciya\">\u0418\u043d\u043a\u0440\u0435\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f<\/h3>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define INC(x) CAT(INC_, x) #define INC_0  1 #define INC_1  2 #define INC_2  3 #define INC_3  4 #define INC_4  5 #define INC_5  6 #define INC_6  7 #define INC_7  8 #define INC_8  9<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/3e3\/28e\/c65\/3e328ec6538d48db0bbd8e0859e6d10a.svg\" alt=\"$3$\" data-tex=\"inline\"><\/math>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/958\/53a\/507\/95853a507427a5bb670390cd035d5611.svg\" alt=\"$INC(3) \\rightarrow \\\\ CAT(INC\\_, 3) \\rightarrow \\\\ INC\\_3 \\rightarrow \\\\ 4$\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<h3 id=\"sravnenie\">\u0421\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u0435<\/h3>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define EQ(x, y) EQ_PICK_SECOND(CAT(EQ_, CAT(x, CAT(_, y))), 0, ~)  #define EQ_PICK_SECOND(...)            EQ_PICK_SECOND_AUX(__VA_ARGS__) #define EQ_PICK_SECOND_AUX(_a, b, ...) b  #define EQ_0_0 ~, 1 #define EQ_1_1 ~, 1 #define EQ_2_2 ~, 1 #define EQ_3_3 ~, 1 #define EQ_4_4 ~, 1 #define EQ_5_5 ~, 1 #define EQ_6_6 ~, 1 #define EQ_7_7 ~, 1 #define EQ_8_8 ~, 1 #define EQ_9_9 ~, 1<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/f30\/c63\/7ff\/f30c637ff08fcc15181ab6cfc05177e2.svg\" alt=\"$(3, 3)$\" data-tex=\"inline\"><\/math>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/b3c\/146\/f3c\/b3c146f3cedfa268bfa3bb0719379d60.svg\" alt=\"$EQ(3, 3) \\rightarrow \\\\ EQ\\_PICK\\_SECOND(CAT(EQ\\_, CAT(3, CAT(\\_, 3))), 0, \\sim) \\rightarrow \\\\ EQ\\_PICK\\_SECOND(EQ\\_3\\_3, 0, \\sim) \\rightarrow \\\\ EQ\\_PICK\\_SECOND(\\sim, 1, 0, \\sim) \\rightarrow \\\\ EQ\\_PICK\\_SECOND\\_AUX(\\sim, 1, 0, \\sim) \\rightarrow \\\\ 1$\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/d77\/9e6\/447\/d779e6447c1f883eb31faca8beaddbff.svg\" alt=\"$(5, 9)$\" data-tex=\"inline\"><\/math>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/88b\/d27\/197\/88bd2719731b96ce8e41a4104257be97.svg\" alt=\"$EQ(5, 9) \\rightarrow \\\\ EQ\\_PICK\\_SECOND(CAT(EQ\\_, CAT(5, CAT(\\_, 9))), 0, \\sim) \\rightarrow \\\\ EQ\\_PICK\\_SECOND(EQ\\_5\\_9, 0, \\sim) \\rightarrow \\\\ EQ\\_PICK\\_SECOND\\_AUX(EQ\\_5\\_9, 0, \\sim) \\rightarrow \\\\ 0$\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u0421\u043c\u044b\u0441\u043b \u0442\u0430\u043a\u043e\u0439: \u0435\u0441\u043b\u0438 \u0447\u0438\u0441\u043b\u0430 \u0440\u0430\u0432\u043d\u044b, <code>CAT(EQ_, CAT(x, CAT(_, y)))<\/code> \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 <code>~, 1<\/code>, \u0438\u043d\u0430\u0447\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 <code>EQ_5_9<\/code>, \u0442.\u043a. \u0442\u0430\u043a\u043e\u0433\u043e \u043c\u0430\u043a\u0440\u043e\u0441\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u0417\u0430\u0442\u0435\u043c \u044d\u0442\u043e \u0445\u043e\u0437\u044f\u0439\u0441\u0442\u0432\u043e \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 <code>0, ~<\/code> \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f <code>EQ_PICK_SECOND<\/code> \u0438 <code>EQ_PICK_SECOND_AUX<\/code>. \u041d\u043e \u0437\u0430\u0447\u0435\u043c <code>EQ_PICK_SECOND<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0432\u043e\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432 <code>EQ_PICK_SECOND_AUX<\/code>? \u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>~, 1<\/code> \u0432\u0441\u0451 \u0435\u0449\u0451 \u0441\u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430 \u043e\u0434\u0438\u043d \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0437\u0430\u043f\u044f\u0442\u043e\u0439:<\/p>\n<p>  <\/p>\n<blockquote><p><b>C11 6.10.3 Macro replacement<\/b><br \/>  The sequence of preprocessing tokens bounded by the outside-most matching parentheses forms the list of arguments for the function-like macro. The individual arguments within the list are separated by comma preprocessing tokens, <b>but comma preprocessing tokens between matching inner parentheses do not separate arguments<\/b>.<\/p><\/blockquote>\n<p>\u0414\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043a\u043e\u0441\u0432\u0435\u043d\u043d\u043e\u0441\u0442\u0438 <code>EQ_PICK_SECOND_AUX<\/code> \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 <code>~, 1<\/code> \u0432 \u0434\u0432\u0430 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430. \u041a\u043b\u044e\u0447\u0435\u0432\u043e\u0439 \u043c\u043e\u043c\u0435\u043d\u0442 \u2014 \u044d\u0442\u043e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>b<\/code> \u0432 <code>EQ_PICK_SECOND_AUX<\/code>:<\/p>\n<p>  <\/p>\n<div class=\"scrollable-table\">\n<table>\n<thead>\n<tr>\n<th>\u0412\u0432\u043e\u0434<\/th>\n<th>\u041f\u0440\u0435\u0434\u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435<\/th>\n<th>\u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442 <code>b<\/code><\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/f30\/c63\/7ff\/f30c637ff08fcc15181ab6cfc05177e2.svg\" alt=\"$(3, 3)$\" data-tex=\"inline\"><\/math><\/td>\n<td><code>EQ_PICK_SECOND_AUX(~, 1, 0, ~)<\/code><\/td>\n<td><code>1<\/code><\/td>\n<\/tr>\n<tr>\n<td><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/c27\/b86\/86c\/c27b8686cd9a72cd449e448467996c45.svg\" alt=\"$(4, 9)$\" data-tex=\"inline\"><\/math><\/td>\n<td><code>EQ_PICK_SECOND_AUX(EQ_5_9, 0, ~)<\/code><\/td>\n<td><code>0<\/code><\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>  <\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 <code>EQ_PICK_SECOND_AUX<\/code> \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u0436\u0438\u0434\u0430\u0435\u043c\u043e\u0435 \u0434\u0432\u043e\u0438\u0447\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 <code>b<\/code>. \u0425\u043e\u0440\u043e\u0448\u043e, \u0441 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0438\u0441\u044c, \u043d\u043e \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0432\u043e\u043f\u0440\u043e\u0441: \u0437\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u0435\u043d \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u0442 <code>~<\/code> \u0432 <code>EQ_PICK_SECOND(CAT(EQ_, CAT(x, CAT(_, y))), 0, ~)<\/code>? \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0447\u0442\u043e \u0431\u0443\u0434\u0435\u0442, \u0435\u0441\u043b\u0438 \u0443\u0431\u0440\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0432\u044b\u0437\u043e\u0432\u0435 <code>EQ_PICK_SECOND_AUX(EQ_5_9, 0, ~)<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">warning: ISO C99 requires at least one argument for the &quot;...&quot; in a variadic macro    17 | EQ_PICK_SECOND_AUX(EQ_5_9, 0)       |                             ^<\/code><\/pre>\n<p>  <\/p>\n<p>\u0420\u0435\u043b\u0435\u0432\u0430\u043d\u0442\u043d\u0430\u044f \u0432\u044b\u0434\u0435\u0440\u0436\u043a\u0430 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430:<\/p>\n<p>  <\/p>\n<blockquote><p><b>C11 6.10.3 Macro replacement<\/b><br \/>  If there is a &#8230; in the identifier-list in the macro definition, then the trailing arguments, including any separating comma preprocessing tokens, are merged to form a single item: the <i>variable arguments<\/i>. The number of arguments so combined is such that, following merger, <b>the number of arguments is one more than the number of parameters in the macro definition (excluding the &#8230;)<\/b>.<\/p><\/blockquote>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<p>\u041d\u0443 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0442\u043e\u0447\u043d\u043e \u0433\u043e\u0442\u043e\u0432\u044b! \u0412\u043e\u0437\u044c\u043c\u0451\u043c <del>\u044f\u0439\u0446\u0430 \u0432 \u043a\u0443\u043b\u0430\u043a<\/del> \u043c\u0430\u043a\u0440\u043e\u0441\u044b-\u0438\u0434\u0438\u043e\u043c\u044b \u0438\u0437 <a href=\"https:\/\/habr.com\/en\/post\/520850\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u043e\u043f\u0443\u0441\u0430<\/a> \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0434\u0430\u043a\u0438\u0439 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cons\" rel=\"nofollow\">Cons-\u0441\u043f\u0438\u0441\u043e\u043a<\/a>:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define GEN(acc, i) IF(EQ(i, 9), STOP, PROGRESS)(acc, i)  #define STOP(acc, i)     acc #define PROGRESS(acc, i) GEN((acc, INC(i)), INC(i))  GEN((0), 0)<\/code><\/pre>\n<p>  <\/p>\n<pre><code class=\"plaintext\">$ clang gen.c -std=c11 -Weverything -E warning: disabled expansion of recursive macro [-Wdisabled-macro-expansion] GEN((0), 0) ^ note: expanded from macro 'GEN' #define GEN(acc, i) IF(EQ(i, 9), STOP, PROGRESS)(acc, i)                                        ^<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0445\u043e\u0434\u0438\u0442, \u0447\u0442\u043e \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043d\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e?<\/p>\n<p>  <\/p>\n<blockquote><p><b>C11 6.10.3.4 Rescanning and further replacement<\/b><br \/>  <b>If the name of the macro being replaced is found during this scan of the replacement list (not including the rest of the source file\u2019s preprocessing tokens), it is not replaced<\/b>. Furthermore, if any nested replacements encounter the name of the macro being replaced, it is not replaced. These nonreplaced macro name preprocessing tokens are no longer available for further replacement even if they are later (re)examined in contexts in which that macro name preprocessing token would otherwise have been replaced.<\/p><\/blockquote>\n<p>\u041e\u0431\u0438\u0434\u043d\u043e!<\/p>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/jz\/lw\/cw\/jzlwcwfmtxb1fsjmh6u3wwk8hja.jpeg\"><\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0434\u043e\u043b\u0436\u0435\u043d \u0436\u0435 \u0431\u044b\u0442\u044c \u0432\u044b\u0445\u043e\u0434? \u041f\u043e\u0441\u043b\u0435 \u043d\u0435\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0438\u0441\u043a\u043e\u0432 \u043d\u0430\u0442\u044b\u043a\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 <a href=\"https:\/\/github.com\/swansontec\/map-macro\" rel=\"nofollow\">map-macro<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d <a href=\"https:\/\/en.wikipedia.org\/wiki\/Functor_(functional_programming)\" rel=\"nofollow\">\u0444\u0443\u043d\u043a\u0442\u043e\u0440<\/a> \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u043e\u0432. \u0420\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0434\u043e\u0441\u0442\u0438\u0433\u0430\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u043e\u0439 \u043b\u0430\u0437\u0435\u0439\u043a\u043e\u0439 \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0435\u2026 \u043d\u043e \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u044c \u0441\u0430\u043c\u0443 \u0438\u0434\u0435\u044e. \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u044b:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define EMPTY() #define DEFER(op) op EMPTY()  #define A(x) x DEFER(B)()(x) #define B()  A<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435 <code>A(blah)<\/code>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/5f5\/140\/1ac\/5f51401acea70911cd8c21acb0516200.svg\" alt=\"$ A(blah) \\rightarrow \\\\ blah \\ DEFER(B)(blah) \\rightarrow \\\\ blah \\ B \\ EMPTY()(blah) \\rightarrow \\\\ blah \\ B \\ ()(blah) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 <code>B ()(blah)<\/code> \u043d\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 <code>A(blah)<\/code> \u0438 \u043d\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430? \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e: \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 <code>B ()<\/code> \u0437\u0430 \u0432\u044b\u0437\u043e\u0432! \u2014 \u041f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u0443\u0435\u0442 \u0442\u043e\u043a\u0435\u043d\u044b <em>\u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e<\/em>: \u0432\u0438\u0434\u0438\u043c <code>blah B EMPTY()(blah)<\/code>. <code>blah<\/code> \u2014 \u0432\u044b\u0437\u043e\u0432? \u041d\u0435\u0442. <code>B<\/code> \u2014 \u0432\u044b\u0437\u043e\u0432? \u041d\u0435\u0442. <code>EMPTY()<\/code> \u2014 \u0432\u044b\u0437\u043e\u0432? \u0414\u0430, \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u043c. <code>(blah)<\/code> \u2014 \u0432\u044b\u0437\u043e\u0432? \u041d\u0435\u0442. \u041f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u0430\u044f \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u043b\u0435\u043a\u0441\u0435\u043c <code>blah B ()(blah)<\/code> \u0438 \u0435\u0441\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f. \u0412\u044b\u0434\u0435\u0440\u0436\u043a\u0430 \u0438\u0437 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0430:<\/p>\n<p>  <\/p>\n<blockquote><p><b>C11 6.10.3.4 Rescanning and further replacement<\/b><br \/>  After all parameters in the replacement list have been substituted and <code>#<\/code> and <code>##<\/code> processing has taken place, all placemarker preprocessing tokens are removed. <b>The resulting preprocessing token sequence is then rescanned, along with all subsequent preprocessing tokens of the source file, for more macro names to replace<\/b>.<\/p><\/blockquote>\n<p>\u0414\u043b\u044f \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f <code>B ()<\/code> \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 <code>blah B ()(blah)<\/code> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0435\u0449\u0451 \u043e\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435. \u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 <del>\u043d\u0435\u043e\u043f\u0438\u0441\u0443\u0435\u043c\u043e\u0439 \u043a\u0440\u0430\u0441\u043e\u0442\u044b \u043e\u0442\u0446\u0435\u043d\u0442\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 TeX-\u0444\u043e\u0440\u043c\u0443\u043b\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u044d\u0441\u0442\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0443\u0434\u043e\u0432\u043e\u043b\u044c\u0441\u0442\u0432\u0438\u044f \u0432\u043c\u0435\u0441\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u0441\u0435\u0440\u044b\u0445-\u0442\u0443\u0441\u043a\u043b\u044b\u0445-\u043d\u0435\u0432\u0437\u0440\u0430\u0447\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u043e\u0432 \u043a\u043e\u0434\u0430<\/del> \u0440\u0430\u0431\u043e\u0442\u0443 \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0430 \u0435\u0449\u0451 \u0447\u0443\u0442\u043e\u0447\u043a\u0443:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/014\/68f\/15c\/01468f15c83d686cb7ff62d63d6ae153.svg\" alt=\"$ blah \\ B \\ () (blah) \\rightarrow \\\\ blah \\ A (blah) \\rightarrow \\\\ blah \\ blah \\ DEFER(B)(blah) \\rightarrow \\\\ blah \\ blah \\ B \\ EMPTY()(blah) \\rightarrow \\\\ blah \\ blah \\ B \\ ()(blah) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/6ee\/3a7\/c47\/6ee3a7c4787e861b56256787246cb6fb.svg\" alt=\"$ blah \\ blah \\ B \\ () (blah) \\rightarrow \\\\ blah \\ blah \\ A (blah) \\rightarrow \\\\ blah \\ blah \\ blah \\ DEFER(B)(blah) \\rightarrow \\\\ blah \\ blah \\ blah \\ B \\ EMPTY()(blah) \\rightarrow \\\\ blah \\ blah \\ blah \\ B \\ ()(blah) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u2026 \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435. \u041a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0430 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e? \u041a\u0430\u043a\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432 \u044f\u0437\u044b\u043a\u0435 \u043f\u043e\u0431\u0443\u0436\u0434\u0430\u0435\u0442 \u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043b\u0435\u043a\u0441\u0435\u043c? \u0410\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432. \u0421 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u0435\u043c \u043c\u043d\u043e\u0433\u043e\u0441\u0442\u0440\u0430\u0434\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043c\u0430\u043a\u0440\u043e\u0441\u0430 <code>EXPAND<\/code>, \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u044e\u0449\u0435\u0433\u043e\u0441\u044f \u0432 \u0441\u0432\u043e\u0438 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/141\/434\/d31\/141434d314c6a5dc034b0fd53476e602.svg\" alt=\"$ A(blah) \\rightarrow blah \\ B \\ ()(blah) \\\\ EXPAND(A(blah)) \\rightarrow blah \\ blah \\ B ()(blah) \\\\ EXPAND(EXPAND(A(blah))) \\rightarrow blah \\ blah \\ blah \\ B \\ ()(blah) \\\\ EXPAND(EXPAND(EXPAND(A(blah)))) \\rightarrow blah \\ blah \\ blah \\ blah \\ B \\ ()(blah) \\\\ \\ldots $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0432\u044b\u0437\u043e\u0432\u043e\u0432 <code>EXPAND<\/code> \u0438 \u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u2014 \u0442\u0430\u043a \u043c\u044b \u0437\u0430\u043f\u043e\u043b\u0443\u0447\u0438\u043c \u0432\u043e\u0436\u0434\u0435\u043b\u0435\u043d\u043d\u0443\u044e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044e. \u0412 map-macro \u043d\u0435 \u0441\u0442\u0430\u043b\u0438 \u043c\u044b\u0441\u043b\u0438\u0442\u044c \u043b\u0443\u043a\u0430\u0432\u043e \u2014 \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0440\u043e\u0432\u043d\u043e 365 \u0440\u0430\u0437:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define EVAL(...)  EVAL4(EVAL4(EVAL4(__VA_ARGS__))) #define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) #define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) #define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) #define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__))) #define EVAL0(...) __VA_ARGS__<\/code><\/pre>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0440\u0430\u0437\u043e\u0432\u043e\u0433\u043e \u0441\u043b\u0443\u0447\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e, \u043d\u043e \u044f \u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043b \u0446\u0435\u043b\u044c \u043f\u043e\u0432\u044b\u0448\u0435 \u2014 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u0431\u044b\u0442\u044c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0443 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u043a\u0430\u043a \u0441\u0442\u0440\u0430\u0448\u043d\u044b\u0439 \u0441\u043e\u043d. \u0421\u043e\u0437\u0435\u0440\u0446\u0430\u0442\u044c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0446\u0438\u044e, \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u0433\u0440\u044f\u0437\u043d\u044b\u0435 \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u043d\u044b\u0435 \u0434\u0435\u043b\u0430 \u0437\u0430 \u043d\u0430\u0441. \u0412 \u0442\u0430\u043a\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u043f\u0440\u0438\u0435\u043c\u043b\u0435\u043c\u043e \u043d\u0438\u0437\u043a\u0438\u0439 \u043f\u0440\u0435\u0434\u0435\u043b 365 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u043f\u043e\u0432\u044b\u0441\u0438\u0442\u044c \u0434\u043e, \u0441\u043a\u0430\u0436\u0435\u043c, <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e27\/2b1\/13c\/e272b113c49a602852355a7673b51611.svg\" alt=\"$2^{16}$\" data-tex=\"inline\"><\/math>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u0434\u0438\u043d \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 \u043c\u043e\u0436\u0435\u0442 \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439, \u0430 \u0442\u043e\u0442 \u2014 \u0442\u0440\u0435\u0442\u0438\u0439, \u0434\u0435\u0441\u044f\u0442\u044b\u0439 \u0438 \u0442.\u0434. \u0412\u0441\u0435\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e27\/2b1\/13c\/e272b113c49a602852355a7673b51611.svg\" alt=\"$2^{16}$\" data-tex=\"inline\"><\/math> \u0440\u0430\u0437 \u2014 \u0441\u043c\u0435\u0440\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0430, \u0441\u0438\u043b\u043e\u0439 \u043c\u044b\u0441\u043b\u0438 \u0430\u043f\u043f\u0440\u043e\u043a\u0441\u0438\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0433\u043b\u0443\u0431\u0438\u043d\u0443 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u2014 \u0441\u043c\u0435\u0440\u0442\u044c \u0434\u043b\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0441\u0442\u0430.<\/p>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"2-potug-ii-obobschyonnaya-rekursiya\">2. \u041f\u043e\u0442\u0443\u0433 II: \u041e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f<\/h1>\n<p>  <\/p>\n<p>\u041a\u043b\u044e\u0447 \u043a \u043f\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u044e \u0441\u0430\u043a\u0440\u0430\u043b\u044c\u043d\u043e\u0439 \u0438\u0441\u0442\u0438\u043d\u044b \u2014 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u2014 \u043b\u044e\u0431\u0430\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u0430\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0438\u043c\u0435\u0435\u0442 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435! \u0422\u0430\u043a \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043c \u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0438\u043c \u0441 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u043c \u0434\u043b\u044f \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u0437\u043d\u0430\u043b \u043a\u043e\u0433\u0434\u0430 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u0432\u0438\u0434\u0430? \u041e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u2014 \u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0435\u043c \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u2014 \u0435\u0441\u043b\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 \u0432\u0435\u0440\u043d\u0443\u043b <code>CONTINUE<\/code> \u2014 \u0437\u043d\u0430\u0447\u0438\u0442 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u043e \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435, \u0435\u0441\u043b\u0438 <code>STOP<\/code> \u2014 \u0437\u043d\u0430\u0447\u0438\u0442 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u043b\u043e\u0441\u044c \u0438 \u043d\u0443\u0436\u043d\u043e \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f. \u041e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u044f \u0432 \u0441\u0430\u043c\u043e\u043c \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u0435 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438! \u0427\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u0434\u043e\u043a\u0441, \u043c\u044b \u0431\u0435\u0441\u0441\u0442\u044b\u0434\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e (<math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e27\/2b1\/13c\/e272b113c49a602852355a7673b51611.svg\" alt=\"$2^{16}$\" data-tex=\"inline\"><\/math>) &quot;\u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0442\u0435\u043b\u0435\u0439&quot;, \u0432\u044b\u0437\u044b\u0432\u0430\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0432 \u043a\u0430\u0436\u0434\u043e\u043c \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c (\u043f\u043e\u0445\u043e\u0436\u0435\u0435 \u043c\u044b \u0434\u0435\u043b\u0430\u043b\u0438 \u0441 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u043c <a href=\"https:\/\/github.com\/Hirrolot\/habr-metalinguistic-seduction\/blob\/f7ef27b5f752b9bb526f649511f37a21f4b2d2fe\/testing-framework\/tests_for_each.h\" rel=\"nofollow\"><code>TESTS_FOR_EACH<\/code><\/a> \u0432 <a href=\"https:\/\/habr.com\/en\/post\/520850\/\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c \u043e\u043f\u0443\u0441\u0435<\/a>).<\/p>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0442\u043e\u0442\u0438\u043f:<\/p>\n<p>  <\/p>\n<p>[<a href=\"https:\/\/godbolt.org\/z\/571GKj\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define EMPTY() #define DEFER(op) op EMPTY()  #define REC REC_0  #define REC_0(x)                    REC_0_OVERLOAD(x) #define REC_0_CONTINUE(x)           REC_1(x) #define REC_0_STOP(...)             __VA_ARGS__ #define REC_0_OVERLOAD(x)           REC_0_OVERLOAD_PRIMITIVE(x) #define REC_0_OVERLOAD_PRIMITIVE(x) REC_0_##x  ...  #define FOO(acc)   CONTINUE(DEFER(FOO_HOOK)()(acc blah)) #define FOO_HOOK() FOO  REC(FOO())<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u043e \u0447\u0442\u043e \u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f <code>REC(FOO())<\/code>:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">REC_3_LIMIT_REACHED(CONTINUE(CONTINUE(CONTINUE(CONTINUE(CONTINUE(CONTINUE(CONTINUE(FOO_HOOK ()(blah blah blah blah blah blah blah blah blah blah)))))))))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0447\u0435\u043c\u0443 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u043c\u043d\u043e\u0433\u043e <code>CONTINUE<\/code> \u0438 <code>blah<\/code>? \u0423 \u043d\u0430\u0441 \u0432\u0435\u0434\u044c \u0432\u0441\u0435\u0433\u043e \u0442\u0440\u0438 \u0443\u0440\u043e\u0432\u043d\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438&#8230;<\/p>\n<p>  <\/p>\n<p>\u0414\u0435\u043b\u043e \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>FOO(blah)<\/code> \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0442\u0440\u0438 \u0440\u0430\u0437\u0430. \u0412\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0439:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_0<\/code>,<\/li>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_0_OVERLOAD<\/code>,<\/li>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_0_OVERLOAD_PRIMITIVE<\/code>,<\/li>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_1<\/code>, &#8230;<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041d\u0430\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0442\u0440\u0438!<\/p>\n<p>  <\/p>\n<p>\u0410\u043d\u0430\u043b\u043e\u0433\u0438\u044f: \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u2014 &quot;\u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044c&quot; \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f, <code>DEFER<\/code> \u2014 &quot;\u0442\u043e\u0440\u043c\u043e\u0437&quot;. \u0417\u043d\u0430\u0447\u0438\u0442 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u0438\u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0440\u0430\u0437, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0434\u0435\u043b\u0430\u043b\u0438 \u043b\u0438\u0448\u043d\u0438\u0445 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0439:<\/p>\n<p>  <\/p>\n<p>[<a href=\"https:\/\/godbolt.org\/z\/xM65vx\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define REC REC_0  #define REC_0(...)                                                                                 \\     REC_0_OVERLOAD(REC_0_GET_CHOICE(__VA_ARGS__))                                                  \\     (REC_0_GET_REST(__VA_ARGS__)) #define REC_0_GET_CHOICE(choice, ...)    choice #define REC_0_GET_REST(choice, ...)      __VA_ARGS__ #define REC_0_OVERLOAD(choice)           REC_0_OVERLOAD_PRIMITIVE(choice) #define REC_0_OVERLOAD_PRIMITIVE(choice) REC_0_##choice #define REC_0_CONTINUE                   REC_1 #define REC_0_STOP(...)                  __VA_ARGS__  ...  #define REC_CONTINUE(hook, ...) CONTINUE, DEFER_2_TIMES(hook)()(__VA_ARGS__) #define REC_STOP(...)           STOP, __VA_ARGS__  #define DEFER_2_TIMES(op) DEFER_0(DEFER_1)(op) #define DEFER_0(op)       op EMPTY() #define DEFER_1(op)       op EMPTY() #define EMPTY()  #define FOO(acc)   REC_CONTINUE(FOO_HOOK, acc blah) #define FOO_HOOK() FOO  REC(FOO())<\/code><\/pre>\n<p>  <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/-5\/vu\/tz\/-5vutzudluareilwxdmcg93aizg.jpeg\"><\/p>\n<p>  <\/p>\n<p>\u0412\u044b\u0432\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">REC_3_LIMIT_REACHED (CONTINUE, DEFER_1 (FOO_HOOK)()(blah blah blah blah))<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 <code>REC_CONTINUE(hook, ...)<\/code>, &quot;\u0437\u0430\u043c\u043e\u0440\u0430\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439&quot; <code>hook<\/code> \u0434\u0432\u0430 \u0440\u0430\u0437\u0430. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043e\u0432\u0435\u0441 \u0435\u043c\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 \u0431\u043b\u043e\u043a <code>REC_*<\/code> \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u0432\u0430 \u0440\u0430\u0437\u0430:<\/p>\n<p>  <\/p>\n<ol>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_0<\/code>,<\/li>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_0_GET_REST<\/code>,<\/li>\n<li>\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 <code>REC_1<\/code>, &#8230;<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041d\u043e \u043f\u043e\u0447\u0435\u043c\u0443 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0447\u0435\u0442\u044b\u0440\u0435 <code>blah<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0442\u0440\u0451\u0445? \u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 <code>blah<\/code> \u2014 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0435\u0440\u0435\u0441\u043a\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0442\u0435\u043b\u0430 <code>REC_0<\/code>. \u0412 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0443\u0431\u0435\u0434\u0438\u0442\u044c\u0441\u044f, \u0432\u044b\u0437\u0432\u0430\u0432 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0438\u043d\u0433\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 <code>REC_2_GET_REST<\/code> (\u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u043c\u0430\u043a\u0440\u043e\u0441\u0430 \u0432 \u043f\u043e\u0437\u0438\u0446\u0438\u0438 <code>#arg<\/code> \u043d\u0435 \u0440\u0430\u0441\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f):<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define REC_2_GET_REST(choice, ...)      PRIMITIVE_CAT(__VA_ARGS__)  ...  #define PRIMITIVE_CAT(x) #x<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u044b\u0432\u043e\u0434:<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">REC_3_LIMIT_REACHED (&quot;FOO_HOOK ()(blah blah blah)&quot;)<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u0435 <code>REC(FOO())<\/code>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/ff8\/87b\/eb4\/ff887beb4a23cf20274fb2108944ee9b.svg\" alt=\"$ REC(FOO()) \\rightarrow \\\\ REC\\_0(FOO()) \\rightarrow \\\\ REC\\_0\\_CONTINUE(REC\\_0\\_GET\\_REST(CONTINUE, \\\\ DEFER\\_1(FOO\\_HOOK)()(blah))) \\rightarrow \\\\ REC\\_0\\_CONTINUE(FOO\\_HOOK()(blah)) \\rightarrow \\\\ REC\\_1(FOO\\_HOOK()(blah)) \\rightarrow \\\\ REC\\_1\\_CONTINUE(REC\\_1\\_GET\\_REST(CONTINUE, \\\\ DEFER\\_1(FOO\\_HOOK)()(blah \\ blah))) \\rightarrow \\\\ \\ldots $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0435\u0442\u0441\u044f, \u0432\u0441\u0451 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435.<\/p>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"3-potug-iii-pobeda\">3. \u041f\u043e\u0442\u0443\u0433 III: \u041f\u043e\u0431\u0435\u0434\u0430!<\/h1>\n<p>  <\/p>\n<p>\u041a\u0442\u043e \u043c\u044b \u0435\u0441\u0442\u044c \u0438 \u0437\u0430\u0447\u0435\u043c \u043c\u044b \u0437\u0434\u0435\u0441\u044c? \u041d\u0430 \u043f\u0435\u0440\u0432\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u0432\u043e\u043f\u0440\u043e\u0441\u0430 \u043c\u043e\u0436\u043d\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043c\u043d\u043e\u0433\u043e\u0433\u0440\u0430\u043d\u043d\u043e, \u0430 \u043d\u0430 \u0432\u0442\u043e\u0440\u0443\u044e \u2014 \u0447\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 Cons-\u0441\u043f\u0438\u0441\u043e\u043a:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e02\/dc8\/259\/e02dc82595761e51e8ffd29ffc812874.svg\" alt=\"$ ((((((((((0), 1), 2), 3), 4), 5), 6), 7), 8), 9) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u0430:<\/p>\n<p>  <\/p>\n<p>[<a href=\"https:\/\/godbolt.org\/z\/fnjjbn\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">...  #define GEN(acc, i) IF(EQ(i, 9), STOP, PROGRESS)(acc, i) #define GEN_HOOK()  GEN  #define STOP(acc, i)     REC_STOP(acc) #define PROGRESS(acc, i) REC_CONTINUE(GEN_HOOK, (acc, INC(i)), INC(i))<\/code><\/pre>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"4-cps-abstragirovanie-ot-prodolzheniya\">4. CPS: \u0410\u0431\u0441\u0442\u0440\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f<\/h1>\n<p>  <\/p>\n<p>\u0421 <code>REC_STOP<\/code> \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u043a\u0430: \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0435 \u043c\u0430\u043a\u0440\u043e\u0441\u044b \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u043d\u0435\u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438: \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0447\u0442\u043e \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 <code>A<\/code> \u0432\u044b\u0437\u0432\u0430\u043b \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 <code>B<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f <code>B<\/code> \u0432\u0435\u0441\u044c \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0438 <code>A<\/code> \u043d\u0435 \u0441\u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<p>\u041a \u0441\u0447\u0430\u0441\u0442\u044c\u044e, \u0434\u0435\u0434\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u044d\u0442\u0443 \u0437\u0430\u0434\u0430\u0447\u0443 \u0437\u0430 \u043d\u0430\u0441 \u0446\u0435\u043b\u044b\u0445 45 \u043b\u0435\u0442 \u043d\u0430\u0437\u0430\u0434. \u041d\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuation-passing_style\" rel=\"nofollow\">\u0441\u0442\u0438\u043b\u044c \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 (CPS, continuation-passing style)<\/a> \u2014 \u043a\u043e\u0433\u0434\u0430 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuation\" rel=\"nofollow\">\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435<\/a> (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Reification_(computer_science)\" rel=\"nofollow\">\u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0439<\/a> \u043f\u043e\u0442\u043e\u043a \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f; \u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u2014 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441) \u044f\u0432\u043d\u043e <em>\u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f<\/em> \u0432 \u0432\u0438\u0434\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0443\u044e \u044d\u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u043f\u0440\u0438 \u0442\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043c\u043e\u0433\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f (\u043b\u044f\u043c\u0431\u0434\u0430 \u0438\u043b\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f). \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0435 \u0433\u0438\u043f\u043e\u0442\u0435\u043d\u0443\u0437\u044b \u043f\u0440\u044f\u043c\u043e\u0443\u0433\u043e\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0440\u0435\u0443\u0433\u043e\u043b\u044c\u043d\u0438\u043a\u0430 \u0432 \u043f\u0440\u044f\u043c\u043e\u043c \u0441\u0442\u0438\u043b\u0435 \u0438 \u0432 CPS:<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u044f\u043c\u043e\u0439 \u0441\u0442\u0438\u043b\u044c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>[<a href=\"https:\/\/godbolt.org\/z\/KTfejY\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#include &lt;math.h&gt; #include &lt;stdio.h&gt;  #define let __auto_type  #define $(return_type, params, body) \\     ({return_type fn params { return body; } fn;})  int main(void) {     let hypotenuse = $(double, (double x, double y), sqrt(x * x + y * y));      printf(&quot;%f\\n&quot;, hypotenuse(3, 4)); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">CPS<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>[<a href=\"https:\/\/godbolt.org\/z\/MTzPKM\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#include &lt;math.h&gt; #include &lt;stdio.h&gt;  #define let __auto_type  #define $(return_type, params, body) \\     ({return_type fn params { return body; } fn;})  int main(void) {     let my_sqrt = $(double, (double x, double (*k)(double y)), k(sqrt(x)));     let my_pow = $(double, (double x, double (*k)(double y)), k(x * x));     let add = $(double, (double x, double y, double (*k)(double z)), k(x + y));      let hypotenuse = $(double, (double a, double b, double (*k)(double n)),         my_pow(a,             $(double, (double a2),                 my_pow(b,                     $(double, (double b2),                         add(a2, b2,                             $(double, (double a2b2), my_sqrt(a2b2, k))                         )                     )                 )             )         )     );      printf(&quot;%f\\n&quot;, hypotenuse(3, 4, $(double, (double x), x))); }<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u0422\u0430\u043a \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0436\u0435 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0439 \u043c\u0430\u043a\u0440\u043e\u0441 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0442\u044c \u0434\u0432\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430: <code>k<\/code> (\u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435) \u0438 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 <code>k_cx<\/code> (\u043c\u0430\u043a\u0440\u043e\u0441\u044b \u043d\u0435 \u043c\u043e\u0433\u0443\u0442 \u0437\u0430\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0440\u0435\u0434\u0443), \u0430 \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 <code>k<\/code>. \u041f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 <code>REC_CONTINUE<\/code> \u0438 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u0442\u044c <code>REC_STOP<\/code> \u0432 \u043e\u0441\u043e\u0431\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435:<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define REC_CONTINUE(k, k_cx, ...) CONTINUE, DEFER_2_TIMES(k)()(UNPARENTHESISE(k_cx), __VA_ARGS__)  #define REC_STOP()               REC_STOP_AUX #define REC_STOP_AUX(_k_cx, ...) STOP, __VA_ARGS__<\/code><\/pre>\n<p>  <\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f Cons-\u0441\u043f\u0438\u0441\u043a\u0430 \u043f\u0440\u0438\u043c\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0444\u043e\u0440\u043c\u0443:<\/p>\n<p>  <\/p>\n<p>[<a href=\"https:\/\/godbolt.org\/z\/EKT447\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">#define GEN(k, k_cx, acc, i) IF(EQ(i, 9), STOP, PROGRESS)(k, k_cx, acc, i) #define GEN_HOOK()           GEN  #define STOP(k, k_cx, acc, i)     REC_CONTINUE(k, (k_cx), acc) #define PROGRESS(k, k_cx, acc, i) REC_CONTINUE(GEN_HOOK, (k, k_cx), (acc, INC(i)), INC(i))  REC(GEN(REC_STOP, ~, (0), 0))<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <code>REC(GEN(REC_STOP, ~, (0), 0))<\/code>. <code>REC_STOP<\/code> \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0451\u043d \u0432 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435, \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u044e\u0449\u0435\u0435 \u0434\u0432\u0438\u0433\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u2014 \u043c\u0430\u043a\u0440\u043e\u0441 <code>STOP<\/code> \u043f\u0440\u0438 \u0434\u043e\u0441\u0442\u0438\u0436\u0435\u043d\u0438\u0438 \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0440\u0430\u0441\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0432 <code>REC_CONTINUE(REC_STOP, (k_cx), acc)<\/code>.<\/p>\n<p>  <\/p>\n<p>\u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0434\u0432\u0443\u0445 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432: \u043f\u043e\u0441\u043b\u0435 Cons-\u0441\u043f\u0438\u0441\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0432\u0442\u043e\u0440\u043e\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0432 \u0444\u043e\u0440\u043c\u0435 <code>(a)(b)(c)...<\/code>:<\/p>\n<p>  <\/p>\n<p>[<a href=\"https:\/\/godbolt.org\/z\/3PdjMc\" rel=\"nofollow\">godbolt<\/a>]<\/p>\n<p>  <\/p>\n<pre><code class=\"cpp\">\/\/ (((a), b), c)  #define GEN(k, k_cx, acc, i) IF(EQ(i, 9), STOP, PROGRESS)(k, k_cx, acc, i) #define GEN_HOOK()           GEN  #define STOP(k, k_cx, acc, i)     REC_CONTINUE(GEN_2_HOOK, (k, (k_cx, acc)), acc, 0) #define PROGRESS(k, k_cx, acc, i) REC_CONTINUE(GEN_HOOK, (k, k_cx), (acc, INC(i)), INC(i))  \/\/ (a)(b)(c)  #define GEN_2(k, k_cx, acc, i) IF(EQ(i, 9), STOP_2, PROGRESS_2)(k, k_cx, acc, i) #define GEN_2_HOOK()           GEN_2  #define STOP_2(k, k_cx, acc, i)     REC_CONTINUE(k, (k_cx), acc) #define PROGRESS_2(k, k_cx, acc, i) REC_CONTINUE(GEN_2_HOOK, (k, k_cx), acc(INC(i)), INC(i))<\/code><\/pre>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0412\u044b\u0432\u043e\u0434<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">((((((((((0), 1), 2), 3), 4), 5), 6), 7), 8), 9)(1)(2)(3)(4)(5)(6)(7)(8)(9)<\/code><\/pre>\n<\/div><\/div>\n<p>  <\/p>\n<hr>\n<p>  <\/p>\n<h1 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u041f\u0438\u0441\u0430\u0442\u044c \u0432 \u0441\u0442\u0438\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439 \u2014 \u0441\u0435\u0431\u044f \u043d\u0435 \u043b\u044e\u0431\u0438\u0442\u044c. \u0412 \u0438\u0434\u0435\u0430\u043b\u0435 \u0431\u044b \u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c, \u043f\u0440\u044f\u043c\u043e\u043c \u0441\u0442\u0438\u043b\u0435, \u0432 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u043d\u0435 \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u0432\u0430\u044f \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c\u0438 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438\u2026 \u0442\u0430\u043a\u0430\u044f \u0448\u0430\u0439\u0442\u0430\u043d-\u043c\u0430\u0448\u0438\u043d\u0430 \u0443\u0436\u0435 <a href=\"https:\/\/github.com\/Hirrolot\/macrolop\/tree\/318d624a012a51739246bdf0e8c182b2386b213a\/include\/macrolop\/eval\" rel=\"nofollow\">\u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u0430<\/a> \u043c\u043d\u043e\u044e. \u041e\u0431 \u044d\u0442\u043e\u043c \u2014 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u043e\u043f\u0443\u0441\u0435.<\/p>\n<\/div>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/523606\/\"> https:\/\/habr.com\/ru\/post\/523606\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"\n<div class=\"post__text post__text-html post__text_v1\" id=\"post-content-body\">\n<p><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/webt\/ij\/9p\/-n\/ij9p-nygxt17eoxodrwteoi07-m.jpeg\"><\/p>\n<p>  <\/p>\n<p><a href=\"https:\/\/youtu.be\/QNpuUXcm5zw?t=526\" rel=\"nofollow\"><em>&gt;&gt; \u041e\u0441\u0442\u043e\u0440\u043e\u0436\u043d\u043e, \u043c\u043e\u0434\u0435\u0440\u043d! 2 \u2014 0.2. \u041f\u0440\u043e\u043f\u0430\u0436\u0430 \u0437\u0430\u043d\u0430\u0447\u043a\u0438<\/em><\/a><\/p>\n<p>  <\/p>\n<p><em>\u0413\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u0432 15 \u043b\u0435\u0442, \u043c\u0435\u043d\u044f \u043e\u0437\u0430\u0434\u0430\u0447\u0438\u043b\u0430 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 compile-time \u0438\u043c\u0438\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Algebraic_data_type\" rel=\"nofollow\">\u0430\u043b\u0433\u0435\u0431\u0440\u0430\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0442\u0438\u043f\u043e\u0432 \u0434\u0430\u043d\u043d\u044b\u0445<\/a> \u0432 \u0447\u0438\u0441\u0442\u043e\u043c \u0421\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u044f \u0441\u043e\u0437\u0434\u0430\u043b <a href=\"https:\/\/github.com\/Hirrolot\/poica\" rel=\"nofollow\">poica<\/a> \u2014 \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a \u043d\u0430 \u043c\u0430\u043a\u0440\u043e\u0441\u0430\u0445. \u0421\u0435\u0440\u0438\u044f \u044d\u0442\u0438\u0445 \u043e\u043f\u0443\u0441\u043e\u0432 \u2014 \u043b\u043e\u0433\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u043c\u043e\u0435\u0433\u043e \u0438\u0441\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f.<\/em><\/p>\n<p>  <\/p>\n<h1 id=\"predislovie\">\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u041c\u0430\u043a\u0440\u043e\u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0421\u0438 \u044f\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u0430\u043d\u0430\u043b\u043e\u0433 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Rewriting\" rel=\"nofollow\">\u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0435\u0440\u043c\u043e\u0432<\/a> \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e\u0439 \u0422\u044c\u044e\u0440\u0438\u043d\u0433-\u043f\u043e\u043b\u043d\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0439 \u043c\u043e\u0434\u0435\u043b\u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439 \u2014 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Lambda_calculus\" rel=\"nofollow\">\u043b\u044f\u043c\u0431\u0434\u0430-\u0438\u0441\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044f<\/a>. \u0418\u043c\u0435\u044f \u0432 \u0430\u0440\u0441\u0435\u043d\u0430\u043b\u0435 \u044d\u0442\u0443 \u043d\u0435\u0432\u044b\u043d\u043e\u0441\u0438\u043c\u043e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044e, \u043c\u043e\u0436\u043d\u043e, \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u043e\u0434\u043d\u0438\u043c\u0438 \u043c\u0430\u043a\u0440\u043e\u0441\u0430\u043c\u0438 \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043b\u044e\u0431\u043e\u0439 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c, \u043f\u043e\u0434\u0434\u0430\u044e\u0449\u0438\u0439\u0441\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0432 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u0435 \u044f\u0437\u044b\u043a\u043e\u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f!<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u0435\u0441\u0442\u044c \u043e\u0434\u043d\u043e &quot;\u043d\u043e&quot;: \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u0430 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 (macro blueprinting), \u0437\u0430\u0448\u0438\u0442\u0430\u044f \u043f\u0440\u044f\u043c\u043e \u0432 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u043c \u043f\u0440\u0435\u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440\u0435 \u2014 \u0438\u043c\u0435\u043d\u043d\u043e \u043e\u043d\u0430 <a href=\"https:\/\/www.ioccc.org\/2001\/herrmann1.hint\" rel=\"nofollow\">\u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0443\u0435\u0442<\/a> \u043c\u0430\u043d\u0438\u043f\u0443\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044e \u043a\u043e\u043b\u043b\u0435\u043a\u0446\u0438\u044f\u043c\u0438 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u043e\u0439 \u0434\u043b\u0438\u043d\u044b, \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u044e <a href=\"https:\/\/en.wikipedia.org\/wiki\/Ackermann_function\" rel=\"nofollow\">\u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0410\u043a\u043a\u0435\u0440\u043c\u0430\u043d\u0430<\/a> \u0438 \u043c\u043d\u043e\u0433\u0438\u043c \u0434\u0440\u0443\u0433\u0438\u043c \u0432\u0435\u0449\u0430\u043c; \u0434\u0430\u0436\u0435 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fixed-point_combinator#Y_combinator\" rel=\"nofollow\">Y \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440<\/a> \u043d\u0435 \u0432 \u0441\u0438\u043b\u0430\u0445 \u043f\u043e\u043c\u043e\u0447\u044c \u0432\u0432\u0438\u0434\u0443 <a href=\"https:\/\/en.wikipedia.org\/wiki\/First-class_citizen\" rel=\"nofollow\">\u043d\u0435\u043f\u0435\u0440\u0432\u043e\u043a\u043b\u0430\u0441\u0441\u043d\u043e\u0439<\/a> \u043f\u0440\u0438\u0440\u043e\u0434\u044b \u043c\u0430\u043a\u0440\u043e\u0441\u043e\u0432.<\/p>\n<p>  <\/p>\n<p>\u041d\u043e \u044d\u0442\u043e \u043d\u0430\u0441 \u043d\u0435 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442! \u041d\u0435 \u043c\u043e\u0436\u0435\u0448\u044c \u0440\u0435\u0448\u0438\u0442\u044c \u0437\u0430\u0434\u0430\u0447\u0443 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u2014 \u0440\u0435\u0448\u0438 \u0435\u0451 \u0447\u0430\u0441\u0442\u0438\u0447\u043d\u043e. \u0421\u0435\u0439 \u043e\u043f\u0443\u0441 \u043f\u043e\u0441\u0432\u044f\u0449\u0451\u043d \u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c\u0443 \u043e\u0431\u043e\u0431\u0449\u0451\u043d\u043d\u043e\u0439 \u043c\u0430\u043a\u0440\u043e\u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0438 \u0432 <a href=\"https:\/\/en.wikipedia.org\/wiki\/Continuation-passing_style\" rel=\"nofollow\">\u0441\u0442\u0438\u043b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0439<\/a> \u043d\u0430 <a href=\"https:\/\/github.com\/pfultz2\/Cloak\/wiki\/C-Preprocessor-tricks,-tips,-and-idioms#deferred-expression\" rel=\"nofollow\">\u043e\u0442\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u043a\u0440\u043e\u0440\u0430\u0441\u043a\u0440\u044b\u0442\u0438\u044f\u0445<\/a>.<\/p>\n<p>  <\/p>\n<p>\u0426\u0435\u043b\u044c \u2014 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cons\" rel=\"nofollow\">Cons-\u0441\u043f\u0438\u0441\u043e\u043a<\/a>:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/formulas\/e02\/dc8\/259\/e02dc82595761e51e8ffd29ffc812874.svg\" alt=\"$ ((((((((((0), 1), 2), 3), 4), 5), 6), 7), 8), 9) $\" data-tex=\"display\"><\/math><\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043f\u0440\u0435\u0434\u0441\u0442\u043e\u0438\u0442 \u043f\u0440\u043e\u0442\u0430\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u043a\u0432\u0430\u0436\u0438\u043d\u0443 \u0432 \u043f\u0440\u043e\u0434\u0432\u0438\u043d\u0443\u0442\u043e\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435\u2026 \u043d\u043e \u0445\u0432\u0430\u0442\u0438\u0442 \u0443\u0436\u0435 \u043b\u043e\u0445\u043c\u0430\u0442\u0438\u0442\u044c \u0431\u0430\u0431\u0443\u0448\u043a\u0443, \u0441\u043a\u043e\u0440\u0435\u0435 \u043f\u043e\u0434 \u043a\u0430\u0442!<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-312846","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/312846","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=312846"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/312846\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=312846"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=312846"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=312846"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}