Aff, Eff, AtomHashMap, TrackingHashMap + fixes [RTM]
Language-ext had been in beta for a few months now. Today we go back to full 'RTM' mode.
The recent changes are:
AtomHashMap
and Ref
change-tracking
A major new feature that allows for tracking of changes in an AtomHashMap
or a Ref
(using STM). The Change
event publishes HashMapPatch<K, V>
which will allow access to the state of the map before and after the change, as well as a HashMap<K, Change<V>>
which describes the transformations that took place in any transactional event.
In the LanguageExt.Rx
project there's various observable stream extensions that leverage the Change
event:
OnChange()
- which simply streams theHashMapPatch<K, V>
OnEntryChange()
- which streams theChange<V>
for any key within the mapOnMapChange()
- which streams the latestHashMap<K, V>
snapshot
Ref
which represents a single value in the STM system, has a simpler Change
event that simply streams the latest value. It also has an Rx
extension, called Change()
.
Documented in previous beta release notes
TrackingHashMap<K, V>
This is a new immutable data-structure which is mostly a clone of HashMap
; but one that allows for changes to be tracked. This is completely standalone, and not related to the AtomHashMap in any way other than it's used by the AtomHashMap.Swap
method. And so, this has use-cases of its own.
Changes are tracked as a HashMap<K, Change<V>>
. That means there's at most one change-value stored per-key. So, there's no risk of an ever expanding log of changes, because there is no log! The changes that are tracked are from the 'last snapshot point'. Which is from the empty-map or from the last state where tracking HashMap.Snapshot()
is called.
Documented in previous beta release notes
Fixes to the Aff
and Eff
system
The Aff
and Eff
system had some unfortunate edge-cases due to the use of memoisation by-default. The underlying system has been simplified to be more of a standard reader-monad without memoisation. You can still memoise if needed by calling: ma.Memo()
.
Future changes will make the
Aff
andEff
into more of a DSL, which will allow for certain elements of the system to be 'pure', and therefore safely memoisable, and other elements not. My prototype of this is in too early a stage to release though, so I've taken the safer option here.
Breaking change: Both Clone
and ReRun
have been removed, as they are now meaningless.
New package LanguageExt.SysX
- for .NET5.0+ features
The LanguageExt.Sys
package is a wrapper for .NET BCL IO functionality, for use with the runtime Eff
and Aff
monads. This is going to stay as netstandard2.0
for support of previous versions of the .NET Framework and .NET Core. This new package adds features that are for net5.0+
.
The first feature to be supported is the Activity
type for Open-Telemetry support.
ScheduleAff
and ScheduleEff
usage was inconsistent
Depending on the monad they were used with, you might see a 'repeat' that was 1 greater than it should have been. This is now fixed.
Lazy Seq
equality fix
Under certain rare circumstances it was possible for the equality operator to error with a lazy Seq
. Fix from @StefanBertels - thanks!
No more empty array allocations
It seams c# isn't smart enough to turn a new A[0]
into a non-allocating operation. And so they have all been replaced with Array.Empty()
. Fix from @timmi-on-rails - thanks!
Any problems, please report them in the Issues as usual. Paul 👍