TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

C++ template macroprogramming versus Lisp macros

99 pointsby oumua_don176 months ago

13 comments

pjmlp6 months ago
Factorial macro example in C++23 metaprogramming,<p><pre><code> #include &lt;iostream&gt; consteval long factorial (int n) { if (n == 0) return 1; return n * factorial(n - 1); } int main() { std::cout &lt;&lt; factorial(7) &lt;&lt; std::endl; } </code></pre> Exercise for the reader if using VC++ or clang&#x2F;ninja, use <i>import std</i> instead.<p>-- <a href="https:&#x2F;&#x2F;godbolt.org&#x2F;z&#x2F;TWe11hM6j" rel="nofollow">https:&#x2F;&#x2F;godbolt.org&#x2F;z&#x2F;TWe11hM6j</a><p>Nicely put 5040 in ESI register at compile time.<p>Granted, C++ isn&#x27;t Lisp, but already has quite a room for creativity at compile time, and C++26 might finally have compile time reflection as well.
评论 #42153652 未加载
评论 #42151697 未加载
评论 #42156959 未加载
评论 #42158279 未加载
评论 #42154283 未加载
评论 #42152632 未加载
评论 #42153973 未加载
thunkingdeep6 months ago
Common misconception of non Lispers that macros are equivalent to compile time programming. You’re not simply moving the evaluation to compile time, you’re moving it upwards outside the program space into a higher dimension of programmability.<p>Not to dog on C++ unfairly, CTE is pretty neat after all.<p>Funnily enough, PGs “On Lisp” has some really neat macros in it that demonstrate capabilities that just can’t be replicated with template based macros, iirc.
评论 #42152815 未加载
lispm6 months ago
<p><pre><code> (defmacro factorial (n) (labels ((fact (m) (if (= m 0) 1 (* m (fact (1- m)))))) `,(fact n))) </code></pre> The `, has no use here and can be removed. Here the backquote and the evaluation just returns the computed value.<p>Thus, this is okay:<p><pre><code> (defmacro factorial (n) (labels ((fact (m) (if (= m 0) 1 (* m (fact (1- m)))))) (fact n))) </code></pre> LABELS defines local recursive functions. The macro returns the result of calling FACT, which is a number and which is a valid <i>form</i> in Common Lisp. A number evaluates to itself.<p><pre><code> CL-USER &gt; (macroexpand-1 &#x27;(factorial 10)) 3628800 T</code></pre>
scott_s6 months ago
Agreed with the technical content and conclusion. However, I think it is worth pointing out that since C++11, it has had a mechanism to specify (maybe) compile-time computations that are written in plain C++: constexpr, <a href="https:&#x2F;&#x2F;en.cppreference.com&#x2F;w&#x2F;cpp&#x2F;language&#x2F;constexpr" rel="nofollow">https:&#x2F;&#x2F;en.cppreference.com&#x2F;w&#x2F;cpp&#x2F;language&#x2F;constexpr</a><p>(My parenthetical &quot;maybe&quot; is that I don&#x27;t think compilers <i>have</i> to compute constexpr expressions at compile time. The compiler will be forced to when such expressions are used in contexts that require values at compile time. But I think it would be permissible for a compile to defer computation of a constexpr to runtime if the value isn&#x27;t needed until runtime.)
评论 #42151035 未加载
评论 #42151149 未加载
liontwist6 months ago
Lisp macros can take arbitrary parameters and are written in lisp.<p>C++ macros can only take types and numbers (until variadic), and writing any code to operate on those inputs is challenging.
评论 #42151117 未加载
评论 #42150840 未加载
评论 #42154445 未加载
评论 #42153182 未加载
unnah6 months ago
C++ templates do have the advantage that they can dispatch on their argument types. Lisp macros are expanded at a purely syntactic level, well before the compiler attempts to do any type deduction, and you cannot provide different macro expansions for different argument types without heroic efforts (which will most likely be specific to a single Lisp compiler). Dispatching on argument types is very useful in expression template based metaprogramming, for example in the Eigen library for linear algebra (<a href="https:&#x2F;&#x2F;eigen.tuxfamily.org&#x2F;" rel="nofollow">https:&#x2F;&#x2F;eigen.tuxfamily.org&#x2F;</a>).
rottc0dd6 months ago
Another post comparing C and lisp Macros: <a href="http:&#x2F;&#x2F;lists.warhead.org.uk&#x2F;pipermail&#x2F;iwe&#x2F;2005-July&#x2F;000130.html" rel="nofollow">http:&#x2F;&#x2F;lists.warhead.org.uk&#x2F;pipermail&#x2F;iwe&#x2F;2005-July&#x2F;000130.h...</a><p>HN discussion: <a href="https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=31199992">https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=31199992</a>
binary1326 months ago
It’s clumsy because C++ templates are an implementation of generic and dependent types, while C++ constexpr and consteval functions are for arbitrary computation. The fact that template metaprogramming _can_ be used for arbitrary computation is actually an unhappy accident of its design that was only proven after its publication.
James_K6 months ago
Macaroni art versus the Mona Lisa.
mgaunard6 months ago
Does this article have a (2002) that I missed or something?
评论 #42153978 未加载
forrestthewoods6 months ago
I don’t have any experience with Lisp. But I think C++ templates and Rust macros are both super bad and impoverished compared to what can be done in Jai.<p><a href="https:&#x2F;&#x2F;www.forrestthewoods.com&#x2F;blog&#x2F;using-jais-unique-and-powerful-compiler-for-typesafe-units&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.forrestthewoods.com&#x2F;blog&#x2F;using-jais-unique-and-p...</a>
评论 #42151960 未加载
评论 #42182497 未加载
评论 #42151606 未加载
mwkaufma6 months ago
The &quot;next&quot; field in the lead code sample is supposed to be a pointer, right?
anothername126 months ago
Pffft, I’d just #. that factorial call and it’d be a normal defun.