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

Support 'protected' access modifier for F#

Open baronfel opened this issue 8 years ago • 26 comments

Submitted by Gustavo Guerra on 3/21/2014 12:00:00 AM
98 votes on UserVoice prior to migration
In addition, there were 53 votes on the original issue on the Visual Studio uservoice

Original item: http://visualstudio.uservoice.com/forums/121579-visual-studio/suggestions/2262739-support-protected-access-modifier-for-f

Original UserVoice Submission Archived Uservoice Comments

baronfel avatar Oct 20 '16 01:10 baronfel

Is this approved? Considered? Declined?

realvictorprm avatar Sep 29 '17 11:09 realvictorprm

It's unlikely we'll do this unless something absolutely forces us to

dsyme avatar Oct 04 '17 01:10 dsyme

I think it's an important OOP Feature. Especially for resource management classes it's important to be able to hide functions / fields which should not be called outside of the class (expect for those classes which inherit).

realvictorprm avatar Dec 12 '17 20:12 realvictorprm

From what I remember there are real issues with this and type inference?

Rickasaurus avatar Dec 21 '17 23:12 Rickasaurus

I will say, lacking this causes serious oddities with various expected patterns, such as IDisposable. It's impossible to follow the normal .NET IDisposable mechanisms when implementing types in F#.

Normally not an issue, but bit a huge number of type providers in the wild a couple of years back, and has many other cases where it's far from ideal. It's been a frequent issue in some of my libraries (which, I grant, are often UI based, where OO patterns are common, and protected is expected).

ReedCopsey avatar Dec 21 '17 23:12 ReedCopsey

Nothing which can't be solved.

Am 22.12.2017 12:32 vorm. schrieb "Rick Minerich" <[email protected]

:

From what I remember there are real issues with this and type inference?

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/fsharp/fslang-suggestions/issues/157#issuecomment-353484027, or mute the thread https://github.com/notifications/unsubscribe-auth/AYPM8Az45mHFSjx3Fsku81w4-REVzhThks5tCup_gaJpZM4Kbowy .

realvictorprm avatar Dec 21 '17 23:12 realvictorprm

@dsyme exactly this is the point I think :-(

realvictorprm avatar Dec 21 '17 23:12 realvictorprm

I will say, lacking this causes serious oddities with various expected patterns, such as IDisposable. It's impossible to follow the normal .NET IDisposable mechanisms when implementing types in F#.

Any other examples besides IDisposable?

The .NET IDisposable implementation pattern is only when using implementation inheritance and I don't think the use of "protected" is really critical to the pattern (except in some absolutist sense for OO purists). F# biases heavily away from implementation inheritance.

Normally not an issue, but bit a huge number of type providers in the wild a couple of years back, and has many other cases where it's far from ideal. It's been a frequent issue in some of my libraries (which, I grant, are often UI based, where OO patterns are common, and protected is expected).

That bug was one of the rare cases (in this case in the TPSDK) where we used implementation inheritance rather than delegation. I still think we probably should never have done that. And in any case "protected" wasn't required to implement disposing properly in that case.

dsyme avatar Jan 05 '18 22:01 dsyme

Any other examples besides IDisposable?

The .NET IDisposable implementation pattern is only when using implementation inheritance and I don't think the use of "protected" is really critical to the pattern (except in some absolutist sense for OO purists). F# biases heavily away from implementation inheritance.

I've had other places where this would be beneficial, but to be fair, they've all been when doing implementation inheritance, mostly related to working with UI libraries (which tend to be completely OO in design).

ReedCopsey avatar Jan 08 '18 19:01 ReedCopsey

So I was asked to add to this issue after asking about the protected keyword on Twitter....

The main reason to support the protected keyword is simply that F# cannot really be considered a first-class .NET language if you can't use it to produce the same end-product assemblies as you can from C#. So while there may be other preferred ways to create objects in F#, being able to create class hierarchies that can be inherited from by C# is vital. It must be possible to see that even without giving specific examples.

Surely you want to expand the popularity of F#? Telling people "we don't do it like that here", which is the typical response I get whenever I mention the lack of the protected keyword to F# community members, is not the way to encourage C#/Java programmers to come across to the F# camp. People have big solutions and want to write a component in F# to take advantage of features like compact syntax, discriminated unions and pattern matching, but still build their class hierarchies the way they do in C#, at least to begin with. Making F# as friendly as possible to C# programmers should be a priority, especially as it's such a small addition to the language, and one that should not be controversial for a .NET language.

Addendum: I am aware when this was discussed on the old User Voice for F# that there were technical objections related to handling access to protected members from lambdas. But C# has protected members and lambdas, so this should be resolved the same way.

rhm avatar Jan 09 '18 00:01 rhm

@rhm Thanks for the information. It is true that F# generally discourages the use of implementation inheritance in design patterns.

From the context on twitter I thought there was a specific Xamarin-related scenario that might be driving this feedback, rather than just a desire to precisely emulate all C#/Java APIs bit-for-bit. Do you have a use case where protected is specifically needed? (except in general OO class hierarchy design based on implementation inheritance). The only one mentioned so far is the pattern used to implement Disposable in .NET implementation inheritance.

dsyme avatar Jan 09 '18 09:01 dsyme

The comment was connected to the Xamarin announcement in the sense that I figure they want to make F# a more friendly option to developers using their frameworks. I'm not super-familiar with their stuff, but I remember when I was trying to use F# to write a WPF application years back that every example included a project of C# glue code because there were some things that were just too difficult to do from F#. Now the reasons for that might be unrelated to protected - it's been a while - but I would have thought it would be a goal to avoid the same happening with Xamarin's frameworks.

If they are all based on implementing interfaces - no problem. If like every other OO UI framework I've ever used, they are based on inheritance, then there will be friction. Even if F# is fine for writing apps, is it a good candidate for creating new components for C# consumers?

rhm avatar Jan 09 '18 10:01 rhm

@dsyme can we add a warning? Like the one you're planning to add for the tuple properties? I think it's something like 'this code is not normally used from F#'.

gusty avatar Jan 09 '18 10:01 gusty

What does include protected in this definition? All of this?

  • protected
  • private protected
  • protected internal

xperiandri avatar Jan 09 '18 18:01 xperiandri

I would like to have protected in F# with a warning per default

realvictorprm avatar Jul 19 '19 20:07 realvictorprm

I'd actually be fine with protected support and not putting it blog posts/release notes, or do it and explicitly say that we're holding our nose by doing it and one should only use it if they desperately need it.

cartermp avatar Jul 19 '19 22:07 cartermp

I'm fine with that approach too :)

realvictorprm avatar Jul 20 '19 06:07 realvictorprm

I actually like how F# handles protected. However, this approach becomes a hassle when integrating with C# libraries that use protected heavily. For example, using Project Orleans in F# is almost unusable. A discussion on how to improve the situation is ongoing here https://github.com/dotnet/orleans/issues/5772

I think protected support with warnings would fix the F#/Orleans onboarding experience.

ray440 avatar Sep 06 '19 22:09 ray440

I understand that it is a deliberate decision not to fully support OO type of development. But it indeed causes some issues with interoperability, and thus selling F# to colleagues. ='(

voroninp avatar Aug 05 '21 16:08 voroninp

I'm marking this as approved, if it uses some extreme keyword like __protected or the like

dsyme avatar Apr 12 '23 13:04 dsyme

I'm marking this as approved, if it uses some extreme keyword like __protected or the like

Noice! This is the main reason I stopped developing in F# as it made it really hard to use implementation inheritance! I hope it makes it through! F# was / is fun!

bbqchickenrobot avatar Jun 29 '23 21:06 bbqchickenrobot

I'm marking this as approved, if it uses some extreme keyword like __protected or the like

Or an attribute [<Protected>] maybe? This would put it put it in a similar category as something like [<AbstractClass>], as a not-very-idiomatic-but-sometimes-necessary object-oriented feature.

Tarmil avatar Jun 30 '23 11:06 Tarmil

If we must have this feature, I think the attribute is definitely a better approach than the double-underscore (or any keyword, really). It would also be great if using this triggered a compiler warning.

pblasucci avatar Jun 30 '23 11:06 pblasucci

Attribute that will work with private and internal but otherwise just ignored?

xperiandri avatar Jun 30 '23 13:06 xperiandri

@dsyme Can we expect protected in F# 9?

nikhilbarthwal avatar Apr 09 '24 07:04 nikhilbarthwal

@dsyme Can we expect protected in F# 9?

It's not planned for F# 9, we will accept contribution though.

vzarytovskii avatar Apr 09 '24 08:04 vzarytovskii