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

Special-case raising an exception with byrefs #872

Open
5 tasks done
cartermp opened this issue May 26, 2020 · 3 comments
Open
5 tasks done

Special-case raising an exception with byrefs #872

cartermp opened this issue May 26, 2020 · 3 comments

Comments

@cartermp
Copy link
Member

cartermp commented May 26, 2020

Tracking as per here: dotnet/fsharp#5776

We should allow raising exceptions in byref-returning functions and methods, like this:

type Ii<'T> =
    abstract GetSpan : int -> ReadOnlySpan<'T>

[<Struct>]
type X(value : int) =
    interface Ii<int> with
        member _.GetSpan n = ReadOnlySpan()

[<Struct>]
type Y(value : int) =
    interface Ii<int> with
        member _.GetSpan n = failwith "Nope"

The existing way of approaching this problem in F# is to insert a dummy return value to satisfy the F# compiler:

[<Struct>]
type Y(value : int) =
    interface Ii<int> with
        member _.GetSpan n = failwith "Nope"; ReadOnlySpan()

The reason why this doesn't work is that the way you raise exceptions in F# is through the raise function, which returns a generic value. Same goes for the other helpers:

  • failwith
  • invalidArg
  • nullArg
  • invalidOp
  • reraise
  • rethrow
  • failwithf

Note that @dsyme is not in favor of special casing anything other than raise. I personally think all other than failwithf should be allowed, though that may be worth considering.

Pros and Cons

The advantages of making this adjustment to F# are:

  • Allowing a fairly common pattern, since exceptions are normal in .NET

The disadvantages of making this adjustment to F# are:

  • More special rules for byref and byref-like types

Extra information

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

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
@dsyme
Copy link
Collaborator

dsyme commented May 28, 2020

Marking approved. I guess I don't really mind how many of those are special-cased.

@Naharie
Copy link

Naharie commented May 4, 2021

Would this be extended to inline functions that raise an error unconditionally? It would make it possible to define custom error functions such as the following:

let inline notPositive name = raise (ArgumentOutOfRangeException(name, name + " must be greater than zero!"))

@Naharie
Copy link

Naharie commented May 4, 2021

Never mind. I just realized #688 already addresses the issue.

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

No branches or pull requests

3 participants