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

Inline Interfaces, i.e. simpler SRTP #641

Closed
4 of 5 tasks
TheJayMann opened this issue Jan 29, 2018 · 9 comments
Closed
4 of 5 tasks

Inline Interfaces, i.e. simpler SRTP #641

TheJayMann opened this issue Jan 29, 2018 · 9 comments

Comments

@TheJayMann
Copy link

TheJayMann commented Jan 29, 2018

I propose the concept of inline interfaces. They would be defined similar to how interfaces are currently defined, but with an inline keyword.

type inline IDuck =
  abstract member Walk: unit -> unit
  abstract member Quack: unit -> unit

The interface can then be used in an inline function or method.

let walkAndQuack (duck: ^a when ^a :> IDuck) =
  duck.Walk ()
  duck.Quack ()

This would be a simpler way to write the equivalent of how SRTPs are done currently.

let walkAndQuack duck =
  (^a: (member Walk: unit -> unit) (duck))
  (^a: (member Quack: unit -> unit) (duck))

Extra information

Related suggestions:
#207 Support anonymous record types [ RFC FS-1030 ]
I am not entirely certain, but I believe the concept of anonymous records or tables may also be attempting to address this issue.

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
@robkuz
Copy link

robkuz commented Jan 30, 2018

actually this in a way already works

    type Duck< ^a 
                when ^a: (member Walk: unit -> unit) 
                and  ^a: (member Quack: unit -> unit) > = ^a

it doesn't however play very nice with tooling imo

@TheJayMann
Copy link
Author

Given the current tooling, even using the above type abbreviations, the inline functions would still have to be written using the verbose and sometimes confusing to remember SRTP syntax.

let inline walkAndQuack (duck: ^a Duck) =
  (^a : (member Walk: unit -> unit)(duck))
  (^a : (member Quack: unit -> unit)(duck))

At this point, there is no real point in having that type abbreviation today. If the type abbreviation could allow the simpler member access, that would also reduce the need for creating the new inline interface syntax that I proposed. Either the type abbreviation syntax or the inline interface syntax would work just as well, so long as it results in the simpler and intuitive member access.

I am now reminded of an earlier suggestion that if a member declares in it's definition that a type constraint have a member, that the member can be accessed with the simpler member access. I don't remember which issue number it is, nor can I think of how to search for it. Assuming the type abbreviation implementation, this suggestion would now be an amendment to that suggestion.

@rmunn
Copy link

rmunn commented Feb 1, 2018

@TheJayMann wrote:

I am now reminded of an earlier suggestion that if a member declares in it's definition that a type constraint have a member, that the member can be accessed with the simpler member access.

Is #440 (which has been approved in principle and now has an RFC) the one you were thinking of?

@TheJayMann
Copy link
Author

This is exactly the one I was thinking. Perhaps, if this issue is approved, rather than being a new RFC, the existing RFC can be updated?

The advantage of the suggestions I had made is that if multiple inline functions were looking for the same member definitions, those method definitions could be made one time, rather than making the same member definitions multiple times. Unless, of course, there were already plans to allow the type abbreviations in the RFC, at which point this is a duplicate.

@Rickasaurus
Copy link

This is a really neat idea.

@rmunn
Copy link

rmunn commented Feb 7, 2018

I have completely avoided using SRTPs so far, because the syntax is just too ugly: difficult to read, which means difficult to maintain — which feels counter to one of F#'s great strengths (code simplicity which leads to ease of maintenance). If this suggestion was accepted and implemented, I'd feel safe actually using SRTPs, since I wouldn't feel that I'd be creating a maintenance nightmare for myself down the road.

@zpodlovics
Copy link

Would it be possible to have the same or similar feature (inline keyword or attributes) for records of functions (for records that only have functions)? Recenty there was a twitter thread about the preferred abstractions interfaces vs records of functions here, and it seems each have their own user base: https://twitter.com/shanelogsdon/status/962786920551079936

Something similar feature would be something like this:

type inline FDuck = { 
Walk: unit->unit 
Quack: unit->unit
}

[<Struct>]
type inline StructFWalk = { 
Walk: unit->unit 
Quack: unit->unit
}

Right now in average there is a huge ~5x-6x performance hit when the functionsa are passed as records instead of passed directly on call intensive workload (low latency event processing with 100M+ event per second). Passing lot's of functions individually around due this performance hit makes the code unreadable.

@realvictorprm
Copy link
Member

I've started an implementation already, see this PR dotnet/fsharp#4726

@dsyme
Copy link
Collaborator

dsyme commented Jun 16, 2022

Treating as duplicate of #1089

@dsyme dsyme closed this as not planned Won't fix, can't repro, duplicate, stale Jun 16, 2022
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

7 participants