fill is very useful for creating arrays having the same vaule at all locations. However, if this vaule is a mutable object, fill will place that very same object at all locations. This behavior can be confusing, especially for beginners, when one tries to mutate a single location, it will silently modify all locations similarly.
IMO, this makes fill and repeat less useful in practice. Also, Iâm not sure why Julia doesnât copy the value at all locations as MATLABâs repmat does? Of course, for immutable structures this issue doesnât exist. I know one can use array comprehensions to create such arrays but itâs not as intuitive/compact. Any ideas?
This is a fundamental difference between Julia and Matlab. Matlab copies everything silently under the hood (function arguments, = assignments, etc.). Julia never does this, so fill is just consistent with the way everything else in Julia works. Changing fill to automatically call copy (or should it be deepcopy?) would make it totally inconsistent with the rest of Julia, and I think thatâs a bad thing.
On the other hand, I agree that this is a very common trap for new users. Itâs so common that I wonder if it would be better to rename fill to something else for Julia 2.0 as a way to gently discourage new Julia users from expecting it to behave just like it does in Matlab. Itâs a useful function in Julia, but itâs not useful for the thing that most Matlab users seem to expect it to be useful for.
Adding a keyword argument like fill(x, dims; copy = false) would be semver-compliant for inclusion in a v1.x release so long as it doesnât change default behavior, right? And putting the default behavior right in the function signature might do a better job of warning new users than expecting them to read the full docstring.
Why it should? Do you want it to check if the value is mutable and take this decision for the programmer? The short answer is that it is confusing to many programmers (Java behaves the same way, as it is just how it is expected to behave when you have the correct memory model in mind) and it would be terrible for performance if done silently.
Iâm actually not aware of any functionality like fill in Matlab. In fact, you cannot even have arrays of arrays, except with the special âcell arrayâ type.
The way Matlab arrays work arenât really comparable to Juliaâs arrays, I think.
repmat is similar to Juliaâs repeat function, though:
I admit that the current behavior of not copying is consistent with Juliaâs design; arrays are not copied by default. But as you said, this is a common trap for many new users, and there should be a way to prevent this misunderstanding. On the same time, the functionality of expanding a vector into given dims is very useful in practice, see how many questions in this discourse about making the same mistake of referring to the same object at all locations.
Historically, repmat was superceded by repeat in 2018 so that now repeat works for both strings and arrays besides scalars. I think now we should have a means to prevent usage of fill with arrays and at the same time provide a convenience method that works for 2D and nD arrays. Something similar to this would be very useful (maybe repmat back or expand or any more expressive name):
Sure, MATLAB doesnât even have array of arrays, but since Julia has that, it makes sense to have that functionality to work for array of arrays in Julia. repmat was deprecated by Jeff in 2018 in favor of repeat, we might think of bringing it back for filling with arrays or choose a better name for a new method, say expand, multicopy, copydims, etc.
Having a copy = false keyword argument is not ideal, because if you set copy = true youâll still have the same problem with arrays of arrays of arrays. So what you really want is a deepcopy. But I believe Iâve heard it said that deepcopy in Julia is not very well defined, or shouldnât exist, or something like that. Canât find a link now.
So the only viable options are:
Use map or a comprehension.
Add fillf which takes a function as the first argument.
Add @fill.
At least a result of the above linked Github issue is that the documentation for fill will be improved in Julia version 1.8.
As far as I know, Matlabâs repmat functionality exists in Juliaâs repeat. I donât think there is any parallel to what you are looking for in Matlab, nor in previous Julia functions.
Thanks for pointing to the related issue. From a fast scim through the discussion there, it seems providing a @fill maco that means [<expr> for _ = 1:n] might be a viable solution.
I meant re-using the name repmat since it carries the postfix mat to now work with arrays, similar to what was suggested by @CameronBieganekâs 3 options above (fillf).
Yes, similar to this.
But after I scimmed through that issue I tend to agree on a macro @fill.
Not really agree with Jeff on this one, but I think I understand the perspective he is coming from. In package code, you really rarely will really want to generically deep copy something. However, I do not see why this hinders better naming of the functions (the PRâs goal). I mean, this seems like an excessively âtraining wheelsâ/âprotecting the programmers from themselvesâ take that is uncommon to Julia design: to avoid giving a function a better name just because it may make them discover a slower function that is not what they need 90% of the time.