23 comments

[ 0.25 ms ] story [ 53.9 ms ] thread
(comment deleted)
No, I think that practical uses of templates come largely down to simple parametrization, with the exception of a bunch of things that you don't tend to need to hack together yourself anymore since they were incorporated into the stdlib and then elided into builtins from there (mostly thinking of traits and variadic template args here).

But I think the boundary pushing was extremely valuable for seeing how far you could push a lot of these compile time ideas into a language that's ostensibly a traditional imperative language. The recent glut of new compiled languages probably owes quite a bit to seeing the potential of what can be done here mixed with the frustration of how complicated it makes things in C++.

Sorry, I thought my comment came out a bit too judgmental, so I nuked it. (I was saying that templates were mostly useful as simple parameterization, and that the only reason to master this stuff was to read other people's code.)
The key here is to be objective, not falling on a flame thread. C++ templates are ugly, I'm agree, but they are useful and heavily used. Lets make them simple to use with some abstractions.
Metaprogramming with Old C++: The Haskell Metaphor: https://github.com/mooseman/pdutils/blob/master/template_pse...
I've first encountered these techniques in Alexandrescu's Modern C++ Design. The most interesting for me was how one arrives to such solutions [in C++]. Later, I read SICP (which was the first time I touched FP) and everything got much more sense...
It's still the "obscure, magical, and freaking way to abuse the compiler it was at the beginning." It's just that the syntax for doing it has been improved. Just because term-rewriting systems are Turing complete doesn't mean one should program that way. Someday, someone may have to fix the code.

On the other hand, if you provide a full programming language, loops and all, at compile time, as LISP does, people go overboard with language extensions. LISP and PL/I were probably the last languages to go that far. There was a fad for "extensible languages" about 30 years ago, but it died out - programs were too hard to maintain.

Not sure you're caught up... http://clojure.org/

It's not the most popular language, but it's well respected for exactly the reasons you say LISP died out.

Sure, it's used in, what, 0.01% of practical, useful projects in the wild? What a success story...
Funny enough, I do a lot of Emacs Lisp. Maybe it's "only" a scripting language in this sense, but I'm sure many people who have been using Emacs for over 5 years start using it to automate their workflows.

One day, a Lisp will rule the world. Maybe it will be called C# or Java.

"Lisp doesn't look any deader than usual to me."

— David Thornley, in reply to a question older than most programming languages (http://lispers.org)

It sounds like "extensible languages" lives on in the Racket language.
(comment deleted)
> Thats all! Simple, isn’t it? Here’s std::decay in the Turbo way:

  template< class T >
  struct decay {
      using U = tml::eval<std::remove_reference<T>>;
      
      using type = tml::eval<
		   tml::conditional<
				    std::is_array<U>,
				    tml::eval<std::remove_extent<U>>*,
				    tml::conditional<
						     std::is_function<U>,
						     std::add_pointer<U>,
						     std::remove_cv<U>
						    >
				   >
			    >;
  };
> I found it much more readable. What do you think?

I think:

1. Programming in XML notation is starting to look good, suddenly.

2.

  (def-compile-time-gizmo decay (x)
    (let ((u (remove-reference x)))
      (cond
        ((is-array u) (remove-extent u))
        ((is-function u) (add-pointer u))
        (t (remove-cv u)))))
3. Why isn't tml::conditional just called tml::if, if it (evidently) only takes three arguments: expr, then, else?
3: Probably because if is a keyword and can't be used. (And it's based on ''std::conditional'' standardized in C++ 11, but that's begging the question.)
Exactly. if is a C++ keyword. I selected tml::conditional following the Standard std::conditional. The boost::mpl library uses mpl::if_, for example.
"Programming in XML notation is starting to look good, suddenly" I hate the typename ::type pattern. tml::eval helps a lot, but still involves a lot of nested template "calls". To deal with this, I'm working on a continuation system for C++ templates: https://github.com/Manu343726/Flux
How much does a codebase have to be worth to justify programming like this?

It seems like if there's one or two guys, they'll just use haskell, or o'caml or f#, and skip this complexity.

I'm guessing a company must have 40-50 engineers, with one super critical execution path that must be separated out to support this style. Maybe 10% of the team has to interact with this style code? Maybe $5 mil in engineering labor - a $50 mil/year company?

As I said in the post, common day to day C++ has (usually) nothing to do with metaprogramming. But huge generic libraries, like most of the STL implementations, rely heavily on template metaprogramming.

Those libraries usually have their own hardcoded tricks and metafunctions. What I'm trying with Turbo is to provide all that functionality in a portable and easy way.

I'm a full-time C++ programmer, and I keep up with the language pretty well, but I absolutely hate template meta-programming. We use it in parts of our codebase at work and I always dread when I have to interact with those parts of the code.

It's horribly ugly and verbose compared to other languages, like Lisp, that basically solve the same problem of computation at compile time. Even this library that supposedly cleans things up is pretty ugly as far as I'm concerned.

It's incredibly slow to compile. Somebody posted "Conway's Game of Life in TMP" the other day, and one of the template parameters was the number of frames to generate at compile time. I changed it from 3 to 10 and kicked off a compilation, and it ran for over 12 hours, used 10+ Gb of RAM, and still hadn't finished when I killed it the next day. I can do the same thing in Lisp, also at compile time, and it'll be a fraction of the code, easier to read, the same syntax as usual Lisp, and execute in negligible time for 10 frames.

And don't get me started on the error messages. Clang is pretty good, but it's still not good enough.

And the worst part of TMP is that due to the other problems with it, it's considered "black magic" by many people and so they don't bother learning it.

Until some of the problems are fixed, I don't think TMP will ever take off and become popular. It's just too hard to work with.

I guess I'm biased by writing a lot of Lisp in my free time lately. Lisp solved the same problem TMP is trying to solve, infinitely better, 50 years ago.

> Until some of the problems are fixed, I don't think TMP will ever take off and become popular. It's just too hard to work with.

Perhaps, although I've seen expression templates a few times in the wild.