Giter Club home page Giter Club logo

fsharpx.collections's Issues

Tagged collections, tagged map

I have old project, that uses FSharp.PowerPack and I want to move some parts to FSharpx.Collections.
After namespace transformation, I ran into a problem:
PowerPack contains other collections, in particular, Tagged.Map
https://github.com/fsprojects/powerpack-archive/blob/master/src/FSharp.PowerPack/TaggedCollections.fs

There's some types in my project, like:
type NamesMap<'v> = Tagged.Map<NameTypes.SomeName, 'v, NameTypes.NameComparer>
Can you recommend, what's the most convenient way to transform this code into your collections? Is it possible to transform, without code modification?

Thank you.

PersistentVector should implement IReadOnlyCollection

Description

The PersistentVector class (and any other list-like classes that know their own length as an O(1) operation, such as RandomAccessList) should probably implement the IReadOnlyCollection<'T> interface. It's a very simple interface, only requiring a Count property. The only tricky thing is that IReadOnlyCollection<'T> was added to .Net relatively recently, so it's only in .Net Framework starting with .Net Framework 4.5, it's only in Windows Phone starting with Windows Phone 8.1, and so on. So adding this interface would tend to break compatibility with some older .Net implementations, and thus it should be behind a compile-time flag that can turn it off if FSharpx.Collections is being built for an older profile. See, for example, how the FSCORE_PORTABLE_OLD flag is defined for some protable profiles (like profile 47), and how that flag is used to skip compiling non-portable bits on older systems.

Pros

Once the ISeq implementation gets merged in, it will be able to handle PersistentVectors far more efficiently in any situation where a count is required (such as the Array.ofSeq implementation that wants to know the length of the incoming data so it can pre-allocate an array to store the result). It would be a shame if a highly-efficient, persistent, immutable collection like PersistentVector ended up causing unnecessary O(N) operations that could have been skipped by simply adding a one-line interface implementation.

Cons

The need to keep FSharpx.Collections portable to older .Net versions will necessarily increase the complexity of the project's build system; compiler directives are never nice things to see in one's code. The alternative to a compiler directive would be to explicitly abandon support .Net 4.0 and earlier, Windows Phone 8.0 and earlier, and so on.

NuGet package with signed assemblies

I want to use FSharpx.Collections (and other FSharpx.* packages) in project which should be signed with strong name.
Can you please publish FSharpx.* packages with signed assemblies?

Should RandomAccessList and PersistentVector be merged?

While working on #54, I started to realize that the RandomAccessList data structure wasn't just similar to PersistentVector, it WAS a PersistentVector that simply iterated in reverse order, and when accessed by index, accessed the item at (count-1)-idx instead. This strikes me as unnecessary duplication of code. Why not just add one function to PersistentVector named reversedIterator, then implement RandomAccessList as something like this instead?

type RandomAccessList =
    inherit PersistentVector
    val lastIndex = count - 1
    override this.Item with get i =
        base.[lastIndex - i]
    override this.rangedIterator(startIndex, endIndex) =
        base.reversedIterator(lastIndex - startIndex, lastIndex - endIndex)
    override this.reversedIterator(startIndex, endIndex) =
        base.rangedIterator(lastIndex - startIndex, lastIndex - endIndex)
    override this.ofSeq items =
        // items |> Seq.rev |> base.ofSeq  // F# 4.0
        items |> List.ofSeq |> List.rev |> Seq.ofList |> base.ofSeq  // F# 3.1
    override this.Last = invalidOp "Can't take Last of a RandomAccessList"
    override this.Head = base.Last
    // etc., etc., etc.

(Note: the above is not valid F# code; I left out constructor parameters, generic types, and so on. Think of it as F# pseudocode).

The RandomAccessList module could stay pretty much the same, as most of its contents are simply calling the corresponding methods of the RandomAccessList type (or the RandomAccessList class, in C# terminology). But the duplication of code could be done away with.

Target net45 as a minimum

Description

The FSharpx.Collections build should move to target net45 as an absolute minimum, and leave net40 behind. FSharp.Core now requires net45 as of version 4.2.1, which means that if I want to use FSharpx.Collections in a project I now have to specify a dependency on FSharp.Core < 4.2. I've done a quick, unscientific survey of GitHub and found that the only projects that use FSharpx.Collections but still depend on .NET 4.0 are ones that haven't been updated in five years; anything currently maintained is at least on .NET 4.5 or higher. So as far as I can tell, there will be basically no cost to moving FSharpx.Collections to .NET 4.5.

Besides which, moving to .NET 4.5 will allow us to implement IReadOnlyCollection in the collections where it makes sense, which may enable future optimizations like this one.

Order-respecting Map?

Time and time again I face the issue of having to replace a Map with a list of pairs, because I need the original order to be preserved.
Would be nice to have a collection like that, even if it's just having both Map and a list of keys under the hood

NameValueCollection.concat impropery handling of dup keys

Description

Duplicate keys should result in adding comma separated value.

See remarks https://msdn.microsoft.com/en-us/library/xsc9a449(v=vs.110).aspx

Note poor design in .NET System.Collections.Specialized results in following bad behavior:

let a = NameValueCollection()
a.Add("1", "uno")
a.Add("1", "one")
a.Add("1", "one,and one")

a.["1"];
val it : string = "uno,one,one,and one"

Repro steps

see existing unit test

Expected behavior

Please provide a description of the behavior you expect.

Actual behavior

Currently concat results in duplicate entries of same key instead of CSV

catOptions is defined incorrectly

Description

https://github.com/fsprojects/FSharpx.Collections/blob/29180453c46b173a6b69fe3aa3313f634723ad68/src/FSharpx.Collections/Collections.fs#L452-452

let inline catOptions (xs:Option<'a> list) = List.choose id

Should be either of

let inline catOptions : Option<'a> list -> 'a list = List.choose id
let inline catOptions (xs:Option<'a> list) = List.choose id xs

Repro steps

Attempt to use catOptions in code.

Expected behavior

catOptions should have the signature Option<'a> list -> 'a list.

Actual behavior

The signature is Option<'b> list -> Option<'a> list -> 'a list.

Known workarounds

use List.choose id instead.

Related information

  • Operating system
    Affects all
  • Branch
    Master
  • .NET Runtime, CoreCLR or Mono Version
    Affects all

Wrong AssemblyInfo locations (fixed in latest project scaffold)

The build.fsx script currently creates AssemblyInfo.fs files in the wrong location. This has been fixed in ProjectScaffold -- see fsprojects/ProjectScaffold#151 -- but that fix needs to make its way into Fsharpx.Collections. We could either grab the latest ProjectScaffold, or just grab fsprojects/ProjectScaffold@dc7d7aa to fix this one issue without affecting other files.

Without this fix, the AssemblyInfo.fs files are being created in the wrong directory. Current output:

Created AssemblyInfo file "src/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections/AssemblyInfo.fs".
Created AssemblyInfo file "src/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections.Experimental/AssemblyInfo.fs".

Those relative paths expand to /home/rmunn/code/fsharp/FSharpx.Collections/src/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections.Experimental/AssemblyInfo.fs and /home/rmunn/code/fsharp/FSharpx.Collections/src/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections/AssemblyInfo.fs, which is clearly wrong.

Output after bugfix (remove the src @@ from one line of build.fsx) is applied:

Created AssemblyInfo file "/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections/AssemblyInfo.fs".
Created AssemblyInfo file "/home/rmunn/code/fsharp/FSharpx.Collections/src/FSharpx.Collections.Experimental/AssemblyInfo.fs".

PersistentHashMap.containsKey is broken for null values

PersistentHashMap.containsKey returns false negatives, if the value of the key-value pair is null.

This can also manifest if the value is None, or the value is unit. In fact, I discovered this because I was trying to treat PersistentHashMap<'a, unit> like a persistent hash set. This is because, internally, .NET stores None and unit as null.

Example:

open FSharpx.Collections

[<EntryPoint>]
let main (argv : string array) : int = 
    let key = "key"
    let value = None // or ()
    let map = PersistentHashMap.add key value PersistentHashMap.empty
    // Assertion fails
    assert (PersistentHashMap.containsKey key map)
    0

1.9.4 from NuGet Gallery is corrupt now

The NuGet Gallery is now serving a corrupt FSharpx.Collections.1.9.4.nupkg. This started happening sometime between Friday and today, Monday. Our builds failed until I put an working copy in our AppVeyor NuGet feed.

get-filehash $env:localappdata\nuget\cache\FSharpx.Collections.1.9.4.nupkg -algorithm md5

md5 of working: B76B5AA6534862913BFC0F0B6775E3D8
md5 of corrupt: 8AB7F69C9AB17E919CA96A07FB8D4B48

This can see that the file is corrupt by trying to open it up with NuGet Package Explorer:
image

paket restore fails correctly with:
image

nuget restore appears to not do the check and does not fail.

NuGet package: Could not load file or assembly 'FSharp.Core...

i just created an f# project for a console application and used NuGet to install FSharpx.Collections 1.14.0. i made a simple function to see how LazyList works. it compiles fine but when it runs, i get the following exception:

System.IO.FileLoadException was unhandled
Message: An unhandled exception of type 'System.IO.FileLoadException' occurred in myproject.exe
Additional information: Could not load file or assembly 'FSharp.Core, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

on NuGet it says "Dependencies: FSharp.Core (≥ 3.0.0)". but in my Project > Properties > Application, it says "Target F# runtime: F# 3.1 (FSharp.Core, 4.3.1.0)" (the default). i'm using vs2013upd4

can you fix this?

MissingMethodException when using RandomAccessList.tryUpdate from F# 4.0 assembly

I am referencing F# 4 from an assembly and FSharpx.Collections. When I attempt to use RandomAccessList.tryUpdate I get

System.MissingMethodException : Method not found: 'Microsoft.FSharp.Core.FSharpOption`1<FSharpx.Collections.RandomAccessList`1<!0>> FSharpx.Collections.RandomAccessList`1.TryUpdate(Int32, !0)'.

If I switch my assembly to reference F# 3.1 the exception does not occur.

PCL Version

Have you considered releasing FSharpX collections as a PCL library? It appears that several of the implementations utilize APIs not in the 259 PCL profile (threading APIs for instance), but a bait and switch approach could be used to support the most common platform (net45, android, ios and win phone).

Nop thread comparison in PersistentHashMap

I am reviewing the code of PersistentHashMap, I am wonder if the following code is correct

member this.ensureEditable(thread1, count1, array1) =
  if !thread = !thread then  // This test looks like its always true, shouldn't one of the operands be thread1
    this.array <- array1
    this.count <- count1
    this
  else HashCollisionNode(thread1, hashCollisionKey, count1, array1)

I am no expert on how to implement a PersistentHashMap so I might have misunderstood something.

Master's head build failed

I just make a clone and try to build head of master with build.cmd. Build failed with next message:

Status:        Failure
---------------------------------------------------------------------
  1) Building D:\projects\FSharpx.Collections\FSharpx.Collections.sln failed with exitcode 1.
  2) FS0366: D:\projects\FSharpx.Collections\src\FSharpx.Collections.Experimental\BinomialHeap.fs(219,15): No implementation was given for 'abstract member IPriorityQueue.Length
 : int'. Note that all interface members must be implemented and listed under an appropriate 'interface' declaration, e.g. 'interface ... with member ...'.
---------------------------------------------------------------------

D:\projects\FSharpx.Collections>git branch
* master

What project name should we use?

Hi,

I extracted all the collectections (including FSharpx.Collections.Experimental) from fsharpx and put them into this project.
I think it hsould be as easy as possible to use them and a dependency on FSharpx (the whole project) is often a big no-no.

This project has already > 1700 unit tests and some API documentation (will add FSharp.Formatting build task).

But what name/namespace should it get?

Here are some ideas:

  • fsharp/Fsharpx.Collections
  • fsharp/Fsharp.Collections
  • fsharp/Fsharp.Data.Collections
  • forki/Fsharpx.Collections
  • ??

// cc @dsyme @ovatsus @mausch @tpetricek @mausch @jackfoxy @panesofglass

RRB Trees: Efficient Immutable Vectors

I propose to add an implementation of Bagwell and Rompf's RRB-Tree Vectors (Relaxed Radix-Balanced Trees) to FSharpx.Collections. They are similar to PersistentVector, but allow for efficient slicing and concatenation. Slicing an RRB vector is effectively constant-time since it takes O(log32 N) time. Concatenating two RRB Vectors together is also O(log32 N) but with a large constant multiplier, as much as 1024 in the worst case, so it should really be considered O(log N) for all practical purposes.

Clojure implementation of RRB vectors: https://github.com/clojure/core.rrb-vector
Scala implementation: https://github.com/nicolasstucki/scala-rrb-vector

Papers about RRB vectors:

ResizeArray is missing distinct and distinctBy functions

Not having those forces me to use Seq.distinctBy instead. I'll give it a try at adding those myself tomorrow.

Edit:

They are easy enough to write.

let distinctBy keyf (array:ResizeArray<_>) =
    let temp = ResizeArray()
    let hashSet = HashSet(HashIdentity.Structural)
    for v in array do
        if hashSet.Add(keyf v) then
            temp.Add(v)
    temp

let distinct (array:ResizeArray<_>) =
    let temp = ResizeArray()
    let hashSet = HashSet(HashIdentity.Structural)
    for v in array do
        if hashSet.Add(v) then
            temp.Add(v)
    temp

The above is almost a carbon copy of the functions of the same name for Arrays inside the F# Collections source. Though now that I know HashSets are used inside the functions I might as well have used them myself.

I'll have a look at inserting them into the Fsharpx.Collections.

CircularBuffer has no tests

CircularBuffer has no tests. Also it would be nice to have a comment which says how this structure differs from RingBuffer, which also exists in the codebase.

PriorityQueue API: IComparable vs comparison function

I'm just curious about the API decision to make the PriorityQueue require an IComparable (along with the isDescending parameter for PriorityQueue.empty) instead of using a comparison function parameter for PriorityQueue.empty.

To me, It seems like passing in a comparison function would be the more idiomatic thing, but I'm pretty new to FP/F# and would love to hear how I'm wrong =).

GetHashCode & thread safety

I have noticed that some of the collections implemented here rely on a mutable Option field to store the hashCode and that field is changed inside GetHashCode, making the collection "thread unsafe", even in collections that I would assume thread safe. Should not the code inside GetHashCode be surrounded by a lock? Is my thinking wrong in any way, or am I assuming what I should not?

PriorityQueue/Heap with Removal of an element in the middle (not head only)

Hi
this is not an issue about a bug. Rather i'm a bit lost, and I'd like to know if among the data structures implemented in this library, there is a heap-like data structure supporting removal of an element in the middle of the priorityqueue/heap, and perhaps finding an element as well.

something like
https://code.msdn.microsoft.com/windowsdesktop/Net-Implementation-of-a-d3ac7b9d
however i have some reasons to believe the code above has some bugs.

I've googled to look for implementations elsewhere and couldn't find any, or at least any that i was able to use.

CHAMP - Compressed Hash-Array Mapped Prefix Tree

Possible addition to FSharpx.Collections?

Abstract
The data structures under-pinning collection API (e.g. lists, sets, maps) in the standard libraries of programming languages are used intensively in many applications.
The standard libraries of recent Java Virtual Machine languages, such as Clojure or Scala, contain scalable and well-performing immutable collection data structures that are implemented as Hash-Array Mapped Tries (HAMTs).HAMTs already feature efficient lookup, insert, and delete operations, however due to their tree-based nature their memory footprints and the runtime performance of iteration and equality checking lag behind array-based counterparts. This particularly prohibits their application in programs which process larger data sets.
In this paper, we propose changes to the HAMT design that increase the overall performance of immutable sets and maps. The resulting general purpose design increases cache locality and features a canonical representation. It outperforms Scala’s and Clojure’s data structure implementations in terms of memory footprint and runtime efficiency of iteration (1.3–6.7 x) and equality checking (3–25.4 x).

http://michael.steindorfer.name/publications/oopsla15.pdf

invalid Bytestring Compare

Just glancing through the code, and saw an obvious bug in ByteString

/// Compares two byte strings based on their structure.
static member Compare (a:ByteString, b:ByteString) =
    let x,o,l = a.Array, a.Offset, a.Count
    let x',o',l' = b.Array, b.Offset, b.Count
    if o = o' && l = l' && x = x' then 0
    elif x = x' then
        if o = o' then if l < l' then -1 else 1
        else if o < o' then -1 else 1 
    else let left, right = x.[o..(o+l-1)], x'.[o'..(o'+l'-1)] in
         if left = right then 0 elif left < right then -1 else 1

The problem is with the:

    elif x = x' then
        if o = o' then if l < l' then -1 else 1
        else if o < o' then -1 else 1 

Consider: If we have an array of all zeroes, for example, then take two slices of that array of the same size but at different offsets, this will compare them as non-equal.

A corrected version:

    if (x == x') && (o == o') then Compare(l,l') else
    ... normal structural comparison ...

I'm not sure I trust the rest of that structural comparison to be especially efficient.

(to anyone watching by e-mail: sorry about submitting before detailing the bug)

Enumerating an empty RandomAccessList fails

for i in RandomAccessList.empty do
    ignore()

Fails with

System.IndexOutOfRangeException : Index was outside the bounds of the array.
   at FSharpx.Collections.RandomAccessList`1.ArrayFor(Int32 i) in D:\code\FSharpx.Collections\src\FSharpx.Collections\RandomAccessList.fs:line 199
   at FSharpx.Collections.RandomAccessList`1.rangedIterator[T](Int32 startIndex, Int32 endIndex) in D:\code\FSharpx.Collections\src\FSharpx.Collections\RandomAccessList.fs:line 227
   at FSharpx.Collections.RandomAccessList`1.System-Collections-Generic-IEnumerable`1-GetEnumerator() in D:\code\FSharpx.Collections\src\FSharpx.Collections\RandomAccessList.fs:line 327

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.