www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Template value inference: closing the UFCS gap for template value

reply FeepingCreature <feepingcreature gmail.com> writes:
Right now, we can write format("Hello %s", 5), or we can write 
"Hello %s".format(5). This is an appealing syntax that also 
appears in other languages like Python.

To take advantage of compile-time parameter checking, we can also 
pass the format string as a template parameter: format!"Hello 
%s"(5). If I'd called with (5, 6), it would have been a compile 
error. However, there is no equivalent UFCS syntax for 
templated-formatstring format!

Forms like "Hello %s".!format(5) seem obvious, but look ugly. 
Luckily, there's an easier way.

With something like format("Hello %s", 5); the types of the 
parameters to format are translated into template type arguments; 
in other words, this is equivalent to format!int("Hello %s", 5). 
Let's call this template type inference.

Since D templates have value parameters, this suggests an 
analogous process of template value inference. How would this 
look?

void format(string fmt, T...)(fmt, T args);

In other words, we specialize format for the *value* of the 
template parameter fmt, and then let IFTI/template inference do 
the work of figuring out the appropriate template instantiation, 
exactly as before.

With this change, format!"..." would no longer be necessary at 
all; all format calls of the form format("format string", args) 
would be templated on the string's value, as they already are on 
the argument types.

Thoughts?
Aug 04 2019
next sibling parent reply Olivier FAURE <couteaubleu gmail.com> writes:
On Monday, 5 August 2019 at 06:49:32 UTC, FeepingCreature wrote:
 Since D templates have value parameters, this suggests an 
 analogous process of template value inference. How would this 
 look?

 void format(string fmt, T...)(fmt, T args);
I'd suggest void format(enum Fmt: string, T...)(Fmt fmt, T args); That said, does the use case of needing UFCS with a template for a formatting string come up *that* often?
Aug 05 2019
parent FeepingCreature <feepingcreature gmail.com> writes:
On Monday, 5 August 2019 at 08:42:29 UTC, Olivier FAURE wrote:
 On Monday, 5 August 2019 at 06:49:32 UTC, FeepingCreature wrote:
 Since D templates have value parameters, this suggests an 
 analogous process of template value inference. How would this 
 look?

 void format(string fmt, T...)(fmt, T args);
I'd suggest void format(enum Fmt: string, T...)(Fmt fmt, T args);
Seems extraneous. Enums are not types, fmt is not a variable. You'd basically be messing with the type system (introducing static single-value types, similar to the range propagation magic) for the sake of syntax. Besides, we already have a syntax for template value parameters.
 That said, does the use case of needing UFCS with a template 
 for a formatting string come up *that* often?
I mean, we're using format!"" exclusively, for typechecked safety. We actually have a regex that translates "foo".format() into format!"foo"() form. It would be nice to not have to do that, especially since ufcs form really is more readable. More than that, though, it is such a logical extension of how templates already work that I think it should work for that reason alone.
Aug 05 2019
prev sibling parent reply Nick Treleaven <nick geany.org> writes:
On Monday, 5 August 2019 at 06:49:32 UTC, FeepingCreature wrote:
 void format(string fmt, T...)(fmt, T args);

 In other words, we specialize format for the *value* of the 
 template parameter fmt, and then let IFTI/template inference do 
 the work of figuring out the appropriate template 
 instantiation, exactly as before.

 With this change, format!"..." would no longer be necessary at 
 all; all format calls of the form format("format string", args) 
 would be templated on the string's value, as they already are 
 on the argument types.

 Thoughts?
Sounds great. I think the main advantages are optimization and compile-time checking rather than UFCS. IFTI should prefer template value parameter inference over an overload that takes the parameter at runtime. (The overload is still necessary for non-literal arguments). Then we could call a function with compile time optimization without even having to be aware of a template overload that takes a literal value argument at compile-time instead of runtime.
Aug 10 2019
parent Nick Treleaven <nick geany.org> writes:
On Saturday, 10 August 2019 at 17:55:14 UTC, Nick Treleaven wrote:
 (The overload is still necessary for non-literal arguments).
Where I said literal, I meant compile-time known value.
Aug 11 2019