-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix TestKitBase and Option<T> #4603
Conversation
@@ -30,7 +30,7 @@ public struct Option<T> | |||
public Option(T value) | |||
{ | |||
Value = value; | |||
HasValue = true; | |||
HasValue = value != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was always thinking about that - but what if null
in a valid value for this optional thing? What if null
means "there is a value, it is obtained from external source/whatever, it is initialized, and it is null
right now"?
So I did not ever change that. Still not sure if we need to do that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, by definition Option will return None or Some, what is the point of using Option if you still allow null to leak through? you wouldn't fix the original NRE problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even with this, you'll still have NRE problem if you forgot to check for None.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In essence, our Option<T>
implementation is a half assed attempt to fix NRE problem, its just moving the problem somewhere else.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you still need a null, then what you need is a tri-state object, where its state can be null, none, and some
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it even broke our own code.
This is stupid, I feel like I'm chasing my own tail.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a good fix actually, I would love to see exception thrown here too - but maybe this should be done on some breaking change release, i.e. Akka.NET 1.5, or even 2.0, because chances are that many users will need to debug their app and fix things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the proper thing to do right now is to implement the right IOption<T>
interface but make it internal and keep the old Option<T>
struct for public consumption.
But this will require so so much work to convert every Option<T>
in our code x__x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to go full rage mode, switch to C# 8 and make the input type non-nullable
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need the IOption<T>
interface exactly? I get the Some<T>
and None<T>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some comments
@@ -1292,7 +1292,9 @@ namespace Akka.Streams.Dsl | |||
public static Akka.Streams.Dsl.Flow<TIn, TOut2, TMat> Batch<TIn, TOut, TOut2, TMat>(this Akka.Streams.Dsl.Flow<TIn, TOut, TMat> flow, long max, System.Func<TOut, TOut2> seed, System.Func<TOut2, TOut, TOut2> aggregate) { } | |||
public static Akka.Streams.Dsl.Flow<TIn, TOut2, TMat> BatchWeighted<TIn, TOut, TOut2, TMat>(this Akka.Streams.Dsl.Flow<TIn, TOut, TMat> flow, long max, System.Func<TOut, long> costFunction, System.Func<TOut, TOut2> seed, System.Func<TOut2, TOut, TOut2> aggregate) { } | |||
public static Akka.Streams.Dsl.Flow<TIn, TOut, TMat> Buffer<TIn, TOut, TMat>(this Akka.Streams.Dsl.Flow<TIn, TOut, TMat> flow, int size, Akka.Streams.OverflowStrategy strategy) { } | |||
[System.ObsoleteAttribute("Deprecated. Please use Collect(isDefined, collector) instead")] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@@ -30,7 +30,7 @@ public struct Option<T> | |||
public Option(T value) | |||
{ | |||
Value = value; | |||
HasValue = true; | |||
HasValue = value != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we want to go full rage mode, switch to C# 8 and make the input type non-nullable
@@ -30,7 +30,7 @@ public struct Option<T> | |||
public Option(T value) | |||
{ | |||
Value = value; | |||
HasValue = true; | |||
HasValue = value != null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need the IOption<T>
interface exactly? I get the Some<T>
and None<T>
We don't need it per se, but by implementing it we can separate the internal implementation of Option with the one that is being used by user, just in case changing Option will break someone elses code. Pretty much a bandaid with backward compatibility. |
But it will be a very big bandaid, akin to using a nuclear warhead to kill an ant. |
The big fear right now is that, even changing that line in |
As long as:
Then I think we should do it "the right way" |
|
Memory impact will most probably came from stack allocation, I think struct was chosen exactly because of this. |
that's fine then |
as long as we don't allocate on every |
Closes #4496.
Original problem was that
Option<T>
failed to report that it has no value when passed a null value.TestKitBase
did not check forOption<Config>.None