fslaborg / Deedle

Easy to use .NET library for data and time series manipulation and for scientific programming
http://fslab.org/Deedle/
BSD 2-Clause "Simplified" License
924 stars 196 forks source link

Frame.ofRecords fails silently when underlaying record type is internal or private #562

Open lkluc opened 4 months ago

lkluc commented 4 months ago

Hello, First, I was really wondering what was happening, I initially thought the .NET Framework might been the problem. Then I thought it might be a difference between interactive versus compiled mode. I was wrong it both cases, it is because the underlaying type of record was internal (and I tested also with private which also fails), and so it seems Frame.ofRecords fails to convert the records into its structure and fails silently resulting in an unusable list.

If you run the following code :

open System
open Deedle

// Assuming we have a record 'Price' and a collection 'values'
type internal Price = { Day : DateTime; Open : float }

let internal prices = 
  [ { Day = DateTime.Now; Open = 10.1 }
    { Day = DateTime.Now.AddDays(1.0); Open = 15.1 }
    { Day = DateTime.Now.AddDays(2.0); Open = 9.1 } ]

// Creates a data frame with columns 'Day' and 'Open'
let df5 = Frame.ofRecords prices

printfn "df5 : %A" (df5.Format())

The unexpected output result is as follows :

df5 : "
0 ->
1 ->
2 ->
"

I don't mind if this happens and we accept that it's the user's fault. However, I expect the function to tell the user that it can not get any information on the structure of the record by returning an exception.

If you can not technically do it, I humbly suggestion you update the specification of the Frame.ofRecords method (or any other in the same situation) to state that the underlaying type must be public and assessible.

Of course a better idea would be to support the private/internal records because I want my class libraries to always export as less services as possible, because having a tidy interface means the less I have to support, the better ! ;)

Please note also that because of this, even an internal accessibility modifier on the module renders the type private and breaks the method, so I would have to expose this internal record type to the interface.

I'll try to get around this limitation with an anonymous record.

Thanks in advance ! :)