You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In 11.0.0 (after #3817), the named arg placeholders are considered indexed and the automatic indexing stops working on the first indexed or named placeholder. The automatic placeholders refer to the fmt::format args in the order they appear, regardless if they are named or not.
The use case
The reason to support this is to allow layering of APIs - a higher level function provides fmt-like interface, but internally adds some named arguments for the user to reference:
print_with_errmsg("Error {m} in {}, something);
print_with_attrs("{bold}{fg:red}{}{normal}", bold_red_text);
These functions internally add some named args at the end, so they don't affect the indexes of user-visible args. For this use case, it would even make sense to forbid referencing the named args by indexes or by automatic indexing, essentially forcing them to be passed at the end, after positional args.
You can of course force users of such APIs to use only indexed args and never the automatic placeholders, but it's not really nice.
I acknowledge that this is kind of niche usage, but there is not many ways around it, if you want to provide the optional value(s) for user to reference, and a nice API.
And both forbid passing positional args after named args (i.e. mixing them in the arguments to format function). On the other hand, Rust forbids unused named arguments, which would also break the above use case. Python is fine.
The text was updated successfully, but these errors were encountered:
Thanks for the suggestion. It is an interesting idea to use named vs unnamed arguments in such way but I don't think it's worth relaxing the checks for this. A potentially better approach would be formatting arguments from different sources separately.
A potentially better approach would be formatting arguments from different sources separately.
I don't understand how this would be done or how it would help with the use case. You cannot call fmt multiple times to process format string incrementally, consuming just some args at the time. That causes a format error. The only possible workaround I see is to write a custom parser to preprocess the string - e.g. first find and replace the {m}, then delegate to fmt. This unfortunately means that the compile-time checking cannot be used.
So there doesn't seem to be any good solution for the use case without direct support in fmt itself.
Consider allowing to mix the named and automatically indexed placeholders:
I think all these are valid usages and should be supported. They all worked before 11.0.0 and the last two stopped working after that release.
On the other hand, I don't really care if this works or not:
In 11.0.0 (after #3817), the named arg placeholders are considered indexed and the automatic indexing stops working on the first indexed or named placeholder. The automatic placeholders refer to the fmt::format args in the order they appear, regardless if they are named or not.
The use case
The reason to support this is to allow layering of APIs - a higher level function provides fmt-like interface, but internally adds some named arguments for the user to reference:
These functions internally add some named args at the end, so they don't affect the indexes of user-visible args. For this use case, it would even make sense to forbid referencing the named args by indexes or by automatic indexing, essentially forcing them to be passed at the end, after positional args.
You can of course force users of such APIs to use only indexed args and never the automatic placeholders, but it's not really nice.
I acknowledge that this is kind of niche usage, but there is not many ways around it, if you want to provide the optional value(s) for user to reference, and a nice API.
Note that both Python and Rust support this:
And both forbid passing positional args after named args (i.e. mixing them in the arguments to format function). On the other hand, Rust forbids unused named arguments, which would also break the above use case. Python is fine.
The text was updated successfully, but these errors were encountered: