What about an `undefs` function in `Base`?

You are advocating a change to Base. If you want to make the case for it, the best way is start with a package and show that it is indispensable.

Once upon a time, I made a similar argument. We can keep discussing this, but discussing it alone will not change anything. Now I’ve created a package to move the question along. I’ve also begun registering it.

As others have mentioned, some think that zeros, ones, trues, and falses should not exist in Base. It places an emphasis on Array where perhaps it really should not be special to the user.

You have made the argument that undefs should be as accessible to a novice user as zeros, ones, trues, and falses. However, undefs is dangerous. It looks like it might act like zeros, and more than one user on this forum has mistaken undef initialization as filling the array with zeros. You’ve also made the performance argument.

As Carsten Bauer mentioned, there is a better solution than undefs for the novice user where they can obtain nearly the same performance. This is calloc, a standard C function. On operating systems, there also more specialized methods in the same vein. You can find my initial explorations with this here:

I have since packaged this into ArrayAllocators.jl. Let me offer a brief demonstration.

julia> using ArrayAllocators

julia> @time zeros(Int, 1024, 1024);
  0.011977 seconds (2 allocations: 8.000 MiB)

julia> @time Array{Int}(undef, 1024, 1024);
  0.000023 seconds (2 allocations: 8.000 MiB)

julia> @time fill!(Array{Int}(undef, 1024, 1024), 0);
  0.006183 seconds (2 allocations: 8.000 MiB)

julia> @time ArrayAllocators.zeros(Int, 1024, 1024);
  0.000175 seconds (3 allocations: 8.000 MiB)

julia> sum(ArrayAllocators.zeros(Int, 1024, 1024))
0

julia> @time Array{Int}(calloc, 1024, 1024);
  0.000026 seconds (3 allocations: 8.000 MiB)

Rather than making undefs more accessible, perhaps we should focus on making zeros “faster” in more cases and defer the eager usage to the fill! syntax.

There’s is a minimalist philosophy attached to Base. As the application programming interface (API) of Base expands, it becomes harder to modify or change that API due to guarantees of backwards compatibility. For many, Base and standard library is already too large. A minimalist Base however is easy to customize with packages.

One reason to add new functionality to Base is that the functionality cannot added via a package. In particular, it may not be possible add the functionality without committing type piracy. Type piracy occurs when we attempt to extend methods for types where we “own” neither the method or the type. In the case of Undefs.jl we do not commit type piracy because we have created a new method, undefs. You might think that ArrayAllocators.zeros looks like piracy, but in fact it does not extend Base.zeros.

In summary, undefs is quite distinct from zeros and other methods because it can lead to novices easily writing incorrect code. Rather we should consider alternatives such as calloc and perhaps changing the implementation of zeros. These alternatives and other implementations may provide similar performance while also being correct and safe. Given the controversy the path forward is to create a package to implement the proposed functionality.

5 Likes