Skip to content
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

Opt-out (by attribute?) auto-upcasting of method parameters #819

Open
gusty opened this issue Dec 16, 2019 · 2 comments
Open

Opt-out (by attribute?) auto-upcasting of method parameters #819

gusty opened this issue Dec 16, 2019 · 2 comments

Comments

@gusty
Copy link

@gusty gusty commented Dec 16, 2019

Opt-out (by attribute?) auto-upcasting of method parameters

I propose we add an attribute or another language construction to avoid automatic upcasting of parameters.

The existing way of approaching this problem in F# is doing some ugly hacks like wrapping the parameter in a generic type, usually a tuple including all the parameters that whose types we want to "fix".

Pros and Cons

The advantages of making this adjustment to F# are:

  • More control over how strict / flexible we want to be.
  • Less cases leading to ambiguity resolution compile-time errors
  • Faster compile time, since the compiler is quicker resolving overloads for sealed types.
  • Better type inference, since type inference is better when the type is sealed (see my submitted issues proving this statement).

The disadvantages of making this adjustment to F# are:

  • Adding an extra modifier attribute or a language construct.
  • It's work, although it shouldn't be complicate.

Extra information

Estimated cost: S

Related suggestions: #820 #821

Affidavit (please submit!)

Please tick this by placing a cross in the box:

  • This is not a question (e.g. like one you might ask on stackoverflow) and I have searched stackoverflow for discussions of this issue
  • I have searched both open and closed suggestions on this site and believe this is not a duplicate
  • 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:

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

More information

This is one of the main pain points we face when developing libraries like F#+ which uses member constraints and sometimes we have interfaces like seq<_> "eating" all subtypes, included some that we prefer to use a different mechanism.

Consider the following example:

type Monad = Monad with
    static member (>>=) (x: seq<_>, f) = ...
    static member (>>=) (x: list<_>, f) = ...

Calling (>>=) with a type Tree<'t> which implements IEnumerable would have undesirable effects (a tree is not a monad). Another thing is that the user explicitly upcast his tree and calls the >>= function.

The way to workaround this is by wrapping:

type Monad = Monad with
    static member (>>=) ((x: seq<_>, f)) = ...
    static member (>>=) ((x: list<_>, f)) = ...

Which is tupling the parameters into a single one, but this suggestion proposes something like:

type Monad = Monad with
    static member (>>=) ([<AsSealed>]x: seq<_>, f) = ...
    static member (>>=) (x: list<_>, f) = ...

The name of the attribute / language construct is to be discussed.

@wallymathieu

This comment has been minimized.

Copy link

@wallymathieu wallymathieu commented Dec 16, 2019

Yes, that makes sense. I would expect it to be something like the inverse of the # flexible type notation for "let" declarations, scoped for members. I.e. 'a when 'a = t

@wallymathieu

This comment has been minimized.

Copy link

@wallymathieu wallymathieu commented Dec 16, 2019

So I guess it would be the inflexible notation for overloading 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.