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

Create a seq.toIList extension #785

Open
ajwillshire opened this issue Sep 21, 2019 · 9 comments

Comments

@ajwillshire
Copy link

commented Sep 21, 2019

Create a seq.toIList extension

I propose we add a simple extension to the library to convert from a collection to an IList, to make life easier when using certain APIs

It could implement something like:

open System.Linq
open System.Collections.Generic

module Seq =

    let toIList(dataIn:seq<'T>):List<'T> = dataIn.ToList()

used like, for example in a .NET Google API:

let request = service.UserRoles.List(userProfileId)
request.Ids <- Repeatable(userRoleList |> List.map (fun x -> x.ToString()) |> Seq.toIList)
request.execute()

where "Repeatable" expects a Collections.Generic.IEnumerable.

The existing way of approaching this problem in F# is to use a method like ResizeArray or to open System.Linq and System.Collections.Generic in the module, which seems like overkill.

Pros and Cons

The advantages of making this adjustment to F# are:
a) It's useful for the above case of working with existing .NET APIs, and probably for other things too.
b) It would help people who are new to F# (whether from a .NET background or not) make sense of the difference between a .NET List and an F# list.
c) Using ResizeArray for this purpose seems a bit hack-y and a random bit of insider knowledge. Nothing about it screams "use this when converting from list to List".
d) It's really simple - all of the required code is above.

The disadvantages of making this adjustment to F# are:
a) Is it a slippery slope? Will there end up being a proliferation of these methods?

Extra information

Estimated cost (XS, S, M, L, XL, XXL):
XS
Related suggestions: (put links to related suggestions here)

Affidavit (please submit!)

Please tick this by placing a cross in the box:

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

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

This comment has been minimized.

Copy link
Contributor

commented Sep 21, 2019

Should be called toResizeArray.

@cartermp

This comment has been minimized.

Copy link
Member

commented Sep 21, 2019

Note that you can already pipe into the ResizeArray constructor today:

image

But the type has to be known as one that satisfies IEnumerable<'T>.

@Happypig375

This comment has been minimized.

Copy link
Contributor

commented Sep 21, 2019

This can also be said for List.toSeq and Array.toSeq, they are just downcasts to seq.

@cartermp

This comment has been minimized.

Copy link
Member

commented Sep 21, 2019

F# lists also satisfy the IReadonlyList<'T> interface, since they are readonly. So there's a bit of tension in having a List function that explicitly turns it into something that is mutable.

@Happypig375

This comment has been minimized.

Copy link
Contributor

commented Sep 21, 2019

List.toArray

@cartermp

This comment has been minimized.

Copy link
Member

commented Sep 21, 2019

@Happypig375 This doesn't change my statement.

@ajwillshire

This comment has been minimized.

Copy link
Author

commented Sep 21, 2019

Yes, I found out about ResizeArray when I asked a friend on Twitter. I just think it's quite non-obvious as the solution to this problem. When the API requires something that satisfies IList, it's not immediately apparent that ResizeArray is the answer. And neither the compiler nor the intellisense are much help in figuring out the answer.

My perspective is as someone who uses F# without having had a grounding in the wider .NET ecosystem, so I don't have an intuitive understanding of the different interfaces (which is my failing, to an extent). There's already a slight eyebrow raise when you first learn that an F# list is not the same as a .NET list, but when the available methods to convert between them when you need to are non-obvious, or hidden in System.Linq, or whatever, it doesn't help on the usability front. And you need to know a little bit of background in order to make a sensible search on StackOverflow.

@isaacabraham

This comment has been minimized.

Copy link

commented Sep 30, 2019

Is actually what is really required then just an alis for the ResizeArray ctor as Seq.toIList?

@Risord

This comment has been minimized.

Copy link

commented Oct 16, 2019

If System.Collections.Generic.List is wanted you can use constructor of it directly. No ResizeArray alias type is need to know nor C#ish System.Linq .ToList() is required. And if IList is wanted you can currently use seq.toArray too.

If you don't have C# background and you are using C# API with F# it can have it weirdness (almost by definition) but I think this won't improve things much.

I think that default flow of thought should be something like: interface is wanted but type you have is not implementing that. Find implementation candidate and see how it can be constructed. Instead of looking your original source object/module for .To# methods/functions. With all sympathy.

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