News for hackers. Stuff that matters.
Re:"14 Years of Go" by Rob Pike by trealira on Tuesday February 27, 2024 @02:15PM (#39528321)
How can you? Genuinely asking. You can overload operator + or operator *, but how could you make a dedicated ternary (three-way) operator that combines those two operations into something like std::fma? I guess you could overload the function call operator, but that doesn't offer much over just defining a function.
Re:"14 Years of Go" by Rob Pike by danieldk on Tuesday February 27, 2024 @02:47PM (#39528793)
You define operators on your e.g. Vector types to construct a type that represents lazy evaluation of the expressions and reflect the operations at the type level. So for a * b + c you would get a type like Add<Mul<Vec, Vec>, Mul>.

The evaluation then happens as assignment or Vec construction when you have something like:

    Vec r = a * b + c
You could either inline the functions on Mul and Add in the evaluation loop and rely on the compiler to deduce that an FMA instruction can be used. In the unlucky case, you at least avoid the intermediate a * b vector.

Another option, since the expression is represented at the type level is to write a compile-time evaluator that replaces patterns like Add<Mul<Vec, Vec>, Mul> by FMA<Vec, Vec, Vec> using templates.

This general idea is the foundation of libraries like Eigen.

Re:"14 Years of Go" by Rob Pike by trealira on Tuesday February 27, 2024 @03:29PM (#39529421)
Thanks for this response as well. I didn't see it earlier. It seems pretty interesting what you can do with C++ templates.
Re:"14 Years of Go" by Rob Pike by tsimionescu on Tuesday February 27, 2024 @02:38PM (#39528669)
You can have the result of * not be the actual multiplication, but a MultiplicationExpression. Then, the result of MultiplicationExpression + Matrix is a MultiplyAddExpression.

Finally you overload the dereference operator of MultiplyAddExpression to actually run std::fma. With some template magic, this can all even be done at compile time.

You can look at boost::phoenix and boost::qi to see this taken to a huge extreme, overriding all of the C++ operators to write parsers using regex-like syntax (e.g. `parser = *a | +b;` generates a parser which recognizes "" or "aaa" or "bb", equivalent to the regex "a*|b+").

Re:"14 Years of Go" by Rob Pike by trealira on Tuesday February 27, 2024 @02:43PM (#39528737)
That makes a lot of sense, thanks. I hadn't even thought about that. I guess you could also have MultiplicationExpression have an implicit coercion operator so you can use it in places where a matrix is expected, which would just compute the multiplication without any corresponding addition. That's pretty interesting.