You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
WARNING: THIS IS AN ALPHA RELEASE AND SHOULDN'T BE CONSUMED WITH CARE! NOT FOR PRODUCTION.
General updates
Free monad doesn't need Alternative trait: removed
All semigroup and monoid-like types have their Append operator renamed to Combine. 'Combine' works semantically for more of the monoidal associative operations than Append (which really only makes sense with collections).
Added new SemigroupK and MonoidK -- these are like the Semigroup and Monoid traits except they work on K<M, A> instead of A. These are almost identical to SemiAlternative and Alternative execept they don't require the underlying value to an an Applicative. The idea here is that SemigroupK and MonoidK would be used on types like collections that 'sum' when the Combine operator is applied, whereas SemiAlternative and Alternative provide an alternative value when the Combine operator is applied (coalescing).
Added missing repeat variants, retry variants, and timeout for the IO monad
Added IO.yieldFor(TimeSpan). This is like Task.Delay but for the IO monad. The war against async means that this does the thread-yielding internally, no need to call await. I figured yieldFor is more meaningful than Delay, it indicates that the thread is yielding, not simply blocking.
Added support for guards in the IO monad
Initial pass at a continuation-monad transformer: ContT<R, M, A> -- just the raw type for now.
HeadOrNone, HeadOrInvalid, HeadOrLeft, LastOrNone, etc. have been removed.
Head and Last are now Option returning. This is a breaking change. Can be mitigated by either matching, casting, or invocation of .ValueUnsafe() extension.
Improved Range type -- previously there were several types (IntegerRange, CharRange, etc.) -- now there's just one: Range<A>. It leverages the new traits built into .NET (IComparisonOperators, IAddtionOperators, etc.)
Started adding support for more of the .NET traits in the collection types and various other places like Foldable.Sum, Foldable.Max, etc.: (IComparisonOperators, IAddtionOperators, IAdditiveIdentity etc.) -- these are Microsoft's ugly named versions of monoids etc.
War on Extension Methods
I'm rapidly coming to the conclusion that extension-methods are a terrible idea. Especially in a library like language-ext where I am trying to present a consistent set of interfaces to types that share common traits. It's just impossible to enforce consistency and relies on the human eye -- and that errs regularly!
The latest move toward using traits is really starting to help reduce the extension methods, or at least mean the extension methods are hanging off traits rather than individual instance-types.
One change that I have made recently is to change Foldable to require implementation of FoldWhile and FoldWhileBack instead of Fold and FoldBack. This means that so many more default behaviours can hang off of Foldable -- and most of them are optimal. For example, Exists -- which can stop processing as soon as its predicate returns true -- couldn't early-out before.
However, quite a lot of those methods, like Sum, Count, etc. also exist on IEnumerable. And so, for a type like Seq which derives from both IEnumerable and K<Seq, A>, there will be extension method resolution issues.
So, the choice is to provide extension methods for IEnumerable (an ill defined type) or for Foldable - a super featureful type with the opportunity for implementers to provide bespoke optimised overrides.
Really, the choice should be easy: extensions for Foldable are just better than extensions for IEnumerable. So, I have done that. The downside is that this will be another breaking change (because the IEnumerable extensions have been removed). The fix is to convert from IEnumerable<A> to EnumerableM<A> using .AsEnumerableM(). EnumerableM<A> supports Foldable (and other traits).
Conclusion
So, I've been working to remove as many non-trait extension methods as I can -- and I will continue to do so leading up to the beta. This will bring consistency to the code-base, reduce the amount of code, and provide ample opportunities for bespoke optimisations. Just be aware that this is another fix-up job.
WARNING: THIS IS AN ALPHA RELEASE AND SHOULDN'T BE CONSUMED WITH CARE! NOT FOR PRODUCTION.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
General updates
Free
monad doesn't needAlternative
trait: removedAppend
operator renamed toCombine
. 'Combine' works semantically for more of the monoidal associative operations thanAppend
(which really only makes sense with collections).SemigroupK
andMonoidK
-- these are like theSemigroup
andMonoid
traits except they work onK<M, A>
instead ofA
. These are almost identical toSemiAlternative
andAlternative
execept they don't require the underlying value to an anApplicative
. The idea here is thatSemigroupK
andMonoidK
would be used on types like collections that 'sum' when theCombine
operator is applied, whereasSemiAlternative
andAlternative
provide an alternative value when theCombine
operator is applied (coalescing).repeat
variants,retry
variants, andtimeout
for the IO monadIO.yieldFor(TimeSpan)
. This is likeTask.Delay
but for the IO monad. The war against async means that this does the thread-yielding internally, no need to call await. I figuredyieldFor
is more meaningful thanDelay
, it indicates that the thread is yielding, not simply blocking.ContT<R, M, A>
-- just the raw type for now.HeadOrNone
,HeadOrInvalid
,HeadOrLeft
,LastOrNone
, etc. have been removed.Head
andLast
are nowOption
returning. This is a breaking change. Can be mitigated by either matching, casting, or invocation of.ValueUnsafe()
extension.Range
type -- previously there were several types (IntegerRange
,CharRange
, etc.) -- now there's just one:Range<A>
. It leverages the new traits built into .NET (IComparisonOperators
,IAddtionOperators
, etc.)Foldable.Sum
,Foldable.Max
, etc.: (IComparisonOperators
,IAddtionOperators
,IAdditiveIdentity
etc.) -- these are Microsoft's ugly named versions of monoids etc.War on Extension Methods
I'm rapidly coming to the conclusion that extension-methods are a terrible idea. Especially in a library like language-ext where I am trying to present a consistent set of interfaces to types that share common traits. It's just impossible to enforce consistency and relies on the human eye -- and that errs regularly!
The latest move toward using traits is really starting to help reduce the extension methods, or at least mean the extension methods are hanging off traits rather than individual instance-types.
One change that I have made recently is to change
Foldable
to require implementation ofFoldWhile
andFoldWhileBack
instead ofFold
andFoldBack
. This means that so many more default behaviours can hang off ofFoldable
-- and most of them are optimal. For example,Exists
-- which can stop processing as soon as its predicate returnstrue
-- couldn't early-out before.And so, the foldable trait is now growing to have a ton of functionality. Also nested foldables!
However, quite a lot of those methods, like
Sum
,Count
, etc. also exist onIEnumerable
. And so, for a type likeSeq
which derives from bothIEnumerable
andK<Seq, A>
, there will be extension method resolution issues.So, the choice is to provide extension methods for
IEnumerable
(an ill defined type) or forFoldable
- a super featureful type with the opportunity for implementers to provide bespoke optimised overrides.Really, the choice should be easy: extensions for Foldable are just better than extensions for
IEnumerable
. So, I have done that. The downside is that this will be another breaking change (because theIEnumerable
extensions have been removed). The fix is to convert fromIEnumerable<A>
toEnumerableM<A>
using.AsEnumerableM()
.EnumerableM<A>
supportsFoldable
(and other traits).Conclusion
So, I've been working to remove as many non-trait extension methods as I can -- and I will continue to do so leading up to the beta. This will bring consistency to the code-base, reduce the amount of code, and provide ample opportunities for bespoke optimisations. Just be aware that this is another fix-up job.
This discussion was created from the release Language-Ext 5.0 alpha-2.
Beta Was this translation helpful? Give feedback.
All reactions