New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bug in signature printing when a method is generic but doesn't use its type parameter #674
Comments
I'm not sure I understand the issue. The second method Just trying to understand what you're suggesting ;) |
is this clearer? Please see the update. Essentially, 'x goes off into the ether. The AST is correct based on expected behaviour working correctly, so it probably just an issue with pretty printing. |
Yes, it's clearer now. I think the main issue with your code is that you are using generics that doesn't appear anywhere in the signature, hence you don't see it back in the signature F# gives you. I.e. suppose you have: static member B<'x>(n, a:'x) =
typeof<'x>.Name,[for i = 0 to n-1 do yield i] This would give you the signature like it's expected (note the appearance of
I don't think changing the inferred signature to something else than it actually is is the right way forward, but perhaps inference could detect that it is a generic signature where the generic type parameter is a requirement (as opposed to being implicit, which is usual in F#, as in my example above). For instance, instead of That way it wouldn't change the actual signature and the shown signature is still legal syntax and actually maps the original definition. An added benefit would be that in the output of your type it becomes immediately obvious what the difference are: type Abc =
class
new : unit -> Abc
static member A : unit -> string * int list
static member B : n:int -> string * int list
static member B<'a> : n:int -> string * int list // now this is distinguishable
static member B : ty:Type * n:int -> string * int list
end Whether this is easy or hard to achieve, I don't know. Type inference is a tricky thing in the compiler. |
interesting... it's as you said... thanks for mentioning the not used + inference idea...
... signature is...
I'm not sure if this is predictable enough though... going back a step to the weird behaviour:
signature
and yet, inference or not, 'x has influenced behaviour. It might not affect most people in practice, yet, maybe it's a rough enough edge to be worthy of sanding one day. The context is "reasoning with types + signatures" + type providers + it came up in actual work that I'll be using for teaching purposes. I'll skip over this so that I don't confuse anyone. I'll definitely avoid the generic notation, which would have been more compact, yet probably not have added much in terms of readability. I do like the way <'x> works generally -- just need to avoid it in this context. Perhaps, hand cranking the type signature is acceptable. Thanks. |
Most of the time you won't need it, F#'s auto-generics take care of that.
It influenced behavior, yes, but Though I do see your point: if the generic parameter is specified, it is probably for a good reason (i.e., in your case you use it with |
there are implications beyond F# only scenarios, like perhaps at that point, you are injecting IL into a byte array, or translating to something further afield. The finer point is, the programmer was explicit, so we should not override this. Also, it's inconsistent with a simpler case:
signature:
The language needs to be predictable so that you can read the code, and not be forced to run it to understand what is going on. NB. we still don't know if this is just pretty printing. |
What I'm reading from this suggestion is to pretty-print generic type arguments for functions and members. For example, in FSI: Class and constructor show generic type argument:
Member does not:
Neither does a function:
I think that's reasonable and probably doesn't require a language change. Assuming it does not, then this seems like a fine feature request in the Visual F# repository. |
@cartermp this shouldn't be too difficult. I can take a look as soon as we decide on a style. |
@cartermp: I've been trying to catch glitches and say something about them without overthinking it. I was unsure of scope at the beginning of this. @realvictorprm: re: style -- probably the way a let does it currently is the right way to go. Although I'd prefer to have fewer angle brackets, this is the idiomatic way in F# / .Net. |
necro I'll close this in favor of an issue over in https://github.com/dotnet/fsharp This feels squarely within the realm of an addition to the existing compiler tooling. |
the generic portion of a method or function gets ignored when fsi produces the signature description. In the case below, we've got nothing to show for x prime "<'x>". Can we improve the situation?
SIGNATURE
Issue -- there are two entries for B in the below. Only when a type is a standard argument, does the signature come close to what I was expecting. Shouldn't the generic version produce a different signature?
Proposed syntax
The existing way of approaching this problem in F# is to make a mental note of what is actually going on underneath.
Pros and Cons
The advantages of making this adjustment to F# are -> Some("type signatures are also accurate + explicit for generic cases")
The disadvantages of making this adjustment to F# are -> None.
Extra information
Estimated cost (XS, S, M, L, XL, XXL): XS
Related suggestions: n/a
Affidavit (please submit!)
Please tick this by placing a cross in the box:
Please tick all that apply:
The text was updated successfully, but these errors were encountered: