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

Introduce a clean mechanism to delay SRTP overload resolution #707

Open
realvictorprm opened this Issue Nov 22, 2018 · 4 comments

Comments

Projects
None yet
3 participants
@realvictorprm
Member

realvictorprm commented Nov 22, 2018

I propose we add a clean mechanism to delay SRTP overload resolution.

The existing way of approaching this problem in F# is to introduce in SRTP calls unrelated type parameters as support.

See this example:

One just wants to create an SRTP call which decides at full application (all parameter types are solved) which overload should be called.

type Tuple =
    static member inline TupleMap ((a, b),          _ : Tuple) = fun f -> (f a, f b)
    static member inline TupleMap ((a, b, c),       _ : Tuple) = fun f -> (f a, f b, f c)
    static member inline TupleMap ((a, b, c, d),    _ : Tuple) = fun f -> (f a, f b, f c, f d)
    
    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = (^a : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

However this code will fail because, although the parameter x is still generic and not further specified, with an overload resolution error. To solve this problem people will introduce another (unrelated/confusing) type parameter as support of the SRTP call.

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = ((^a or ^b) : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

Which in fact delays the overload resolution because at that point the parameter x isn't fully solved yet.

To change this I would propose to be able to add a keyword delayed which tells that as soon as not all parameters of the functions haven't been fully solved yet the overload resolution may be delayed.
In our example:

    static member inline Map f (x: 'Tin) : 'Tout =
        let inline call_2 (a: ^a, b : ^b) = (delayed ^a : (static member TupleMap : ^b * _ -> ^t) (b, a))
        call_2 (Unchecked.defaultof<Tuple>, x) f

My syntax proposal here is open for discussion. One could also write it like this:

(^a : (delayed static member TupleMap : ^b * _ -> ^t) (b, a))

Pros and Cons

The advantages of making this adjustment to F# are:

  • people stop creating super weird SRTP expressions which are just because they want delayed overload resolution

The disadvantages of making this adjustment to F# are:

  • Another keyword to learn and understand!

Extra information

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

Related suggestions: None I think

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
@cartermp

This comment has been minimized.

Member

cartermp commented Nov 22, 2018

A new keyword just to get around a limitation of a design doesn't feel right at all. Especially when it's less typing to apply the workaround. Additionally, I do not believe that many F# programmers are interested in "delayed overload resolution", and creating a brand-new language feature just for that feels awfully niche. I'm not in favor of this.

@realvictorprm

This comment has been minimized.

Member

realvictorprm commented Nov 22, 2018

A keyword would be at least better than doing weird quirks to delay resolution. Moreover it really helps F# coders to avoid introducing unrelated type parameters.

@gusty

This comment has been minimized.

gusty commented Nov 24, 2018

Another alternative would be to "fix" the design, by specifying clear rules about delayed resolution.

@realvictorprm

This comment has been minimized.

Member

realvictorprm commented Nov 26, 2018

Im in favor of this idea too. Any thoughts on this @dsyme?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment