Skip to content

Avoid type inference defaulting to object in absence of evidence #885

@gusty

Description

@gusty

There are many situations where type inference has no enough evidence to decide the type and in absence of the inline keyword (sometimes even with it) defaults to its defaults value, which typically is object, except for math operations which is int.

Examples:

let f x = string x // without inline or further evidence from usage it's inferred to obj
let add x y = x + y // without inline or further evidence from usage it's inferred to int

This is already obvious for experienced F# users, but take the example of the addition, it's been asked for almost every newcomer in SO, Slack, forums.

But the problem doesn't end there, this apparently isolated behavior cause many headaches when working with complicated type inference problems.

The existing way of approaching this problem in F# is ... there's no way around it while maintaining genericity.

There are different things we can put in place to avoid this common problem:

1) Remove the "default default to obj". Optionally defaults to obj can be specified manually in the compiler and we can make default keyword available to the user.

2) Allow user to use the default keyword in trait-calls, adding a syntax to set no default. This would be a way to gain gradually control over the situation, without introducing a breaking change.

Pros and Cons

The advantages of making this adjustment to F# are more control over type inference, consistency with other areas of type inference, like value restriction where in absence of evidence the compiler asks the user what to do.

The disadvantages of making this adjustment to F# are introduction of another error that the user has to understand what it means. Still I think this is better than getting an obj inferred silently.
It's work.

(1) is easy to implement but it would introduce a breaking change.

Extra information

Estimated cost (XS, S, M, L, XL, XXL): Depending on options, from XS to M

Related suggestions: It seems to me that this situation is getting worse with the coming dotnet/fsharp#6805

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions