Le mercredi 07 janvier 2015 à 04:25 -0800, [email protected] a écrit :
>
>
> On Wednesday, January 7, 2015 9:36:28 PM UTC+10, Milan Bouchet-Valat wrote:
> Le mardi 06 janvier 2015 à 05:27 -0800, [email protected] a écrit :
> >
> >
> > On Tuesday, January 6, 2015 10:43:16 PM UTC+10, Milan Bouchet-Valat
> wrote:
> > Le mardi 06 janvier 2015 à 04:38 -0800, [email protected] a
> écrit :
> > >
> > >
> > > On Tuesday, January 6, 2015 7:38:00 PM UTC+10, Milan
> Bouchet-Valat
> > > wrote:
> > > Le lundi 05 janvier 2015 à 19:16 -0800,
> [email protected] a écrit :
> > > > My reasoning for Nullable{T} is that it is type
> stable. Taking your
> > > > example, None and Int would be different type
> objects, introducing a
> > > > type instability and potential performance
> penalty. But Nullable{T}
> > > > is always type Nullable{T} and get(Nullable{T})
> is always type T.
> > > > Allowing Nullable{T} to decay into T would
> re-introduce the type
> > > > instability.
> > > Right. But that doesn't mean `Nullable(3) == 3`
> shouldn't return `true`.
> > > This operation could be allowed, provided that
> `Nullable{Int}() == 3`
> > > raised a `NullException` or returned
> `Nullable{Bool}()`.
> > >
> > >
> > > Yeah, (==){T}(a::Nullable{T}, b::T) should be able to be
> defined as
> > > !isnull(a) && get(a) == b
> > I'd consider this definition (which is different from the
> ones I
> > suggested above) as unsafe: if `a` is `null`, then you
> silently get
> > `false`. Better provide additional safety by either
> returning a
> > `Nullable`, or raising an exception.
> >
> >
> >
> > If the Nullable does not have a value then it doesn't equal any
> value
> > of the type, so the correct answer is false. If it returns bool or
> > some sort of Nullable than again its type unstable and also can't
> be
> > directly used in an if. A user who cares about the null case can
> > always check isnull() themselves directly on the original object.
> We're hitting the debate about what John calls [1] ontological
> missingness vs. epistemological missingness. You appear to assume
> that
> if a `Nullable` is `null`, then it has no value (ontological
> missingness). But another conception (which is more common in
> statistics) is that the value exists somewhere, but we don't know it
> (epistemological missingness).
>
>
> Wasn't aware of the statistics conception, I just based it on the
> terminology used in the documentation, that the value is "not present"
> or the isnull() tests if it is "missing a value".
>
>
> In the former situation, you indeed know that `(null != 3) == true`.
> In
> the latter, you have to propagate the uncertainty by saying `(null !=
> 3)
> == null`.
>
>
> A Nullable is immutable, its value isn't down the back of the couch
> (which is my understanding of epistemological missingness, usually
> applied to the TV remote :), it can never get a value once its null.
That's not a technical question (immutable/mutable), but a conceptual
one. If you have missing values in e.g. survey data, it usually means
that the individual has not replied to the question (away, refused to
reply, bug in the collect...). So you cannot say whether the value would
have been 3 or something else.
Regards
> > And throwing exceptions is expensive and prevents the test being
> used
> > in high performance code. In fact I would consider it rather nasty
> if
> > something like an equality test could throw. That means the ==
> > function can't be used in any code that is a callback from C if
> there
> > is any possibility of one of its parameters being a nullable.
> >
> > Thats not to say that a user can't define their *own* version with
> > either of these characteristics if it suits their use-case, but any
> > general case should prefer the type stable high performance usage.
> My two proposals higher in the thread are type-stable. And I don't
> think
> raising an exception hurts performance (even `getindex` does it), and
> while it can be a problem with C callbacks, that's already the case
> of
> all functions that raise exceptions (including `get(::Nullable)`
> itself
> -- thus any code working with `Nullable` may raise exceptions if not
> written carefully).
>
>
> Sorry I wasn't clear enough, raising exceptions for errors is fine. But
> (given my ontological viewpoint) I would consider this use as flow control,
> not an error.
>
>
> That said, I agree that always returning a `Nullable{Bool}` may not
> be
> very practical in most contexts, even though it's consistent. The
> solutions of throwing an exception or returning `false` are certainly
> more practical. But that decision should be taken with regard to the
> broader scope of how applying functions to `Nullable` works
> (discussion
> at https://github.com/JuliaLang/julia/pull/9446 )
>
>
>
> Well, isequal(Nullable, Nullable) is defined to return true if both are null
> or false if only one is null or the result of isequal(the values)
>
>
> So returning false seems consistent with the one null, one not null case.
>
>
> Cheers
> Lex
>
>
> Regards
>
>
> 1:
>
> https://github.com/JuliaCon/presentations/tree/master/RepresentingData
>
> > Cheers
> > Lex
> >
> >
> >
> > >
> > > Cheers
> > > Lex
> > >
> > >
> > > Regarding the original question:
> > > > On Tuesday, January 6, 2015 12:03:24 PM UTC+10,
> > Seth wrote:
> > > > I'm trying to figure out how (and under
> > what circumstances)
> > > > one would use Nullable. That is, it
> seems
> > that it might be
> > > > valuable when you don't know whether
> the
> > value/object exists
> > > > (sort of like Python's None, I guess),
> but
> > then something like
> > > > "Nullable(3) == 3" returns false, and
> that
> > sort of messes up
> > > > how I'm thinking about it.
> > > >
> > > >
> > > > The code I'd imagine would be useful
> would
> > be something like
> > > >
> > > >
> > > > function foo(x::Int, y=Nullable{Int}())
> #
> > that is, y defaults
> > > > to python's "None" but is restricted to
> > Int
> > > > if !isnull(y)
> > > > return x+y # x + get(y) works,
> > but why must we invoke
> > > > another method to get the value?
> > > > else
> > > > return 2x
> > > > end
> > > > end
> > > >
> > > >
> > > > I'm left wondering why it wasn't
> > reasonable to allow y to
> > > > return get(y) if not null, else raise a
> > NullException,
> > > The question is how you define "return". In the
> > strict sense, if you
> > > write `return y`, then `y` must be returned, not
> > `get(y)`, or the Julia
> > > language would really be a mess.
> > >
> > > That said, with return type declarations, if
> > `foo()::Int` allowed
> > > stating that `foo()` always returns an `Int`,
> then
> > `y` could
> > > automatically be converted to an `Int`, raising
> an
> > exception if it's
> > > `null`. But that merely allows you to type
> `return
> > y` instead of
> > > `return get(y)`, so not a big deal.
> > >
> > > Finally, there's the question of whether `x + y`
> > should be allowed to
> > > mean `x + get(y)`. That's debatable, but I think
> a
> > more useful behavior
> > > would be to make it equivalent to
> > > `isnull(y) ? Nullable(x + get(y)) :
> > Nullable{Int}()`. That would allow
> > > handling the possibility of missingness only when
> > you actually want to
> > > get an `Int` from a `Nullable{Int}`.
> > >
> > > This has been discussed more generally for any
> > function call at
> > > https://github.com/JuliaLang/julia/pull/9446
> > >
> > > > and the conclusion I'm coming to is
> that I
> > don't understand
> > > > the concept of Nullable yet. Any
> > pointers?
> > > >
> > >
> > > Regards
> >
>