Skip to content
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

Enhancement request: isempty(::Nothing) = true #35438

Closed
sbromberger opened this issue Apr 11, 2020 · 8 comments
Closed

Enhancement request: isempty(::Nothing) = true #35438

sbromberger opened this issue Apr 11, 2020 · 8 comments

Comments

@sbromberger
Copy link
Contributor

What breaks if we implement isempty for Nothing?

(Does it make sense to implement iterate for Nothing?)


julia> a = nothing
julia> isempty(a)
ERROR: MethodError: no method matching iterate(::Nothing)
Closest candidates are:
  iterate(::Core.SimpleVector) at essentials.jl:600
  iterate(::Core.SimpleVector, ::Any) at essentials.jl:600
  iterate(::ExponentialBackOff) at error.jl:218
  ...
Stacktrace:
 [1] isempty(::Nothing) at ./essentials.jl:736
 [2] top-level scope at REPL[2]:1
@KristofferC
Copy link
Member

What's the justification? To me, this looks like a random type and a random function with a random return value. Asking "what breaks" isn't really useful because it means that pretty anything that used to be an error can be made to have an arbitrary implementation.

@sbromberger
Copy link
Contributor Author

sbromberger commented Apr 11, 2020

We've run into a situation where we can expect one of {Vector{Int}, Nothing} and it would be nicer to be able to check whether any data is returned in one go. length() and isempty aren't defined for Nothing. We've defined isempty for scalars (= false) so I don't think it's too outlandish a request and it makes testing unions of collections and Nothing, which seem to be increasingly common, easier.

Edited to add: the reason I asked "what breaks?" is because frequently, enhancement requests have already been considered by the core team and there's a reason that they haven't been implemented. Perhaps I should've been more explicit but I didn't expect that to be the thing upon which we got hung. Feel free to read that as "has the core team considered this already, and if they did, what was the reason it wasn't implemented?"

@KristofferC
Copy link
Member

KristofferC commented Apr 11, 2020

able to check whether any data is returned in one go

So just do it? x === nothing ? false : isempty(x)? Just because you have a case where nothing means that there is no data doesn't mean that is the same in other peoples code. You can't really standardize your particular choice of what nothing means in your codebase for a function in general. It's just a choice.

We've defined isempty for scalars (= false) so I don't think it's too outlandish a request and it makes testing unions of collections and Nothing, which seem to be increasingly common, easier.

This is a consequence of numbers being iterable which there has been a lot of discussion about (#7903).

We've run into a situation where we can expect one of {Vector{Int}, Nothing} and it would be nicer to be able to check whether any data is returned in one go

But you can have a Union{T, Nothing} for any T so with a similar argument it would be nicer to be able to call any function on Nothing and get something (what?) back.
The reason you tend to use a union with Nothing is because the nothing means something different than the value. But what it means is just a convention and it needs to be explicitly coded at the point where it is used.

@sbromberger
Copy link
Contributor Author

The convention surrounding nothing is explicit, though. I would argue that that convention implies that isempty(nothing) should be true.

@jakobnissen
Copy link
Contributor

I must echo Kristoffer in that this seems like an implementation detail of your particular system that you advocate leak into Base. The meaning of isempty is to test whether a collection of items is empty, and nothing is not a collection of items. I think it makes no sense.

If you interpret nothing to semantically mean something like the empty set, then this opens a Pandora's box of what nothing actually is. For example, does it make sense to define Base.:+(x, ::Nothing) = x?

Furthermore, in your case, the alternative (namely x === nothing ? true : isempty(x)) is a simple one-liner, and is optimally efficient.

@sbromberger
Copy link
Contributor Author

I guess since there's a reasonable way to do this it doesn't merit further discussion. Thanks for the input.

@fredrikekre
Copy link
Member

ref #26350

@KristofferC
Copy link
Member

(that's Missing though)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants