language-ext v3.4.0 Release Notes
Release Date: 2020-02-12 // about 4 years ago-
๐ NOTE: I am just investigating some issues with this release relating to the code-gen, keep an eye out for 3.4.3 tonight or tomorrow (12/Feb/2020)
๐ In an effort to slowly get language-ext to the point where .NET Core 3 can be fully supported (with all of the benefits of new C# functionality) I have taken some baby steps towards that world:
โก๏ธ Updated the references for
CodeGeneration.Roslyn
to0.7.5-alpha
๐ This might seem crazy, but the
CodeGeneration.Roslyn
DLL doesn't end up in your final build (if you set it up correctly), and doesn't get used live even if you do. So, if the code generates correctly at build-time, it works. Therefore, including analpha
is low risk.๐ I have been testing this with my TestBed and unit-tests and working with the
CodeGeneration.Roslyn
team and thealpha
seems stable.๐ A release of
CodeGeneration.Roslyn
is apparently imminent, so, if you're not happy with this, then please wait for subsequent releases of language-ext when I've upgraded to the fullCodeGeneration.Roslyn
release. I just couldn't justify the code-gen holding back the development of the rest of language-ext any more.โก๏ธ Updated the minimum .NET Framework and .NET Standard versions
Ecosystem Old New .NET Framework net46
net461
.NET Standard netstandard2.0
netstandard2.1
๐
OptionAsync<A>
andEitherAsync<A>
supportIAsyncEnumerable<A>
๐ The
netstandard2.1
release supportsIAsyncEnumerable<A>
forOptionAsync<A>
andEitherAsync<A>
. This is the first baby-step towards leveraging some of the newer features of C# and .NET Core.pipe
prelude function๐ Allow composition of single argument functions which are then applied to the initial argument.
var split= fun((string s) =\> s.Split(' '));var reverse = fun((string[] words) =\> words.Rev().ToArray());var join= fun((string[] words) =\> string.Join(" ", words));var r = pipe("April is the cruellest month", split, reverse, join); //"month cruellest this is April"
โ Added
Hashable<A>
andHashableAsync<A>
type-classes0๏ธโฃ
Hashable<A>
andHashableAsync<A>
provide the methodsGetHashCode(A x)
andGetHashCodeAsync(A x)
. There are lots ofHashable*<A>
class-instances that provide default implementations for common types.โก๏ธ Updates to the
[Record]
and[Union]
code-gen0๏ธโฃ The
GetHashCode()
code-gen now usesHashable*<A>
for default field hashing. Previously this looked forEq*<A>
where the*
was the type of the field to hash, now it looks forHashable*<A>
.0๏ธโฃ By default
Equals
,CompareTo
, andGetHashCode
use:// \* == the type-name of the field/propertydefault(Eq\*).Equals(x, y); default(Ord\*).CompareTo(x, y); default(Hashable\*).GetHashCode(x);
0๏ธโฃ To provide the default structural functionality for the fields/properties. Those can now be overridden with The
Eq
,Ord
, andHashable
attributes:[Record] public partial struct Person { [Eq(typeof(EqStringOrdinalIgnoreCase))] [Ord(typeof(OrdStringOrdinalIgnoreCase))] [Hashable(typeof(HashableStringOrdinalIgnoreCase))] public readonly string Forename; [Eq(typeof(EqStringOrdinalIgnoreCase))] [Ord(typeof(OrdStringOrdinalIgnoreCase))] [Hashable(typeof(HashableStringOrdinalIgnoreCase))] public readonly string Surname; }
The code above will generate a record where the fields
Forename
andSurname
are all structurally part of the equality, ordering, and hashing. However, the case of the strings is ignored, so:{ Forename: "Paul", Surname: "Louth" } == { Forename: "paul", Surname: "louth" }
NOTE: Generic arguments aren't allowed in attributes, so this technique is limited to concrete-types only. A future system for choosing the structural behaviour of generic fields/properties is yet to be designed/defined.
๐ Bug fixes