Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Using a hierarchy to show template errors is brilliant and I'm sort of surprised compilers haven't always done that.

I was investigating C++-style templates for a hobby language of mine and SFINAE is an important property to make them work in realistic codebases, but leads to exactly this problem. When a compile error occurs, there isn't a single cause, or even a linear chain of causes, but an potentially arbitrarily large tree of them.

For example, it sees a call to foo() and there is a template foo(). It tries to instantiate that but the body of foo() calls bar(). It tries to resolve that and finds a template bar() which it tries to instantiate, and so on.

The compiler is basically searching the entire tree of possible instantiations/overloads and backtracking when it hits dead ends.

Showing that tree as a tree makes a lot of sense.



Only if stuck in C++17 and earlier.

Past that point SFINAE should be left for existing code, while new code should make use of concepts and compile time execution.


I really wish templates didn't work on a dumb "replace at call site until something compiles" manner.

All template requirements should be verified at the function definition, not at every call site.

There is concepts. But they are so unwieldy.


It's honestly a seriously hard problem.

Yes, it's definitely nice to be able to typecheck generic code before instantiation. But supporting that ends up adding a lot of complexity to the typesystem.

C++-style templates are sort of like "compile-time dynamic types" where the type system is much simpler because you can just write templates that try to do stuff and if the instantiation works, it works.

C++ templates are more powerful than generics in most other languages, while not having to deal with covariance/contravariance, bounded quantification, F-bounded quantification, traits, and all sorts of other complex machinery that Java, C#, etc. have.

I still generally prefer languages that do the type-checking before instantiation, but I think C++ picks a really interesting point in the design space.


Please no. Templates being lazy is so much better than Rust's eager trait evaluation, the latter causing incredible amounts of pain beyond a certain complexity threshold.


How so? I'd really like to see an example. If you can't explain what requirements your function has before calling it then how do you know it even does what you expect?


C++0x concepts tried to achieve that but that didn't work.

(But Rust traits works like that)


There were lots of politics evolved, moreso than technical issues.

While not perfect concepts lite, alongside compile time evaluation do the job.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: