Confusing use of ticks in FS0064 warning.
See the real life situation here https://github.com/dotnet/fsharp/discussions/18808
One type argument is 'TRequest, the other 'TRequest'
The first impression is that the warning message adds it's own ticks without rhyme or reason:
This construct causes code to be less generic than indicated by the type annotations. The type variable 'TRequest' has been constrained to be type ''TRequest'
It's also not correct in the sense that the second part is not actual type but a type variable.
<data name="NonRigidTypar3" xml:space="preserve">
<value>This construct causes code to be less generic than indicated by the type annotations. The type variable '{0} has been constrained to be type '{1}'.</value>
</data>
Notice the missing tick here: variable '{0} has
But then I am wondering, would that solve it, or not really and using ticks for two things (one is string handling to form the error message, another is a common symbol to use with generic arguments) will lead to problems not matter how the message template is restructured?
Rust uses single backticks ` to quote things in its compiler error messages, perhaps at least in part because it uses the typewriter apostrophe ' for lifetime parameter names ('a) and would otherwise have this exact problem.
We of course also have double-backticked identifiers in F#, but I think we normally (always?) strip the double backticks and don't display them in error messages. And even if we don't, double-backticked identifiers are much less common than ' in type parameters.
Ignoring the bug in this specific error message template where the closing ' is missing, using backticks instead of apostrophes would look like:
-The type variable ''TRequest'' has been constrained to be type ''TRequest'
+The type variable `'TRequest'` has been constrained to be type `'TRequest`
It's hard to say whether a change like that would be worth the churn, though.
Looks roughly the same to me. What about markdown like emphasis? It's likely also what most AI tools will be trained to understand and figure out as a template-delimiter and separate it from the name-content itself.
This construct causes code to be less generic than indicated by the type annotations. The type variable **TRequest** has been constrained to be type **'TRequest**
If could make it (admittedly a breaking change - assuming we would transfer it as text and possibly break names that contained ** in them) to render it as bold at some selected places - terminal output for supported terminals, IDE error list.
@T-Gro Markdown like emphasis and trying to make it bold sounds like a great idea.
I personally have an harder time parsing F# error messages than with other languages, in large part because due to the way the compiler works it is not always clear what is the root cause of the warning/error. So I often have to go through two stages:
- What does this error message even mean
- What is the root cause
When you are confused about 1, the whole experience isn't funny at all. But clearly emphasizing type variables in these messages would go a long way toward eliminating 1, at least in my case. The ** ** syntax would catch eyes better, because ticks are used in many places in F#.
or just use parentheses around the type variables? How about non-ASCII pairs like 【 】or 「 」?
Interesting idea.
Given the compliance demands around globalization, I would not feel safe using a symbol whose meaning we do not understand. Is it offensive in any culture? Is it coming from an "enemy" culture for anyone using it?
If it's e.g. a math symbol, that would be fine of course.
Just to add my two cents, even nothing at all would be better than current situation of wrapping a type variable in ticks. I notice only the second placeholder in the message is wrapped, the single tick in the first placeholder apparently is there because it's not carried as part of the type var name (?).
It would look like this:
This construct causes code to be less generic than indicated by the type annotations. The type variable 'TRequest' has been constrained to be type 'TRequest
Another solution is separate message when the second part is not a type but a type var.
@majocha :
The current template is:
The type variable '{0} has been constrained to be type '{1}'
Is your proposal to change it to:
The type variable {0} has been constrained to be type {1} and
The type variable {0} has been constrained to be another type variable {1}
Yes, maybe even like this, to minimalize the change:
The type variable '{0} has been constrained to be type {1}
Because apparently for type-vars the initial tick is rendered in {1} but not rendered in {0}.
we should not put the types in single quotes.
https://github.com/dotnet/fsharp/issues/1170#issuecomment-218686747
That was 2016 😁