fslang-suggestions icon indicating copy to clipboard operation
fslang-suggestions copied to clipboard

Expose static members of shadowed type abbreviations by functions

Open Happypig375 opened this issue 6 years ago • 8 comments

I propose we expose static members of type abbreviations.

I can't believe no one has raised this before.

We should be able to shorten System.Int32.TryParse to int.TryParse.

The existing way of approaching this problem in F# is typing the full name out.

Pros and Cons

The advantages of making this adjustment to F# are

  1. This makes F# even more approachable to beginners, who do not need to know about what the 32 in Int32 means yet.
  2. C# has had this for years. This bridges the gap between C# and F#. This reduces unpleasant surprises for C# developers coming to F#.
  3. Type abbreviations shorten long names. Using a static member from the type requires the whole type be typed out again. Frustration and curses then occur.

The disadvantage of making this adjustment to F# is the implementation effort required.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): S

Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • [X] This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • [X] I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • [X] This is not something which has obviously "already been decided" in previous versions of F#. If you're questioning a fundamental design decision that has obviously already been taken (e.g. "Make F# untyped") then please don't submit it.

Please tick all that apply:

  • [X] This is not a breaking change to the F# language design
  • [X] I or my company would be willing to help implement and/or test this

Happypig375 avatar May 24 '19 12:05 Happypig375

Normally System is open so really its just two characters difference. Int32.TryParse vs int.TryParse

7sharp9 avatar May 24 '19 16:05 7sharp9

Imagine typing Int32 everywhere instead of int. This was why type abbreviations were added.

Happypig375 avatar May 25 '19 10:05 Happypig375

In general I'm in favor, though I could see this as being by design from @dsyme's perspective.

cartermp avatar May 25 '19 16:05 cartermp

This is actually down to a name collision. It's already possible to access static members from type abbreviations. But not if you then bind another value to the same name:

type guid = System.Guid // A type abbreviation

guid.NewGuid() // Accessing a static member works OK

let guid x = System.Guid.TryParse x // Here we define a function with the same name.

guid.NewGuid() // Compiler error. We can no longer access static member

This is exactly what's happening with int. The int function removes the ability to refer to the int type from a value expression. It can only be referred to in a type expression.

I'm not sure if there is a way around this. The compiler would have to work out if you were referring to the value or the type based on the surrounding context. Bear in mind the value could be an object that also has members.

The reason this is easier in C# is that int, float etc. are reserved keywords that can't be used for naming anything else. Trying to introduce that into F# would be a very breaking change. Note that C# has the same limitation for type names that aren't keywords.

theprash avatar May 26 '19 09:05 theprash

I'm personally fine with the possibility of shadowing int, string and I think nowadays it's pretty standard to do so in small function scopes, though I don't do it that much, but I've seen lot of code around.

The way around it is: don't do it if you need the original meaning.

gusty avatar May 26 '19 10:05 gusty

What about:

guid.NewGuid() // There is no "NewGuid" instance method in the guid object. Interpreting as a type instead.

Happypig375 avatar May 26 '19 10:05 Happypig375

A large part of this is now superseded by #749.

Happypig375 avatar Jun 11 '19 16:06 Happypig375

As mentioned above - type abbreviations already support static member lookup. The case of int and string is indeed a clash between int as a value and int as a type abbreviation. The former takes precedence.

I'm not particularly in favour of mod'ing the name resolution rules to allow lookups through single-identifier values and lookups through type names to be combined in one name resolution - though I think that's the logical implication of this suggestion.

dsyme avatar Jul 01 '19 14:07 dsyme